| *** Variables *** |
| ${PLATFORM} SEPARATOR= |
| ... """ ${\n} |
| ... cpu: CPU.ARMv7A @ sysbus ${\n} |
| ... ${SPACE*4}cpuType: "cortex-a9" ${\n} |
| ... ${\n} |
| ... pmu: Miscellaneous.ArmPerformanceMonitoringUnit @ { ${\n} |
| ... ${SPACE*8}cpu; ${\n} |
| ... ${SPACE*8}sysbus new Bus.BusRangeRegistration { ${\n} |
| ... ${SPACE*8}${SPACE*4}address: ${MMIO_ADDRESS}; ${\n} |
| ... ${SPACE*8}${SPACE*4}size: 0x1000 ${\n} |
| ... ${SPACE*8}} ${\n} |
| ... ${SPACE*4}} ${\n} |
| ... ${SPACE*4}peripheralId: ${PERIPHERAL_ID} ${\n} |
| ... ${SPACE*4}withProcessorIdMMIORegisters: true ${\n} |
| ... ${\n} |
| ... memory: Memory.MappedMemory @ sysbus 0x0 ${\n} |
| ... ${SPACE*4}size: 0x20000 ${\n} |
| ... """ |
| |
| ${BOGUS_EVENT_1} 0x1 |
| ${BOGUS_EVENT_2} 0xAB |
| ${SOFTWARE_INCREMENT_EVENT} 0x00 |
| ${INSTRUCTIONS_EVENT} 0x8 |
| ${CYCLES_EVENT} 0x11 |
| |
| ${CPU_MIDR} 0x410fc090 |
| ${MMIO_ADDRESS} 0xF0000000 |
| ${MMIO_SOFTWARE_LOCK_KEY} 0xC5ACCE55 |
| ${PERIPHERAL_ID} 0xFEDCBA9876543210 |
| ${REG_ID_PFR1_OFFSET} 0xD24 |
| ${REG_MIDR_OFFSET} 0xD00 |
| ${REG_MPUIR_OFFSET} 0xD10 |
| ${REG_PMCCNTR_OFFSET} 0x07C |
| ${REG_PMCNTENSET_OFFSET} 0xC00 |
| ${REG_PMCR_OFFSET} 0xE04 |
| ${REG_PMLAR_OFFSET} 0xFB0 # MMIO-only register |
| ${REG_PMPID0_OFFSET} 0xFE0 |
| ${REG_PMPID2_OFFSET} 0xFE8 |
| ${REG_PMPID4_OFFSET} 0xFD0 |
| ${REG_PMSWINC_OFFSET} 0xCA0 |
| ${REG_PMXEVCNTR0_OFFSET} 0x000 |
| ${REG_PMXEVCNTR30_OFFSET} 0x078 |
| ${REG_PMXEVTYPER0_OFFSET} 0x400 |
| ${REG_PMXEVTYPER30_OFFSET} 0x478 |
| ${REG_TLBTR_OFFSET} 0xD0C |
| |
| *** Keywords *** |
| Create Machine |
| # Some keywords expect numbers to be printed as hex. |
| Execute Command numbersMode Hexadecimal |
| |
| Execute Command using sysbus |
| Execute Command mach create |
| Execute Command machine LoadPlatformDescriptionFromString ${PLATFORM} |
| |
| # Create infinite loop |
| Execute Command sysbus WriteDoubleWord 0x1000 0xE320F000 # nop |
| Execute Command sysbus WriteDoubleWord 0x1004 0xEAFFFFFD # b to 0x1000 |
| |
| # Set predefined PerformanceInMips, so it's possible to calculate |
| # the number of expected instructions to execute in the given time frame |
| Execute Command cpu PerformanceInMips 100 |
| Execute Command cpu PC 0x1000 |
| |
| Set Register Bits |
| [Arguments] ${regName} ${value} |
| ${enabledCounters}= Execute Command cpu.pmu GetRegister ${regName} |
| ${mask}= Evaluate hex(int($enabledCounters, 16) | int($value)) |
| |
| Execute Command cpu.pmu SetRegister ${regName} ${mask} |
| |
| Clear Register Bits |
| [Arguments] ${regName} ${value} |
| ${enabledCounters}= Execute Command cpu.pmu GetRegister ${regName} |
| ${mask}= Evaluate hex(int($enabledCounters, 16) & ~int($value)) |
| |
| Execute Command cpu.pmu SetRegister ${regName} ${mask} |
| |
| Assert Bit Set |
| [Arguments] ${value} ${bit} |
| ${isSet}= Evaluate (${value} & (1 << ${bit})) > 0 |
| Should Be True ${isSet} |
| |
| Assert Bit Unset |
| [Arguments] ${value} ${bit} |
| ${isNotSet}= Evaluate (${value} & (1 << ${bit})) == 0 |
| Should Be True ${isNotSet} |
| |
| Enable PMU |
| Set Register Bits "PMCR" 1 |
| |
| Disable PMU |
| Clear Register Bits "PMCR" 1 |
| |
| Reset PMU Counters |
| Set Register Bits "PMCR" 2 |
| |
| Reset PMU Cycle Counter |
| Set Register Bits "PMCR" 4 |
| |
| Set Cycles Divisor 64 |
| [Arguments] ${divisor} |
| IF ${divisor} |
| Set Register Bits "PMCR" 8 |
| ELSE |
| Clear Register Bits "PMCR" 8 |
| END |
| |
| Switch Privilege Mode |
| [Arguments] ${privileged} |
| # use CPSR to switch between PL0/PL1 |
| IF ${privileged} # PL1 - SVC mode |
| ${cpsr}= Execute Command cpu CPSR |
| ${cpsr}= Evaluate (int(${cpsr}) & ~0x1F ) | 0x13 |
| Execute Command cpu CPSR ${cpsr} |
| ELSE # PL0 |
| ${cpsr}= Execute Command cpu CPSR |
| ${cpsr}= Evaluate (int(${cpsr}) & ~0x1F ) | 0x10 |
| Execute Command cpu CPSR ${cpsr} |
| END |
| |
| Enable PMU Counter |
| [Arguments] ${counter} |
| ${value}= Evaluate (1 << int($counter)) |
| |
| Set Register Bits "PMCNTENSET" ${value} |
| |
| Disable PMU Counter |
| [Arguments] ${counter} |
| ${value}= Evaluate (1 << int($counter)) |
| |
| Execute Command cpu.pmu SetRegister "PMCNTENCLR" ${value} |
| |
| Enable Overflow Interrupt For PMU Counter |
| [Arguments] ${counter} |
| ${value}= Evaluate (1 << int($counter)) |
| |
| Execute Command cpu.pmu SetRegister "PMINTENSET" ${value} |
| |
| Disable Overflow Interrupt For PMU Counter |
| [Arguments] ${counter} |
| ${value}= Evaluate (1 << int($counter)) |
| |
| Execute Command cpu.pmu SetRegister "PMINTENCLR" ${value} |
| |
| Increment Software PMU Counter |
| [Arguments] ${counter} |
| ${value}= Evaluate (1 << int($counter)) |
| |
| Execute Command cpu.pmu SetRegister "PMSWINC" ${value} |
| |
| Assert PMU Counter Is Equal To |
| [Arguments] ${counter} ${value} |
| ${cnt}= Execute Command cpu.pmu GetCounterValue ${counter} |
| |
| Should Be Equal As Integers ${cnt} ${value} |
| |
| Assert Executed Instructions Equal To |
| [Arguments] ${value} |
| ${executedInstructions}= Execute Command cpu ExecutedInstructions |
| |
| Should Be Equal As Integers ${executedInstructions} ${value} |
| |
| Assert PMU Cycle Counter Equal To |
| [Arguments] ${value} |
| ${cycles}= Execute Command cpu.pmu GetCycleCounterValue |
| |
| Should Be Equal As Integers ${cycles} ${value} |
| |
| Assert PMU IRQ Is Set |
| ${irqState}= Execute Command cpu.pmu IRQ |
| Should Contain ${irqState} GPIO: set |
| |
| Assert PMU IRQ Is Unset |
| ${irqState}= Execute Command cpu.pmu IRQ |
| Should Contain ${irqState} GPIO: unset |
| |
| Assert PMU Counter Overflowed |
| [Arguments] ${counter} |
| # n-th bit denotes overflow status for the n-th PMU counter |
| ${overflowStatus}= Execute Command cpu.pmu GetRegister "PMOVSR" |
| Assert Bit Set ${overflowStatus} ${counter} |
| |
| Assert PMU Counter Not Overflowed |
| [Arguments] ${counter} |
| ${overflowStatus}= Execute Command cpu.pmu GetRegister "PMOVSR" |
| Assert Bit Unset ${overflowStatus} ${counter} |
| |
| Assert Command Output Equal To |
| [Arguments] ${expectedOutput} ${command} |
| ${output}= Execute Command ${command} |
| Should Be Equal ${output} ${expectedOutput} strip_spaces=True |
| |
| Get ${name} Register Offset |
| ${variableName}= Set Variable ${{ "REG_" + "${name}" + "_OFFSET" }} |
| [Return] ${ ${variableName} } |
| |
| MMIO-Accessed ${name} Should Be Equal To Value ${expectedValue} |
| ${offset}= Get ${name} Register Offset |
| ${output}= Execute Command sysbus ReadDoubleWord ${{ ${MMIO_ADDRESS} + ${offset} }} |
| Should Be Equal As Integers ${output} ${expectedValue} |
| |
| MMIO-Accessed ${name} Should Be Equal To System Register |
| # There are no direct PMXEVCNTR and PMXEVTYPER system registers for all counters but only |
| # two such registers depending on PMSELR so PMU wrapping methods have to be used instead. |
| IF "${name}".startswith("PMXEVCNTR") |
| ${expectedValue}= Execute Command cpu.pmu GetCounterValue ${{ int("${name}".replace("PMXEVCNTR", "")) }} |
| ELSE IF "${name}".startswith("PMXEVTYPER") |
| ${expectedValue}= Execute Command cpu.pmu GetCounterEvent ${{ int("${name}".replace("PMXEVTYPER", "")) }} |
| ELSE |
| ${expectedValue}= Execute Command cpu GetSystemRegisterValue "${name}" |
| END |
| |
| MMIO-Accessed ${name} Should Be Equal To Value ${expectedValue} |
| |
| Write ${value} To ${name} Using MMIO |
| ${offset}= Get ${name} Register Offset |
| Execute Command sysbus WriteDoubleWord ${{ ${MMIO_ADDRESS} + ${offset} }} ${value} |
| |
| Unlock MMIO Writes |
| Write ${MMIO_SOFTWARE_LOCK_KEY} To PMLAR Using MMIO |
| |
| *** Test Cases *** |
| Should Count Cycles |
| Create Machine |
| |
| Enable PMU |
| Enable PMU Counter 31 # Cycle counter |
| |
| Execute Command emulation RunFor "00:00:01.12" |
| |
| # Given a known PerformanceInMIPS, it can be assumed that 112 000 000 instructions have been executed |
| Assert PMU Cycle Counter Equal To 112 000 000 |
| Assert Executed Instructions Equal To 112 000 000 |
| |
| Should Count Cycles With Divisor |
| Create Machine |
| Enable PMU Counter 31 # Cycle counter |
| Enable PMU |
| Set Cycles Divisor 64 ${True} |
| |
| Execute Command emulation RunFor "00:00:00.01" |
| Assert Executed Instructions Equal To 1000000 |
| Assert PMU Cycle Counter Equal To 15625 |
| |
| Set Cycles Divisor 64 ${False} |
| |
| Execute Command emulation RunFor "00:00:00.01" |
| Assert Executed Instructions Equal To 2000000 |
| Assert PMU Cycle Counter Equal To 1015625 |
| |
| Should Program PMU Counter To Count Cycles |
| Create Machine |
| |
| Enable PMU |
| Execute Command cpu.pmu SetCounterEvent 0 ${CYCLES_EVENT} |
| Enable PMU Counter 0 |
| |
| Execute Command emulation RunFor "00:00:01.12" |
| |
| # As above, given PerformanceInMIPS, we know how many instructions to expect |
| # One cycle is equal to one instruction, this is not a mistake |
| Assert Executed Instructions Equal To 112 000 000 |
| Assert PMU Counter Is Equal To 0 112 000 000 |
| |
| # Now, an instruction should be equal to 1.25 cycles |
| Execute Command cpu CyclesPerInstruction 1.25 |
| Execute Command emulation RunFor "00:00:00.01" |
| |
| # Executed 1 000 000 instructions, so 1 250 000 cycles |
| Assert Executed Instructions Equal To 113 000 000 |
| Assert PMU Counter Is Equal To 0 113 250 000 |
| |
| Should Program PMU Counter To Count Instructions |
| Create Machine |
| |
| # Cycles value will be used in dependent tests |
| Enable PMU Counter 31 |
| Enable PMU |
| Execute Command cpu.pmu SetCounterEvent 0 ${INSTRUCTIONS_EVENT} |
| Enable PMU Counter 0 |
| |
| Execute Command emulation RunFor "00:00:01.12" |
| Assert Executed Instructions Equal To 112 000 000 |
| Assert PMU Counter Is Equal To 0 112 000 000 |
| |
| Provides program-counter |
| |
| Should Reset PMU counters |
| Requires program-counter |
| |
| Assert PMU Counter Is Equal To 0 112 000 000 |
| Reset PMU Counters |
| Assert PMU Counter Is Equal To 0 0 |
| |
| Assert PMU Cycle Counter Equal To 112 000 000 |
| Reset PMU Cycle Counter |
| Assert PMU Cycle Counter Equal To 0 |
| |
| Should Kick Software Increment |
| Create Machine |
| |
| # Configure PMU counters, only Counter 0 subscribes to Software Increment event, Counter 1 subscribes to non-implemented event |
| # So only Counter 0 is expected to be incremented |
| Execute Command cpu.pmu SetCounterEvent 0 ${SOFTWARE_INCREMENT_EVENT} |
| Execute Command cpu.pmu SetCounterEvent 1 ${BOGUS_EVENT_1} |
| |
| # Verify the configured events by reading their event ids |
| ${ev1}= Execute Command cpu.pmu GetCounterEvent 1 |
| ${ev0}= Execute Command cpu.pmu GetCounterEvent 0 |
| Should Be Equal As Integers ${ev1} 1 |
| Should Be Equal As Integers ${ev0} 0 |
| |
| Increment Software PMU Counter 0 |
| Increment Software PMU Counter 1 |
| |
| # Counters and PMU are disabled, should not count |
| Assert PMU Counter Is Equal To 0 0 |
| Assert PMU Counter Is Equal To 1 0 |
| |
| Enable PMU Counter 0 |
| |
| Increment Software PMU Counter 1 |
| Increment Software PMU Counter 0 |
| |
| # Still not counting, PMU is not enabled |
| Assert PMU Counter Is Equal To 0 0 |
| Assert PMU Counter Is Equal To 1 0 |
| Enable PMU |
| |
| Increment Software PMU Counter 0 |
| Increment Software PMU Counter 1 |
| |
| # PMU Counter 1 is not a Software Increment, so it shouldn't increment at all |
| # Counter 0 is incremented only once, after "Enable PMU". Previous increments were invalid, since PMU was disabled |
| Assert PMU Counter Is Equal To 0 1 |
| Assert PMU Counter Is Equal To 1 0 |
| |
| Should Respect PMU Counter Pasue And Resume |
| Create Machine |
| Enable PMU |
| |
| Execute Command cpu.pmu SetCounterEvent 1 ${CYCLES_EVENT} |
| Enable PMU Counter 1 |
| Execute Command emulation RunFor "00:00:00.01" |
| |
| Assert PMU Counter Is Equal To 1 1000000 |
| Assert Executed Instructions Equal To 1000000 |
| |
| # Shouldn't count with disabled PMU |
| Disable PMU |
| Execute Command emulation RunFor "00:00:00.01" |
| |
| Assert PMU Counter Is Equal To 1 1000000 |
| Assert Executed Instructions Equal To 2000000 |
| |
| Enable PMU |
| Execute Command emulation RunFor "00:00:00.01" |
| |
| Assert PMU Counter Is Equal To 1 2000000 |
| Assert Executed Instructions Equal To 3000000 |
| |
| # Shouldn't count when the counter is disabled |
| Disable PMU Counter 1 |
| Execute Command emulation RunFor "00:00:00.01" |
| |
| Assert PMU Counter Is Equal To 1 2000000 |
| Assert Executed Instructions Equal To 4000000 |
| |
| Enable PMU Counter 1 |
| Execute Command emulation RunFor "00:00:00.01" |
| |
| Assert PMU Counter Is Equal To 1 3000000 |
| Assert Executed Instructions Equal To 5000000 |
| |
| Should Trigger Cycles Overflow |
| Create Machine |
| |
| Enable PMU |
| |
| ## Counter 2 |
| # The performance in MIPS is known, so it's possible to calculate the exact moment the counter should overflow |
| # Configure counter, so after 3 000 000 instructions it should have overflowed and have the value 2 stored |
| # so it's set to "UINT32_MAX - value + 3" |
| Execute Command cpu.pmu SetCounterEvent 2 ${CYCLES_EVENT} |
| Execute Command cpu.pmu SetCounterValue 2 0xFFD23942 |
| Enable Overflow Interrupt For PMU Counter 2 |
| Enable PMU Counter 2 |
| |
| ## Counter 1 |
| Execute Command cpu.pmu SetCounterEvent 1 ${CYCLES_EVENT} |
| # expected to execute 1 000 000 instructions, so load "UINT32_MAX - value" to counter |
| # it is expected to overflow one instruction after |
| Execute Command cpu.pmu SetCounterValue 1 0xFFF0BDBF |
| Enable Overflow Interrupt For PMU Counter 1 |
| Enable PMU Counter 1 |
| |
| # See that it didn't overflow too soon |
| Execute Command emulation RunFor "00:00:00.01" |
| Assert Executed Instructions Equal To 1000000 |
| # The value is counter's base value "0xFFF0BDBF" + 1 000 000 expected instructions to execute |
| Assert PMU Counter Is Equal To 1 0xFFFFFFFF |
| Assert PMU Counter Not Overflowed 1 |
| Assert PMU IRQ Is Unset |
| |
| # It will overflow 1 instruction after, we now execute 100 000, so overflow bit has to be set |
| Execute Command emulation RunFor "00:00:00.001" |
| Assert PMU Counter Overflowed 1 |
| Assert PMU IRQ Is Set |
| |
| Provides cycles-overflow |
| |
| Should Resume Execution After Cycles Overflow |
| Requires cycles-overflow |
| |
| Execute Command emulation RunFor "00:00:00.01" |
| Assert Executed Instructions Equal To 2100000 |
| # instructions are counted from 0 after overflow, so instead from 1 000 000 + 100 000 subtract 1 |
| Assert PMU Counter Is Equal To 1 1099999 |
| |
| Provides resumed-after-overflow |
| |
| Should Overflow Second Time |
| Requires resumed-after-overflow |
| # Clear overflow bit for counter 1 |
| Execute Command cpu.pmu SetRegister "PMOVSR" 0x2 |
| |
| Execute Command emulation RunFor "00:00:00.009" |
| Assert Executed Instructions Equal To 3000000 |
| Assert PMU Counter Is Equal To 2 2 |
| |
| Assert PMU Counter Overflowed 2 |
| |
| Should Increment Bogus Event From Monitor |
| # The event is unimplemented, and there will be warnings in the logs |
| # but still can be used it in a test scenario |
| Create Machine |
| |
| Enable PMU |
| Execute Command cpu.pmu SetCounterEvent 1 ${BOGUS_EVENT_2} |
| Enable PMU Counter 1 |
| |
| Execute Command cpu.pmu BroadcastEvent ${BOGUS_EVENT_2} 5 |
| Assert PMU Counter Is Equal To 1 5 |
| |
| # now, let's overflow |
| Enable Overflow Interrupt For PMU Counter 1 |
| Execute Command cpu.pmu BroadcastEvent ${BOGUS_EVENT_2} 0xFFFFFFFF |
| Assert PMU Counter Is Equal To 1 4 |
| |
| Assert PMU Counter Overflowed 1 |
| Assert PMU IRQ Is Set |
| |
| Should Count Instructions With PL Masking |
| Create Machine |
| |
| Enable PMU Counter 0 |
| Execute Command cpu.pmu SetCounterEvent 0 ${INSTRUCTIONS_EVENT} ignoreCountAtPL0=false ignoreCountAtPL1=true |
| Enable PMU |
| Enable Overflow Interrupt For PMU Counter 0 |
| |
| Execute Command emulation RunFor "00:00:00.01" |
| Assert Executed Instructions Equal To 1000000 |
| # The counter doesn't count at PL1, so should be zero |
| Assert PMU Counter Is Equal To 0 0 |
| |
| Switch Privilege Mode ${False} |
| Execute Command emulation RunFor "00:00:00.01" |
| Assert Executed Instructions Equal To 2000000 |
| # The PMU counter only counted in PL0, so only 1 000 000 instructions |
| Assert PMU Counter Is Equal To 0 1000000 |
| |
| Execute Command cpu.pmu SetCounterEvent 0 ${INSTRUCTIONS_EVENT} ignoreCountAtPL0=true ignoreCountAtPL1=true |
| # Now, counting at PL0 is disabled too, so PMU counter should not progress |
| Execute Command emulation RunFor "00:00:00.01" |
| Assert Executed Instructions Equal To 3000000 |
| Assert PMU Counter Is Equal To 0 1000000 |
| |
| # See that the counter doesn't count and doesn't trigger overflow |
| # Configure counter, so after 3 000 000 instructions it should have overflowed and have the value 2 stored |
| # so it's set to "UINT32_MAX - value + 3" |
| # But it shouldn't count anything at PL0 |
| Execute Command cpu.pmu SetCounterValue 0 0xFFD23942 |
| Execute Command emulation RunFor "00:00:00.03" |
| Assert Executed Instructions Equal To 6000000 |
| # No progress for the couner |
| Assert PMU Counter Is Equal To 0 0xFFD23942 |
| Assert PMU Counter Not Overflowed 0 |
| Assert PMU IRQ Is Unset |
| |
| # Now, switch the mode back to PL1 and enable counting events there |
| Execute Command cpu.pmu SetCounterEvent 0 ${INSTRUCTIONS_EVENT} ignoreCountAtPL0=true ignoreCountAtPL1=false |
| Switch Privilege Mode ${True} |
| |
| # The counter hadn't progressed at all, so it's not necessary to set it's value again |
| Execute Command emulation RunFor "00:00:00.03" |
| Assert Executed Instructions Equal To 9000000 |
| Assert PMU Counter Is Equal To 0 2 |
| Assert PMU Counter Overflowed 0 |
| Assert PMU IRQ Is Set |
| |
| Should Allow MMIO Writes Only After Disabling Software Lock |
| Create Machine |
| |
| Create Log Tester 0 |
| Execute Command logLevel -1 pmu |
| Assert Command Output Equal To True pmu SoftwareLockEnabled |
| |
| # Try writing. |
| Write 0xAB To PMXEVTYPER0 Using MMIO |
| Wait For Log Entry write ignored |
| Wait For Log Entry Software Lock can be cleared by writing ${MMIO_SOFTWARE_LOCK_KEY} to the PMLAR register at ${REG_PMLAR_OFFSET} |
| MMIO-Accessed PMXEVTYPER0 Should Be Equal To Value 0 |
| |
| # Try unlocking with invalid key. |
| ${invalidUnlockKey}= Set Variable 0xABCD |
| Write ${invalidUnlockKey} To PMLAR Using MMIO |
| Wait For Log Entry Tried to disable Software Lock with invalid value ${invalidUnlockKey}, should be ${MMIO_SOFTWARE_LOCK_KEY} |
| Assert Command Output Equal To True pmu SoftwareLockEnabled |
| |
| # Unlock. |
| Unlock MMIO Writes |
| Wait For Log Entry Software Lock disabled |
| Assert Command Output Equal To False pmu SoftwareLockEnabled |
| |
| # Write again. |
| Write ${BOGUS_EVENT_1} To PMXEVTYPER0 Using MMIO |
| Should Not Be In Log write ignored |
| Wait For Log Entry cpu: Invalid/Unimplemented event ${BOGUS_EVENT_1} selected for PMU counter 0 |
| MMIO-Accessed PMXEVTYPER0 Should Be Equal To Value ${BOGUS_EVENT_1} |
| |
| Should Kick Software Incremented Counters Using MMIO |
| Create Machine |
| Unlock MMIO Writes |
| |
| # Enable PMU. |
| Write 0x1 To PMCR Using MMIO |
| |
| # Set counters 0 and 30 to software increment event and enable them. |
| Write ${SOFTWARE_INCREMENT_EVENT} To PMXEVTYPER0 Using MMIO |
| Write ${SOFTWARE_INCREMENT_EVENT} To PMXEVTYPER30 Using MMIO |
| Write ${{ (1 << 30) | 1 }} To PMCNTENSET Using MMIO |
| |
| # Increment counters using both MMIO and System Registers. |
| Write 1 To PMSWINC Using MMIO |
| Write ${{ 1 << 30 }} To PMSWINC Using MMIO |
| Increment Software PMU Counter 30 |
| |
| # Make sure the MMIO-accessed count is valid and equal to system registers. |
| MMIO-Accessed PMXEVCNTR0 Should Be Equal To Value 1 |
| MMIO-Accessed PMXEVCNTR0 Should Be Equal To System Register |
| MMIO-Accessed PMXEVCNTR30 Should Be Equal To Value 2 |
| MMIO-Accessed PMXEVCNTR30 Should Be Equal To System Register |
| |
| Should Read Peripheral ID Using MMIO |
| Create Machine |
| |
| ${peripheralId}= Execute Command pmu PeripheralId |
| ${peripheralId}= Strip String ${peripheralId} |
| |
| # Peripheral ID's bits 20-23 should contain variant from bits 20-23 of MIDR. |
| Should Be Equal As Integers ${{ ((${peripheralId}^${CPU_MIDR}) >> 20) & 0xF }} 0 |
| |
| # Each of PMPID0-PMPID7 contains 8 bits from PeripheralId. |
| MMIO-Accessed PMPID0 Should Be Equal To Value ${{ ${peripheralId} & 0xFF }} |
| MMIO-Accessed PMPID2 Should Be Equal To Value ${{ (${peripheralId} >> 16) & 0xFF }} |
| MMIO-Accessed PMPID4 Should Be Equal To Value ${{ (${peripheralId} >> 32) & 0xFF }} |
| |
| Should Read Processor ID System Registers Using MMIO |
| Create Machine |
| |
| MMIO-Accessed ID_PFR1 Should Be Equal To System Register |
| MMIO-Accessed MIDR Should Be Equal To System Register |
| # MIDR is read for MPUIR because Cortex-A9 doesn't have MPU. |
| MMIO-Accessed MPUIR Should Be Equal To Value ${CPU_MIDR} |
| MMIO-Accessed TLBTR Should Be Equal To System Register |
| |
| Should Read PMU Registers Using MMIO |
| # Let's use a saved state with enabled cycle counter and counter 0 counting instructions. |
| Requires program-counter |
| |
| # Compare PMU registers used in the case providing `program-counter` state. |
| MMIO-Accessed PMXEVCNTR0 Should Be Equal To System Register |
| MMIO-Accessed PMXEVTYPER0 Should Be Equal To System Register |
| MMIO-Accessed PMCCNTR Should Be Equal To System Register |
| MMIO-Accessed PMCNTENSET Should Be Equal To System Register |
| MMIO-Accessed PMCR Should Be Equal To System Register |