Exception switch from EL3 to non-secure EL1

The CPU succesfully switches to EL1h, non-secure. But the el1_entry is never called. I don't know why. If using secure el1, the el1_entry gets called. Compiled using clang -c boot.S -o boot.o, and linked with ld. Any help would be appreciated.

global _Entry

_Entry:

  mrs x0, scr_el3

  orr x0, x0, #(1 << 10)

  orr x0, x0, #(1 << 0)

  msr scr_el3, x0

  mov x0, #0b00101

  msr spsr_el3, x0

  adr x1, el1_entry

  msr elr_el3, x1

  eret

el1_entry:

  ldr x15, =0xdeadbeef

  b .

Parents
  • I can think of some possible answers it's worth checking:

    • Does the memory allow Non-secure accesses?

      • It looks like you have el1_entry in the same page as the EL3 code.  Unless you've set up the EL3 (and S_EL1) MMU to generate Non-secure accesses, the default will be to produce Secure accesses.  Depending on the memory system and the device, typically a memory would either Secure or Non-secure, but not both.  If it's something like the Arm FVP model, then you might have a switch to disable the memory system level checking of memory access security.  But be aware, strictly NS and S are different address spaces -  and allowing a given memory location to appear in both can lead to interesting cache coherency problems.
    • Have you initialised the _EL2 and _EL1 to safe values?
      • Most Arm system registers reset to an unknown value - which is safe because they don't effect execution immediately after reset.  Software is expected to initialise those registers before moving to lower ELs, where the registers do affect execution.
      • If the code works for moving to S_EL1, but not NS_EL1, then my starting point would be the EL2 registers (as the A55 doesn't have S_EL2).  But you should initialize the EL1 regs too.
Reply
  • I can think of some possible answers it's worth checking:

    • Does the memory allow Non-secure accesses?

      • It looks like you have el1_entry in the same page as the EL3 code.  Unless you've set up the EL3 (and S_EL1) MMU to generate Non-secure accesses, the default will be to produce Secure accesses.  Depending on the memory system and the device, typically a memory would either Secure or Non-secure, but not both.  If it's something like the Arm FVP model, then you might have a switch to disable the memory system level checking of memory access security.  But be aware, strictly NS and S are different address spaces -  and allowing a given memory location to appear in both can lead to interesting cache coherency problems.
    • Have you initialised the _EL2 and _EL1 to safe values?
      • Most Arm system registers reset to an unknown value - which is safe because they don't effect execution immediately after reset.  Software is expected to initialise those registers before moving to lower ELs, where the registers do affect execution.
      • If the code works for moving to S_EL1, but not NS_EL1, then my starting point would be the EL2 registers (as the A55 doesn't have S_EL2).  But you should initialize the EL1 regs too.
Children