ARM Cortex-A55 Unaligned Access Fault in EL3 with MMU Disabled

When working with the ARM Cortex-A55 processor in the 64-bit execution state (AArch64) at Exception Level 3 (EL3), developers may encounter a data abort exception triggered by unaligned memory accesses, even when the MMU and caches are disabled. This issue arises when attempting to perform memory operations, such as STUR (Store Register Unscaled), on addresses that are not naturally aligned to the size of the data being accessed. In the provided scenario, the STUR xzr, [x0, #-0x1c] instruction attempts to store the zero register (xzr) at an unaligned address, resulting in a synchronous exception.

The Cortex-A55 processor, like other ARMv8-A cores, has specific alignment requirements for memory accesses. When the MMU is disabled, all memory is treated as device memory, which imposes stricter alignment rules compared to normal memory. Device memory typically requires natural alignment, meaning that the address must be a multiple of the access size (e.g., 8-byte alignment for 64-bit accesses). Failure to meet these alignment requirements results in a data abort exception, even if the SCTLR_EL3.A (Alignment Check Enable) bit is cleared to disable alignment fault checking.

The exception is reported in the ESR_EL3 (Exception Syndrome Register) with an encoding of 0x96000061, indicating a synchronous abort due to an unaligned access. The FAR_EL3 (Fault Address Register) contains the address that caused the fault (0x00000000201ffeb4 in this case). The CPSR and SPSR_EL3 registers provide additional context about the processor state at the time of the exception.

SCTLR_EL3.A Bit Misconfiguration and Device Memory Alignment Constraints

The root cause of the unaligned access fault lies in the interaction between the SCTLR_EL3.A bit and the memory type being accessed. The SCTLR_EL3.A bit controls whether alignment faults are enabled for normal memory accesses. When this bit is cleared (0), the processor does not generate alignment faults for normal memory accesses, allowing unaligned accesses to proceed without exceptions. However, this behavior does not apply to device memory.

Device memory, which is the default memory type when the MMU is disabled, has stricter alignment requirements. Even with SCTLR_EL3.A cleared, unaligned accesses to device memory will still trigger data abort exceptions. This is because device memory is typically used for memory-mapped I/O registers, where unaligned accesses could lead to unpredictable behavior or hardware faults. The Cortex-A55 enforces these alignment rules to ensure reliable operation.

In the provided scenario, the STUR xzr, [x0, #-0x1c] instruction attempts to store a 64-bit value at an address that is not 8-byte aligned (0x201ffeb4). Since the MMU is disabled, the memory is treated as device memory, and the unaligned access triggers a data abort exception. The ESR_EL3 value (0x96000061) confirms that the exception is due to an unaligned access.

Resolving Unaligned Access Faults in Device Memory Without Enabling the MMU

To resolve the unaligned access fault without enabling the MMU, developers must ensure that all memory accesses to device memory are naturally aligned. This can be achieved by carefully aligning data structures and ensuring that pointers used for memory operations meet the alignment requirements. In cases where unaligned accesses are unavoidable, developers can use a combination of load/store instructions to manually handle the unaligned access.

For example, instead of using a single STUR instruction to store a 64-bit value at an unaligned address, the operation can be split into multiple 32-bit or 8-bit stores. This approach ensures that each individual access is aligned, avoiding the data abort exception. Below is an example of how to handle an unaligned 64-bit store using 32-bit stores:

// Original unaligned 64-bit store
STUR xzr, [x0, #-0x1c]

// Split into two 32-bit stores
MOV w1, #0          // Lower 32 bits of xzr
MOV w2, #0          // Upper 32 bits of xzr
STR w1, [x0, #-0x1c] // Store lower 32 bits
STR w2, [x0, #-0x18] // Store upper 32 bits

This approach ensures that each 32-bit store is aligned, preventing the data abort exception. However, it is important to note that this method increases the number of memory accesses and may impact performance. Therefore, it should only be used when absolutely necessary.

Another approach is to use the LDUR/STUR instructions with smaller access sizes (e.g., 8-bit or 16-bit) to handle unaligned accesses. For example:

// Split into eight 8-bit stores
MOV w1, #0          // Lower 8 bits of xzr
STRB w1, [x0, #-0x1c] // Store byte 0
STRB w1, [x0, #-0x1b] // Store byte 1
STRB w1, [x0, #-0x1a] // Store byte 2
STRB w1, [x0, #-0x19] // Store byte 3
STRB w1, [x0, #-0x18] // Store byte 4
STRB w1, [x0, #-0x17] // Store byte 5
STRB w1, [x0, #-0x16] // Store byte 6
STRB w1, [x0, #-0x15] // Store byte 7

This method ensures that each byte store is aligned, but it further increases the number of memory accesses and should be used sparingly.

In summary, the unaligned access fault in the Cortex-A55 when the MMU is disabled is caused by the stricter alignment requirements of device memory. To resolve this issue, developers must ensure that all memory accesses to device memory are naturally aligned or use manual techniques to handle unaligned accesses. While these techniques can prevent data abort exceptions, they may impact performance and should be used judiciously.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *