We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello ,all。I am now learning the use of PMU. But when I do this, PMXEVCNTR_EL0 is always 0. PMCCNTR_EL0 is normal
Device: cortex-a72(ARMV8.2-A)
System: Rtos(ThreadX)
step
1. Configure PMCNTENSET_EL0 to enable Cycle counter
2. Configure pmuserenr_el0(en).
3. Configure PMSELR_EL0 to select count.
4. Configure PMXEVTYPER_EL0 and set events.
5. Configure PMCNTENSET_EL0 to enable Cycle counter and event counter
6. Configure PMCR_EL0 and enable PMU, reset Cycle counter, and event counter
7. Run the test code
8 Stop the PMUs
9. Configure PMSELR_EL0 to select count,
10 Read PMXEVCNTR_EL0 and PMCCNTR_EL0.
result
PMXEVCNTR_EL0 is 0, and PMCCNTR_EL0 is normal
I have checked the value of the relevant register, and the value of the register is indeed changed. I have checked the Arm® Cortex®-A76 Core Technical Reference Manual, and all the events set are also supported.
Note: The code is running in firmware.code:void ARM_PMU_Start(void) { // PMU->CTRL |= PMU_CTRL_ENABLE_Msk;
int val=0;
__asm__ volatile("msr pmuserenr_el0, %0" :: "r" ((1 << 0) | (1 << 2)));
__asm__ volatile("msr PMSELR_EL0, %0" : : "r" (0)); __asm__ volatile("isb" : :); __asm__ volatile("msr PMXEVTYPER_EL0, %0" : : "r" (0x2)); __asm__ volatile("isb" : :);
__asm__ volatile("msr PMSELR_EL0, %0" : : "r" (1)); __asm__ volatile("isb" : :); __asm__ volatile("msr PMXEVTYPER_EL0, %0" : : "r" (0x4)); __asm__ volatile("isb" : :);
__asm__ volatile("msr PMSELR_EL0, %0" : : "r" (2)); __asm__ volatile("isb" : :); __asm__ volatile("msr PMXEVTYPER_EL0, %0" : : "r" (0x6)); __asm__ volatile("isb" : :); __asm__ volatile("msr PMCNTENSET_EL0, %0" : : "r" ((7|(1<<31)))); __asm__ volatile("isb" : :);
__asm__ volatile("mrs %0, PMCR_EL0" : "=r" (val)); val|=1 << 0; val|=1 << 1; val|=1 << 2; __asm__ volatile("msr PMCR_EL0, %0" : : "r" (val)); __asm__ volatile("isb" : :);
}void ARM_PMU_Stop(){ int val=0; __asm__ volatile("mrs %0, pmcr_el0" : "=r" (val)); __asm__ volatile("msr pmcr_el0, %0" : : "r" (val&(~PMU_CTRL_ENABLE_Msk))); __asm__ volatile("mrs %0, pmccntr_el0" : "=r" (val)); printf("Perf:pmccntr_el0 %d \n",val);
__asm__ volatile("msr PMSELR_EL0, %0" : : "r" (0)); __asm__ volatile("isb" : :); __asm__ volatile("mrs %0, PMXEVCNTR_EL0" : "=r" (val)); printf("Perf:PMXEVCNTR_EL0 %d \n",val);
__asm__ volatile("msr PMSELR_EL0, %0" : : "r" (1)); __asm__ volatile("isb" : :); __asm__ volatile("mrs %0, PMXEVCNTR_EL0" : "=r" (val)); printf("Perf:PMXEVCNTR_EL0 %d \n",val);
__asm__ volatile("msr PMSELR_EL0, %0" : : "r" (2)); __asm__ volatile("isb" : :); __asm__ volatile("mrs %0, PMXEVCNTR_EL0" : "=r" (val)); printf("Perf:PMXEVCNTR_EL0 %d \n",val);}void Test_PMU(){ ARM_PMU_Start(); test_code();//the test code ARM_PMU_Stop(); }
Here you should also enable both event counts & cycle counter read feature.From the code "__asm__ volatile("msr pmuserenr_el0, %0" :: "r" ((1 << 0) | (1 << 2)))", we saw that you have enabled CR & EN feature. I think you should also set the ER(bit 3) to make event counters read enabled.
I try to enable read feature, but it still return 0 for event counter, any other suggestion?
I did that, but the register is still 0