Reputation: 11
I am writing an MMU Fault exception handler for my dual-core Cortex-A76 CPU, AArch64 architecture. The OS is ThreadX RTOS, so all code runs at EL1 level.
When an MMU fault is triggered, the ESR_EL1 value is either 0x860000XX or 0x960000XX, corresponding to EC values 0x21 and 0x25. FAR_EL1 is supposed to store the memory address that caused the fault, but it does not.
I am using the CodeViser emulator for debugging.
The last instruction executed was 51840: 94171570 bl 616e00
. After execution, the system state is as shown in Figure 1. In Figure 1, the PC value is 0x616e00. Because the address 0x616e00 does not have an MMU TLB configuration, data cannot be read from this address. When a single step (Step) is executed, an MMU Instruction Abort is triggered, and the system jumps to the 0x200 vector in the exception vector table. The state at this point is shown in Figure 2.
In Figure 2, ELR_EL1 is 0x616e00, indicating that the exception was caused by the instruction at 0x616e00. ESR_EL1 is 0x86000006, indicating this is an MMU Instruction Abort exception. The exception details can be seen in Figure 3. According to the definition of FAR_EL1, the value of FAR_EL1 should be 0x616e00 in this case, but it is not. Can someone explain why this is happening? We expect FAR_EL1 to display the correct value.
According to the definition of FAR_EL1, for ESR_EL1 values of 0x860000XX (MMU instruction abort) and 0x960000XX (MMU data abort), FAR_EL1 should store the memory address that caused the exception.
I have observed that sometimes FAR_EL1 correctly stores the faulting memory address, but other times it does not.
Upvotes: 1
Views: 124