199 lines
9.6 KiB
Plaintext
199 lines
9.6 KiB
Plaintext
*** Variables ***
|
|
${PRIV_ALL} 0x3
|
|
${PRIV_WRITE} 0x2
|
|
${PRIV_READ} 0x1
|
|
${PRIV_NONE} 0x0
|
|
${START_PC} 0x0
|
|
${DMA_ADDR} 0x45000000
|
|
${IOMMU_ADDR} 0x46000000
|
|
|
|
*** Keywords ***
|
|
Create Platform
|
|
Execute Command using sysbus
|
|
Execute Command mach create "risc-v"
|
|
|
|
Execute Command machine LoadPlatformDescriptionFromString "clint: IRQControllers.CoreLevelInterruptor @ sysbus 0x44000000 { frequency: 66000000 }"
|
|
Execute Command machine LoadPlatformDescriptionFromString "cpu: CPU.RiscV32 @ sysbus { timeProvider: clint; cpuType: \\"rv32gc\\" }"
|
|
Execute Command machine LoadPlatformDescriptionFromString "mem: Memory.MappedMemory @ sysbus 0x0 { size: 0x100000 }"
|
|
Execute Command machine LoadPlatformDescriptionFromString "iommu0: Miscellaneous.WindowIOMMU @ sysbus ${IOMMU_ADDR} { IRQ -> cpu@1 }"
|
|
Execute Command machine LoadPlatformDescriptionFromString "dma0: SimpleDMA @ { sysbus ${DMA_ADDR}; iommu0 0 }"
|
|
|
|
Execute Command sysbus WriteDoubleWord ${START_PC} 0x000000ef # jal ra, 0
|
|
Execute Command cpu PC ${START_PC}
|
|
|
|
Write Range With Doublewords
|
|
[Arguments] ${start_addr} ${length} ${value}
|
|
${end_addr}= Evaluate ${start_addr}+${length}
|
|
${bytesPerDoubleword}= Evaluate 4
|
|
FOR ${addr} IN RANGE ${start_addr} ${end_addr} ${bytesPerDoubleWord}
|
|
Execute Command sysbus WriteDoubleWord ${addr} ${value}
|
|
END
|
|
|
|
Write To Address By DMA
|
|
[Arguments] ${dma_addr_hex} ${addr} ${value}
|
|
${dma_addr}= Convert To Integer ${dma_addr_hex}
|
|
Execute Command sysbus WriteDoubleWord ${dma_addr+0} ${value}
|
|
Execute Command sysbus WriteDoubleWord ${dma_addr+4} ${addr}
|
|
|
|
Read From Address By DMA
|
|
[Arguments] ${dma_addr_hex} ${addr}
|
|
${dma_addr}= Convert To Integer ${dma_addr_hex}
|
|
Execute Command sysbus WriteDoubleWord ${dma_addr+8} ${addr}
|
|
${read_value}= Execute Command sysbus ReadDoubleWord ${dma_addr+0}
|
|
RETURN ${read_value}
|
|
|
|
Define Window
|
|
[Arguments] ${window_index} ${start_addr} ${end_addr} ${offset} ${priv}
|
|
|
|
${window_register}= Evaluate 4 * ${window_index} + ${IOMMU_ADDR}
|
|
${start_register}= Evaluate 0x0 + ${window_register}
|
|
${end_register}= Evaluate 0x400 + ${window_register}
|
|
${offset_register}= Evaluate 0x800 + ${window_register}
|
|
${priv_register}= Evaluate 0xC00 + ${window_register}
|
|
|
|
Execute Command sysbus WriteDoubleWord ${start_register} ${start_addr}
|
|
Execute Command sysbus WriteDoubleWord ${end_register} ${end_addr}
|
|
Execute Command sysbus WriteDoubleWord ${offset_register} ${offset}
|
|
Execute Command sysbus WriteDoubleWord ${priv_register} ${priv}
|
|
|
|
*** Test Cases ***
|
|
Simple DMA Should Read And Write
|
|
Create Platform
|
|
|
|
Write Range With Doublewords 0x100 0x110 0x01234567
|
|
Define Window 0 0x0 0x10000 0x0 ${PRIV_ALL}
|
|
|
|
Write To Address By DMA ${DMA_ADDR} 0x104 0x89abcdef
|
|
${written_value}= Execute Command sysbus ReadDoubleWord 0x104
|
|
Should Be Equal As Integers ${written_value} 0x89abcdef
|
|
|
|
${read_value}= Read From Address By DMA ${DMA_ADDR} 0x100
|
|
Should Be Equal As Integers ${read_value} 0x01234567
|
|
|
|
${read_value}= Read From Address By DMA ${DMA_ADDR} 0x104
|
|
Should Be Equal As Integers ${read_value} 0x89abcdef
|
|
|
|
Address Are Translated
|
|
Create Platform
|
|
|
|
Define Window 0 0x1000 0x1100 256 ${PRIV_ALL}
|
|
Define Window 1 0x1200 0x1300 -256 ${PRIV_ALL}
|
|
|
|
Write To Address By DMA ${DMA_ADDR} 0x1000 0x01234567
|
|
${read_value}= Execute Command sysbus ReadDoubleWord 0x1100
|
|
Should Be Equal As Integers ${read_value} 0x01234567
|
|
${read_value}= Execute Command sysbus ReadDoubleWord 0x1000
|
|
Should Be Equal As Integers ${read_value} 0x0
|
|
|
|
Write To Address By DMA ${DMA_ADDR} 0x1200 0x89abcdef
|
|
${read_value}= Execute Command sysbus ReadDoubleWord 0x1100
|
|
Should Be Equal As Integers ${read_value} 0x89abcdef
|
|
${read_value}= Execute Command sysbus ReadDoubleWord 0x1000
|
|
Should Be Equal As Integers ${read_value} 0x0
|
|
|
|
IOMMU Fault Triggers IRQ
|
|
Create Platform
|
|
Create Log Tester 0
|
|
Execute Command logLevel -1
|
|
|
|
Define Window 0 0x0000 0x1000 0x0 ${PRIV_NONE}
|
|
Start Emulation
|
|
|
|
Read From Address By DMA ${DMA_ADDR} 0x0FFA
|
|
Wait For Log Entry IOMMU fault at 0xFFA when trying to access as Read
|
|
Wait For Log Entry Setting the IRQ
|
|
Wait For Log Entry Setting CPU IRQ #1
|
|
|
|
Permissions Are Respected
|
|
Create Platform
|
|
Create Log Tester 0
|
|
Execute Command logLevel -1
|
|
|
|
Define Window 0 0x0000 0x1000 0x0 ${PRIV_NONE}
|
|
Define Window 1 0x1000 0x2000 0x0 ${PRIV_ALL}
|
|
Write Range With Doublewords 0x1000 0x1FFF 0x01234567
|
|
Define Window 3 0x2000 0x3000 0x0 ${PRIV_NONE}
|
|
Define Window 5 0x3000 0x4000 0x0 ${PRIV_WRITE}
|
|
Define Window 6 0x4000 0x5000 0x0 ${PRIV_READ}
|
|
|
|
Read From Address By DMA ${DMA_ADDR} 0x0FFA
|
|
Wait For Log Entry IOMMU fault at 0xFFA
|
|
|
|
Write To Address By DMA ${DMA_ADDR} 0x0FFC 0x0
|
|
Wait For Log Entry IOMMU fault at 0xFFC
|
|
|
|
Write To Address By DMA ${DMA_ADDR} 0x1000 0x0
|
|
Should Not Be In Log IOMMU fault at 0x1000
|
|
|
|
Write To Address By DMA ${DMA_ADDR} 0x1FFF 0x0
|
|
Read From Address By DMA ${DMA_ADDR} 0x1FFF
|
|
Should Not Be In Log IOMMU fault at 0x1FFF
|
|
|
|
Write To Address By DMA ${DMA_ADDR} 0x2000 0x0
|
|
Wait For Log Entry IOMMU fault at 0x2000
|
|
|
|
Write To Address By DMA ${DMA_ADDR} 0x3000 0x0
|
|
Should Not Be In Log IOMMU fault at 0x3000
|
|
|
|
Read From Address By DMA ${DMA_ADDR} 0x3000
|
|
Wait For Log Entry IOMMU fault at 0x3000
|
|
|
|
Read From Address By DMA ${DMA_ADDR} 0x4000
|
|
Should Not Be In Log IOMMU fault at 0x4000
|
|
|
|
Write To Address By DMA ${DMA_ADDR} 0x4000 0x0
|
|
Wait For Log Entry IOMMU fault at 0x4000
|
|
|
|
Throws Error On Registering Two IOMMUs For One Peripheral
|
|
Create Platform
|
|
Create Log Tester 0
|
|
|
|
Execute Command machine LoadPlatformDescriptionFromString "iommu1: Miscellaneous.WindowIOMMU @ sysbus 0x47000000"
|
|
Run Keyword And Expect Error *Trying to change the BusController from * Execute Command machine LoadPlatformDescriptionFromString "dma1: SimpleDMA @ { sysbus 0x48000000; iommu0 1; iommu1 0 }"
|
|
|
|
Defining Invalid Window Throws
|
|
# This test case doesn't check 64-bit unsigned integer overflow
|
|
Create Platform
|
|
Create Log Tester 0
|
|
|
|
Define Window 0 0x0 0xffffffff 0x7fffffff ${PRIV_NONE}
|
|
Define Window 0 0x100 0x100 0x0 ${PRIV_NONE}
|
|
Define Window 0 0x101 0x100 0 ${PRIV_NONE}
|
|
Wait For Log Entry MMUWindow has start address .* grater than end address treatAsRegex=true
|
|
|
|
Define Window 0 0x100 0x1000 -256 ${PRIV_NONE}
|
|
Should Not Be In Log MMUWindow has incorrect offset
|
|
Define Window 0 0x100 0x1000 -257 ${PRIV_ALL}
|
|
Wait For Log Entry MMUWindow has incorrect offset
|
|
Write To Address By DMA ${DMA_ADDR} 0x200 0x0
|
|
Wait For Log Entry The window at index .* match the address, but isn't validated sucesfully treatAsRegex=true
|
|
|
|
Define Window 0 0x100 0x1000 0 ${PRIV_NONE}
|
|
Define Window 1 0x1000 0x1004 0 ${PRIV_NONE}
|
|
Define Window 1 0xFFF 0x1004 0 ${PRIV_NONE}
|
|
Wait For Log Entry MMUWindows .* overlap each other treatAsRegex=true
|
|
Define Window 1 0x000 0x101 0 ${PRIV_NONE}
|
|
Wait For Log Entry MMUWindows .* overlap each other treatAsRegex=true
|
|
|
|
Restrict Access From Two Peripherals
|
|
Create Platform
|
|
Execute Command machine LoadPlatformDescriptionFromString "dma1: SimpleDMA @ { sysbus 0x48000000; iommu0 1 }"
|
|
Create Log Tester 0
|
|
Execute Command logLevel -1
|
|
|
|
Define Window 0 0x0000 0x1000 0x0 ${PRIV_NONE}
|
|
Define Window 1 0x1000 0x2000 0x0 ${PRIV_ALL}
|
|
Write Range With Doublewords 0x1000 0x1FFF 0x01234567
|
|
|
|
Write To Address By DMA ${DMA_ADDR} 0x0FFC 0x0
|
|
Wait For Log Entry IOMMU fault at 0xFFC
|
|
|
|
Write To Address By DMA ${DMA_ADDR} 0x1000 0x0
|
|
Should Not Be In Log IOMMU fault at 0x1000
|
|
|
|
Write To Address By DMA 0x48000000 0x0FFC 0x0
|
|
Wait For Log Entry IOMMU fault at 0xFFC
|
|
|
|
Write To Address By DMA 0x48000000 0x1000 0x0
|
|
Should Not Be In Log IOMMU fault at 0x1000
|