1

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
bruin
  • 979
  • 1
  • 10
  • 30
  • since `mov x1, xzr` means zero offset from address in `x4`, `ldr w0, [x4, x1, lsl #0x2]` is same as `ldr w0, [x4]`. Would `ldr w0, [x4]` reading give same error ? – user3124812 Sep 01 '21 at 10:12
  • and since you mentioned FPGA, how is `0x3e60` address mapped ? If that's FPGA `device memory` than un-aligned reading crash is expected behavior. But it's not problem of `ldr` instruction, but MMU mapping – user3124812 Sep 01 '21 at 10:15
  • The memory map at reset is that the 1st 64KiB is SRAM (i.e., not device memory). As for status of `ldr wo, [x4]`, I will test the behavior tomorrow. In the actual code (which causes exception), `x1` is not zero (it was `0x14`), I changed it to zero in the test code in the post, just for simplicity. – bruin Sep 01 '21 at 15:36
  • @user3124812 As just tested, `ldr w0, [x4]` has the same result as `ldr w0, [x4, x1, lsl #0x2]` where `x1` is 0. – bruin Sep 02 '21 at 01:11
  • 1
    Is the memory address being loaded marked as Device memory? If yes then irrespective of SCTLR_EL3.A bit value, there will be unaligned fault. If its not device memory then following can be checked. On reset SCTLR_EL3.A bit is set to unknown value. Can you explicitly set the SCTLR_EL3.A bit to zero, then add barrier "ISB" and check if you still see the alignment fault? – Shivakumar Sep 03 '21 at 17:57
  • @Shivakumar Thanks for your reply. The memory is not device memory but SRAM. How to check if it's "mared" as Device memory? For explicit setting SCTLR_EL3.A, I will make a test and report back the result. Thanks again. – bruin Sep 03 '21 at 22:37

1 Answers1

2

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.

Shivakumar
  • 427
  • 2
  • 15