589 lines
24 KiB
Plaintext
589 lines
24 KiB
Plaintext
*** 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
|