This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

PMU event count register PMEVCNTR<n> alway is 0

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();

}