blob: 96e8195625a51b2fbddab6160a839f24b0c15b5f [file] [log] [blame]
*** 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
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