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
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'd appreciate any advice on how to stop this read from trapping to EL2!
