Search code examples
memory-alignmentarmv8

ARMv8: unaligned LDR in EL3 causes exception Data Abort


I have the following bare-metal startup code for ARMv8 on FPGA, for testing the data alignment access:

.section .text.boot
.global _start
_start:
    mrs x0, mpidr_el1
    and x0, x0, #0xff
    cbz x0, master
    b proc_hang

master:    
    ldr x1, =stack_top
    mov sp, x1

    // test unaligned assess
    mov x4, #0x3e61
    mov x1, xzr
    ldr w0, [x4, x1, lsl #0x2]

    bl main
    b .

proc_hang:
    wfe
    b proc_hang

Upon reboot/reset, EL is 3.

The ldr w0, [x4, x1, lsl #0x2] instruction above will trigger an Exception in EL3, and PC changes to 0x200, which is the 5th entry of the default VBAR_EL3 (0x0). This means the exception is CURR_EL_SPX_SYNC (meaning sync exception in the current EL3, using SP3, according to my current understanding).

At this time, the value of ESR_EL3 is set to 0x96000021, with in which the EC bits (Exception Class, bit 31:26) is 0b100101, means "Data Abort".

The current SCTLR_EL3 value, however, is 0x40c50838, within which the bit 1 is 0, meaning alignment check is disabled. My expectation is that, if alignment check is disabled, then the above LDR instruction should success without raising exceptions.

My questions are:

  • is this expected behavior?
  • is there other system registers to be set/checked?

Btw, I also tested different address for the above case, with the following result:

  • 0x3e60: ok
  • 0x3e61: Exception (PC=0x200)
  • 0x3e62: ditto
  • 0x3e63: ditto
  • 0x3e64: ok
  • 0x3e65: Exception (PC=0x200)
  • 0x3e66: ditto
  • 0x3e67: ditto
  • 0x3e68: ok

Solution

  • Alignment faults can be configured to fault or no-fault for accesses to Normal memory only by setting SCTLR_ELx.A bit. Unaligned access to "Device" memory cannot be configured and will always cause fault if address is unaligned. In MMU On configuration, Device or Normal memory type can be configured by programming appropriate bits in MAIR_ELx and translation system takes care of assigning these properties to memory. In case of MMU off, translation system assigns Device-nGnRnE attribute for data accesses and assigns Normal memory attribute for instruction access. In your case you are running in MMU off configuration, translation system assigns Device-nGnRnE attribute and so the fault. Refer VMSA (Chapter 5, section D5.2.9) in Arm Arm for more details.