1*** Variables *** 2${PRIV_ALL} 0x3 3${PRIV_WRITE} 0x2 4${PRIV_READ} 0x1 5${PRIV_NONE} 0x0 6${START_PC} 0x0 7${DMA_ADDR} 0x45000000 8${IOMMU_ADDR} 0x46000000 9 10*** Keywords *** 11Create Platform 12 Execute Command using sysbus 13 Execute Command mach create "risc-v" 14 15 Execute Command machine LoadPlatformDescriptionFromString "clint: IRQControllers.CoreLevelInterruptor @ sysbus 0x44000000 { frequency: 66000000 }" 16 Execute Command machine LoadPlatformDescriptionFromString "cpu: CPU.RiscV32 @ sysbus { timeProvider: clint; cpuType: \\"rv32gc\\" }" 17 Execute Command machine LoadPlatformDescriptionFromString "mem: Memory.MappedMemory @ sysbus 0x0 { size: 0x100000 }" 18 Execute Command machine LoadPlatformDescriptionFromString "iommu0: Miscellaneous.WindowIOMMU @ sysbus ${IOMMU_ADDR} { IRQ -> cpu@1 }" 19 Execute Command machine LoadPlatformDescriptionFromString "dma0: SimpleDMA @ { sysbus ${DMA_ADDR}; iommu0 0 }" 20 21 Execute Command sysbus WriteDoubleWord ${START_PC} 0x000000ef # jal ra, 0 22 Execute Command cpu PC ${START_PC} 23 24Write Range With Doublewords 25 [Arguments] ${start_addr} ${length} ${value} 26 ${end_addr}= Evaluate ${start_addr}+${length} 27 ${bytesPerDoubleword}= Evaluate 4 28 FOR ${addr} IN RANGE ${start_addr} ${end_addr} ${bytesPerDoubleWord} 29 Execute Command sysbus WriteDoubleWord ${addr} ${value} 30 END 31 32Write To Address By DMA 33 [Arguments] ${dma_addr_hex} ${addr} ${value} 34 ${dma_addr}= Convert To Integer ${dma_addr_hex} 35 Execute Command sysbus WriteDoubleWord ${dma_addr+0} ${value} 36 Execute Command sysbus WriteDoubleWord ${dma_addr+4} ${addr} 37 38Read From Address By DMA 39 [Arguments] ${dma_addr_hex} ${addr} 40 ${dma_addr}= Convert To Integer ${dma_addr_hex} 41 Execute Command sysbus WriteDoubleWord ${dma_addr+8} ${addr} 42 ${read_value}= Execute Command sysbus ReadDoubleWord ${dma_addr+0} 43 RETURN ${read_value} 44 45Define Window 46 [Arguments] ${window_index} ${start_addr} ${end_addr} ${offset} ${priv} 47 48 ${window_register}= Evaluate 4 * ${window_index} + ${IOMMU_ADDR} 49 ${start_register}= Evaluate 0x0 + ${window_register} 50 ${end_register}= Evaluate 0x400 + ${window_register} 51 ${offset_register}= Evaluate 0x800 + ${window_register} 52 ${priv_register}= Evaluate 0xC00 + ${window_register} 53 54 Execute Command sysbus WriteDoubleWord ${start_register} ${start_addr} 55 Execute Command sysbus WriteDoubleWord ${end_register} ${end_addr} 56 Execute Command sysbus WriteDoubleWord ${offset_register} ${offset} 57 Execute Command sysbus WriteDoubleWord ${priv_register} ${priv} 58 59*** Test Cases *** 60Simple DMA Should Read And Write 61 Create Platform 62 63 Write Range With Doublewords 0x100 0x110 0x01234567 64 Define Window 0 0x0 0x10000 0x0 ${PRIV_ALL} 65 66 Write To Address By DMA ${DMA_ADDR} 0x104 0x89abcdef 67 ${written_value}= Execute Command sysbus ReadDoubleWord 0x104 68 Should Be Equal As Integers ${written_value} 0x89abcdef 69 70 ${read_value}= Read From Address By DMA ${DMA_ADDR} 0x100 71 Should Be Equal As Integers ${read_value} 0x01234567 72 73 ${read_value}= Read From Address By DMA ${DMA_ADDR} 0x104 74 Should Be Equal As Integers ${read_value} 0x89abcdef 75 76Address Are Translated 77 Create Platform 78 79 Define Window 0 0x1000 0x1100 256 ${PRIV_ALL} 80 Define Window 1 0x1200 0x1300 -256 ${PRIV_ALL} 81 82 Write To Address By DMA ${DMA_ADDR} 0x1000 0x01234567 83 ${read_value}= Execute Command sysbus ReadDoubleWord 0x1100 84 Should Be Equal As Integers ${read_value} 0x01234567 85 ${read_value}= Execute Command sysbus ReadDoubleWord 0x1000 86 Should Be Equal As Integers ${read_value} 0x0 87 88 Write To Address By DMA ${DMA_ADDR} 0x1200 0x89abcdef 89 ${read_value}= Execute Command sysbus ReadDoubleWord 0x1100 90 Should Be Equal As Integers ${read_value} 0x89abcdef 91 ${read_value}= Execute Command sysbus ReadDoubleWord 0x1000 92 Should Be Equal As Integers ${read_value} 0x0 93 94IOMMU Fault Triggers IRQ 95 Create Platform 96 Create Log Tester 0 97 Execute Command logLevel -1 98 99 Define Window 0 0x0000 0x1000 0x0 ${PRIV_NONE} 100 Start Emulation 101 102 Read From Address By DMA ${DMA_ADDR} 0x0FFA 103 Wait For Log Entry IOMMU fault at 0xFFA when trying to access as Read 104 Wait For Log Entry Setting the IRQ 105 Wait For Log Entry Setting CPU IRQ #1 106 107Permissions Are Respected 108 Create Platform 109 Create Log Tester 0 110 Execute Command logLevel -1 111 112 Define Window 0 0x0000 0x1000 0x0 ${PRIV_NONE} 113 Define Window 1 0x1000 0x2000 0x0 ${PRIV_ALL} 114 Write Range With Doublewords 0x1000 0x1FFF 0x01234567 115 Define Window 3 0x2000 0x3000 0x0 ${PRIV_NONE} 116 Define Window 5 0x3000 0x4000 0x0 ${PRIV_WRITE} 117 Define Window 6 0x4000 0x5000 0x0 ${PRIV_READ} 118 119 Read From Address By DMA ${DMA_ADDR} 0x0FFA 120 Wait For Log Entry IOMMU fault at 0xFFA 121 122 Write To Address By DMA ${DMA_ADDR} 0x0FFC 0x0 123 Wait For Log Entry IOMMU fault at 0xFFC 124 125 Write To Address By DMA ${DMA_ADDR} 0x1000 0x0 126 Should Not Be In Log IOMMU fault at 0x1000 127 128 Write To Address By DMA ${DMA_ADDR} 0x1FFF 0x0 129 Read From Address By DMA ${DMA_ADDR} 0x1FFF 130 Should Not Be In Log IOMMU fault at 0x1FFF 131 132 Write To Address By DMA ${DMA_ADDR} 0x2000 0x0 133 Wait For Log Entry IOMMU fault at 0x2000 134 135 Write To Address By DMA ${DMA_ADDR} 0x3000 0x0 136 Should Not Be In Log IOMMU fault at 0x3000 137 138 Read From Address By DMA ${DMA_ADDR} 0x3000 139 Wait For Log Entry IOMMU fault at 0x3000 140 141 Read From Address By DMA ${DMA_ADDR} 0x4000 142 Should Not Be In Log IOMMU fault at 0x4000 143 144 Write To Address By DMA ${DMA_ADDR} 0x4000 0x0 145 Wait For Log Entry IOMMU fault at 0x4000 146 147Throws Error On Registering Two IOMMUs For One Peripheral 148 Create Platform 149 Create Log Tester 0 150 151 Execute Command machine LoadPlatformDescriptionFromString "iommu1: Miscellaneous.WindowIOMMU @ sysbus 0x47000000" 152 Run Keyword And Expect Error *Trying to change the BusController from * Execute Command machine LoadPlatformDescriptionFromString "dma1: SimpleDMA @ { sysbus 0x48000000; iommu0 1; iommu1 0 }" 153 154Defining Invalid Window Throws 155 # This test case doesn't check 64-bit unsigned integer overflow 156 Create Platform 157 158 Define Window 0 0x0 0xffffffff 0x7fffffff ${PRIV_NONE} 159 Define Window 0 0x100 0x100 0x0 ${PRIV_NONE} 160 Define Window 0 0x101 0x100 0 ${PRIV_NONE} 161 Wait For Log Entry MMUWindow has start address .* grater than end address treatAsRegex=true 162 163 Define Window 0 0x100 0x1000 -256 ${PRIV_NONE} 164 Should Not Be In Log MMUWindow has incorrect offset 165 Define Window 0 0x100 0x1000 -257 ${PRIV_ALL} 166 Wait For Log Entry MMUWindow has incorrect offset 167 Write To Address By DMA ${DMA_ADDR} 0x200 0x0 168 Wait For Log Entry The window at index .* match the address, but isn't validated sucesfully treatAsRegex=true 169 170 Define Window 0 0x100 0x1000 0 ${PRIV_NONE} 171 Define Window 1 0x1000 0x1004 0 ${PRIV_NONE} 172 Define Window 1 0xFFF 0x1004 0 ${PRIV_NONE} 173 Wait For Log Entry MMUWindows .* overlap each other treatAsRegex=true 174 Define Window 1 0x000 0x101 0 ${PRIV_NONE} 175 Wait For Log Entry MMUWindows .* overlap each other treatAsRegex=true 176 177Restrict Access From Two Peripherals 178 Create Platform 179 Execute Command machine LoadPlatformDescriptionFromString "dma1: SimpleDMA @ { sysbus 0x48000000; iommu0 1 }" 180 Create Log Tester 0 181 Execute Command logLevel -1 182 183 Define Window 0 0x0000 0x1000 0x0 ${PRIV_NONE} 184 Define Window 1 0x1000 0x2000 0x0 ${PRIV_ALL} 185 Write Range With Doublewords 0x1000 0x1FFF 0x01234567 186 187 Write To Address By DMA ${DMA_ADDR} 0x0FFC 0x0 188 Wait For Log Entry IOMMU fault at 0xFFC 189 190 Write To Address By DMA ${DMA_ADDR} 0x1000 0x0 191 Should Not Be In Log IOMMU fault at 0x1000 192 193 Write To Address By DMA 0x48000000 0x0FFC 0x0 194 Wait For Log Entry IOMMU fault at 0xFFC 195 196 Write To Address By DMA 0x48000000 0x1000 0x0 197 Should Not Be In Log IOMMU fault at 0x1000 198