1*** Variables *** 2${a0} 0xA 3${r0} 0x0 4${r1} 0x1 5${ASSEMBLY_ADDRESS} 0x0 6${X_CHAR} 120 7${ARM_UART_DATA_ADDRESS} 0x2000 8${WATCHPOINT_ADDRESS} 0x100 9${ARM_PLATFORM} SEPARATOR=\n 10... """ 11... cpu: CPU.ARMv7A @ sysbus 12... ${SPACE*4}cpuType: "cortex-a9" 13... 14... mem: Memory.MappedMemory @ sysbus 0x0 15... ${SPACE*4}size: 0x1000 16... 17... uart: UART.TrivialUart @ sysbus 0x2000 18... """ 19${ARM64_PLATFORM} SEPARATOR=\n 20... """ 21... cpu: CPU.ARMv8A @ sysbus 22... ${SPACE*4}cpuType: "cortex-a53" 23... ${SPACE*4}genericInterruptController: gic 24... 25... mem: Memory.MappedMemory @ sysbus 0x0 26... ${SPACE*4}size: 0x1000 27... 28... gic: IRQControllers.ARM_GenericInterruptController @ { 29... ${SPACE*8}sysbus new Bus.BusMultiRegistration { address: 0x8000000; size: 0x010000; region: "distributor" }; 30... ${SPACE*8}sysbus new Bus.BusMultiRegistration { address: 0x8010000; size: 0x010000; region: "cpuInterface" } 31... ${SPACE*4}} 32... ${SPACE*4}\[0-1\] -> cpu@\[0-1\] 33... ${SPACE*4}architectureVersion: IRQControllers.ARM_GenericInterruptControllerVersion.GICv2 34... ${SPACE*4}supportsTwoSecurityStates: true 35... """ 36${RISCV_PLATFORM} SEPARATOR=\n 37... """ 38... cpu: CPU.RiscV32 @ sysbus 39... ${SPACE*4}timeProvider: clint 40... ${SPACE*4}cpuType: "rv32gc" 41... 42... mem: Memory.MappedMemory @ sysbus 0x0 43... ${SPACE*4}size: 0x100000 44... 45... clint: IRQControllers.CoreLevelInterruptor @ sysbus 0x44000000 46... ${SPACE*4}frequency: 66000000 47... """ 48 49*** Keywords *** 50Create Platform 51 [Arguments] ${platform} ${assembly} 52 Execute Command using sysbus 53 Execute Command mach create 54 Execute Command machine LoadPlatformDescriptionFromString ${platform} 55 Execute Command cpu AssembleBlock ${ASSEMBLY_ADDRESS} "${assembly}" 56 Execute Command cpu PC ${ASSEMBLY_ADDRESS} 57 58Expect Instructions Count 59 [Arguments] ${expected_count} 60 ${insn_count}= Execute Command cpu ExecutedInstructions 61 Should Be Equal As Numbers ${insn_count} ${expected_count} 62 63Expect PC 64 [Arguments] ${expected_pc} 65 ${pc}= Execute Command cpu PC 66 Should Be Equal As Numbers ${pc} ${expected_pc} 67 68Repeat String 69 [Arguments] ${str} ${count} 70 ${rep_str}= Set Variable ${EMPTY} 71 FOR ${i} IN RANGE 0 ${count} 72 ${rep_str}= Catenate SEPARATOR=${EMPTY} ${rep_str} ${str} 73 END 74 [return] ${rep_str} 75 76Surround Assembly Block With Nops 77 [Arguments] ${inner_assembly} ${preceeding_nops} ${following_nops} 78 ${start_nops}= Repeat String nop; ${preceeding_nops} 79 ${end_nops}= Repeat String nop; ${following_nops} 80 ${assembly}= Catenate SEPARATOR=${EMPTY} ${start_nops} ${inner_assembly} ${end_nops} 81 [return] ${assembly} 82 83Execute Instructions 84 [Arguments] ${instructions_count} 85 ${time_interval}= evaluate ${instructions_count} / 1000000 86 ${time_interval}= Format String {0:.6f} ${time_interval} 87 Execute Command sysbus.cpu PerformanceInMips 1 88 Execute Command emulation RunFor "${time_interval}" 89 90*** Test Cases *** 91Should Have Correct Instructions Count On Translation Block End 92 [Tags] instructions_counting 93 ${assembly}= Surround Assembly Block With Nops ${EMPTY} 10 0 94 Create Platform ${ARM64_PLATFORM} ${assembly} 95 Execute Command cpu MaximumBlockSize 7 96 Execute Command sysbus.cpu SetHookAtBlockEnd "cpu.Log(LogLevel.Info, 'BlockEnd Hook: Executed {0} Instructions', cpu.ExecutedInstructions)" 97 Create Log Tester 1 98 Wait For Log Entry BlockEnd Hook: Executed 7 Instructions pauseEmulation=true 99 100Should Have Correct Instructions Count After Multiple Translation Blocks 101 [Tags] instructions_counting 102 ${assembly}= Surround Assembly Block With Nops bl -0x24; 9 0 103 Create Platform ${ARM64_PLATFORM} ${assembly} 104 Execute Command sysbus.cpu SetHookAtBlockEnd "cpu.Log(LogLevel.Info, 'BlockEnd hook at PC: {} with {} executed instructions'.format(cpu.PC, cpu.ExecutedInstructions))" 105 Create Log Tester 1 106 Execute Instructions 100 107 FOR ${i} IN RANGE 1 10 108 Wait For Log Entry BlockEnd hook at PC: 0x0 with ${i * 10} executed instructions timeout=0 109 END 110 111Should Have Correct Instructions Count On Execute Instructions 112 [Tags] instructions_counting 113 ${assembly}= Surround Assembly Block With Nops ${EMPTY} 10 0 114 Create Platform ${ARM64_PLATFORM} ${assembly} 115 Execute Instructions 8 116 Expect Instructions Count 8 117 118Should Have Correct Instructions Count On WFI 119 [Tags] instructions_counting 120 ${assembly}= Surround Assembly Block With Nops wfi; 3 0 121 Create Platform ${ARM64_PLATFORM} ${assembly} 122 Execute Command cpu AddHookAtWfiStateChange 'self.Log(LogLevel.Info, "ENTER WFI - instructions count = {}".format(self.ExecutedInstructions))' 123 Create Log Tester 1 124 Start Emulation 125 126 Wait For Log Entry ENTER WFI - instructions count = 4 pauseEmulation=true 127 128Should Have Correct Instructions Count On MMU External Fault 129 [Tags] instructions_counting 130 ${assembly}= Surround Assembly Block With Nops lw a1, 0(a0); 4 0 131 Create Platform ${RISCV_PLATFORM} ${assembly} 132 Execute Command cpu EnableExternalWindowMmu true 133 Execute Command cpu SetRegister ${a0} 0x100000 134 Create Log Tester 1 135 Wait For Log Entry MMU fault - the address 0x100000 is not specified in any of the existing ranges 136 Expect Instructions Count 5 137 138Should Have Correct Instructions Count On Read Watchpoint 139 [Tags] instructions_counting 140 ${assembly}= Surround Assembly Block With Nops ldrb r0, [r1]; 7 4 141 Create Platform ${ARM_PLATFORM} ${assembly} 142 Execute Command sysbus.cpu SetRegister ${r1} ${WATCHPOINT_ADDRESS} 143 144 Execute Command sysbus AddWatchpointHook ${WATCHPOINT_ADDRESS} 1 Read "cpu.Log(LogLevel.Info, 'Watchpoint hook at PC: {}'.format(cpu.PC))" 145 Execute Command sysbus.cpu SetHookAtBlockBegin "cpu.Log(LogLevel.Info, 'BlockBegin hook at PC: {} with {} executed instructions'.format(cpu.PC, cpu.ExecutedInstructions))" 146 147 Create Log Tester 0 148 Expect Instructions Count 0 149 150 Execute Instructions 12 151 152 Wait For Log Entry Watchpoint hook at PC: 0x1c timeout=0 153 Wait For Log Entry BlockBegin hook at PC: 0x1c with 7 executed instructions timeout=0 154 155 Should Not Be In Log Watchpoint hook 156 Should Not Be In Log BlockBegin hook 157 158 Expect PC 0x30 159 Expect Instructions Count 12 160 161Should Have Correct Instructions Count On Uart Access 162 [Tags] instructions_counting 163 ${assembly}= Surround Assembly Block With Nops strb r0, [r1]; 7 4 164 Create Platform ${ARM_PLATFORM} ${assembly} 165 Create Terminal Tester sysbus.uart 166 167 Execute Command sysbus.cpu SetRegister ${r0} ${X_CHAR} 168 Execute Command sysbus.cpu SetRegister ${r1} ${ARM_UART_DATA_ADDRESS} 169 170 Wait For Prompt On Uart x pauseEmulation=true 171 172 Expect PC 0x20 173 Expect Instructions Count 8 174