[Need Help] How to Read CNTPCT_EL0 Without Trapping to EL2?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
CorkiMain
Posts: 10
Joined: Wed Aug 07, 2024 10:13 am
Libera.chat IRC: CorkiMain

[Need Help] How to Read CNTPCT_EL0 Without Trapping to EL2?

Post by CorkiMain »

Hello, I'm having a problem where reads to the CNTPCT_EL0 register traps to EL2 on hardware.

I wrote some basic code to perform delays using the CNTPCT_EL0 and CNTFRQ_EL0 registers. The code is written in Arm64 Assembly and runs at EL1. When I run the code in QEMU, it works perfectly. However, when I run the code on a Raspberry Pi 5, the following instruction always traps to EL2.

Code: Select all

mrs     x9,     CNTPCT_EL0
I tried to follow the code for the documentation that describes how to access the register from the architecture reference manual.

Code: Select all

if PSTATE.EL == EL0 then
    if !(EL2Enabled() && HCR_EL2.<E2H,TGE> == '11') && CNTKCTL_EL1.EL0PCTEN == '0' then
        if EL2Enabled() && HCR_EL2.TGE == '1' then
            AArch64.SystemAccessTrap(EL2, 0x18);
        else
            AArch64.SystemAccessTrap(EL1, 0x18);
    elsif EL2Enabled() && HCR_EL2.E2H == '0' && CNTHCTL_EL2.EL1PCTEN == '0' then
        AArch64.SystemAccessTrap(EL2, 0x18);
    elsif EL2Enabled() && HCR_EL2.<E2H,TGE> == '10' && CNTHCTL_EL2.EL1PCTEN == '0' then
        AArch64.SystemAccessTrap(EL2, 0x18);
    elsif EL2Enabled() && HCR_EL2.<E2H,TGE> == '11' && CNTHCTL_EL2.EL0PCTEN == '0' then
        AArch64.SystemAccessTrap(EL2, 0x18);
    else
        return CNTPCT_EL0;
elsif PSTATE.EL == EL1 then
    if EL2Enabled() && CNTHCTL_EL2.EL1PCTEN == '0' then
        AArch64.SystemAccessTrap(EL2, 0x18);
    else
        return CNTPCT_EL0;
elsif PSTATE.EL == EL2 then
    return CNTPCT_EL0;
elsif PSTATE.EL == EL3 then
    return CNTPCT_EL0;
I set CNTHCTL_EL2.EL1PCTEN to 1. I expected this to fix the issue because I am running at EL1, so the value of CNTPCT_EL0 should be returned. However, the instruction still causes a trap to EL2. The value of ESR_EL2 is 0x6232f921, which just tells me that the instruction to read the register is causing the exception.

I'd appreciate any advice on how to stop this read from trapping to EL2! :P
Octocontrabass
Member
Member
Posts: 5777
Joined: Mon Mar 25, 2013 7:01 pm

Re: [Need Help] How to Read CNTPCT_EL0 Without Trapping to EL2?

Post by Octocontrabass »

CorkiMain wrote: Thu May 15, 2025 12:31 pmI set CNTHCTL_EL2.EL1PCTEN to 1.
The only thing I can think of is that maybe you're setting the wrong bit by mistake? Otherwise it sounds like you're doing everything right.
User avatar
CorkiMain
Posts: 10
Joined: Wed Aug 07, 2024 10:13 am
Libera.chat IRC: CorkiMain

Re: [Need Help] How to Read CNTPCT_EL0 Without Trapping to EL2?

Post by CorkiMain »

Octocontrabass wrote: Thu May 15, 2025 8:43 pm The only thing I can think of is that maybe you're setting the wrong bit by mistake? Otherwise it sounds like you're doing everything right.
Maybe I goofed something up. I'll double check the register value that I'm writing and that I'm in EL1. I'll report back if I find the issue.
Post Reply