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
  • So secure accesses are allowed, the whole ram region is not MMU mapped and no protection rules are set. I think the secure access is denied if the MMU is enabled for the current exception level.

    That's not quite right. The Cortex-A55 supports two Physical Address Spaces (PAS); Secure and Non-secure.  All accesses by the core will resolve to a physical address in one of those two PASs.  In Non-secure state, the output PAS is always Non-secure (doesn't matter if the MMU is on or off).  In Secure state, when the MMU is disabled the output PAS is Secure, when the MMU is enabled the output PAS is set via the translation tables.

    On real hardware, it's important that the output PAS from the core matches whatever the thing in the memory is.  Typically you'd get a bus level fault if you tried to access a memory with the wrong PAS (as strictly, you asked for an address that doesn't exist).

    EL2 is disabled by default on qemu unless i specify virtualization flag.

    I'm not familiar with qemu... when you say it's disabled - what does that mean?

    On HW, the EL2 registers would still be there.  Qemu might have set them to a known value, but they might not be the ones you want.  For example, HCR_EL2.RW controls whether NS_EL1 uses AArch32 or AArch64.  You'd need to make sure that matches what you're putting into SPSR_EL3 before doing the ERET into EL1.

    Maybe i should check the ESR_EL1?

    The ESR is a good thing to check.  But also look at which EL you're in.  As in, did the ERET itself fail (illegal exception return), meaning you are still in EL3 and need to check ESR_EL3.  Or, did the ERET succeed, and something went wrong in EL1. 

Reply
  • So secure accesses are allowed, the whole ram region is not MMU mapped and no protection rules are set. I think the secure access is denied if the MMU is enabled for the current exception level.

    That's not quite right. The Cortex-A55 supports two Physical Address Spaces (PAS); Secure and Non-secure.  All accesses by the core will resolve to a physical address in one of those two PASs.  In Non-secure state, the output PAS is always Non-secure (doesn't matter if the MMU is on or off).  In Secure state, when the MMU is disabled the output PAS is Secure, when the MMU is enabled the output PAS is set via the translation tables.

    On real hardware, it's important that the output PAS from the core matches whatever the thing in the memory is.  Typically you'd get a bus level fault if you tried to access a memory with the wrong PAS (as strictly, you asked for an address that doesn't exist).

    EL2 is disabled by default on qemu unless i specify virtualization flag.

    I'm not familiar with qemu... when you say it's disabled - what does that mean?

    On HW, the EL2 registers would still be there.  Qemu might have set them to a known value, but they might not be the ones you want.  For example, HCR_EL2.RW controls whether NS_EL1 uses AArch32 or AArch64.  You'd need to make sure that matches what you're putting into SPSR_EL3 before doing the ERET into EL1.

    Maybe i should check the ESR_EL1?

    The ESR is a good thing to check.  But also look at which EL you're in.  As in, did the ERET itself fail (illegal exception return), meaning you are still in EL3 and need to check ESR_EL3.  Or, did the ERET succeed, and something went wrong in EL1. 

Children