This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Why does it fail to switch from EL3 to SVC mode ?

(1) I intrrrupt the cpu in UEFI (EL2) by press enter key when the serial outputs the following message.

NOTICE:  Booting Trusted Firmware

NOTICE:  BL1: v1.0(release):14b6608

NOTICE:  BL1: Built : 14:15:51, Sep  1 2014

NOTICE:  BL1: Booting BL2

NOTICE:  BL2: v1.0(release):14b6608

NOTICE:  BL2: Built : 14:15:51, Sep  1 2014

NOTICE:  BL1: Booting BL3-1

NOTICE:  BL3-1: v1.0(release):14b6608

NOTICE:  BL3-1: Built : 14:15:53, Sep  1 2014

UEFI firmware (version v2.1 built at 14:41:56 on Oct 23 2014)

The default boot selection will start in   9 seconds

[1] Linux from NOR Flash

[2] Shell

[3] Boot Manager

(2)I follow the tutorial(Running Bare-Metal code at EL3 on the Juno board) to switch to EL3.

  1. Interrupt the CPU in UEFI (EL2)
  2. Disable the MMU at EL2
  3. Load a stub image containing a single SMC instruction
  4. Single-step the SMC instruction to enter EL3
  5. Disable the MMU at EL3
  6. Reprogram the TZPC to allow Secure world access to Normal world memory regions, such as DDR
  7. //////Load the bare-metal image to be run at EL3

(3)I modified the example project "startup_ARMv8_AArch64_with_AArch32_app" which is located in the example folder of DS5 installation folder.

        It's aimed not to initial the GIC. I download the file "AArch64_startup.axf" at EL3.


(4)I set the PC to the entry point and set a breakpoint to the following "eret" instruction. I step the eret instuction when it runs to the breakpoint.

        PC register changed to the value of "__main", but the CPSR is still EL3h. It failed to switch to SVC mode.

 

   PS:I also run the program in the VE_AEMv8x4 Brae-Metal simulation envirionment and it successed to switch to SVC mode.


drop_primary_to_el1:

    ldr x1, lit___main

    msr ELR_EL3, x1

    mov x1, #(AArch32_Mode_SVC | \

              AARCH64_SPSR_F   | \

              AARCH64_SPSR_I   | \

              AARCH64_SPSR_A)

    msr SPSR_EL3, x1

    eret

      

The problem is why it failed to switch from EL3 to SVC mode.

  • Based on your description, it sounds like you've hit an illegal exception return.  Mostly likely explanation is that the SCR_EL3/HCR_EL2 settings conflict with your SPSR value.

    The RW bits in SCR_EL3 and HCR_EL2 control the execution state (AArch32 or AArch64) of lower ELs.  If the SPSR value doesn't match the configured execution state, you get an illegal exception return.

  • Hi Martin:

    1. Will illegal exception result in branching to vector table entry pointed by the VBAR ? The PC register changed to the value of __main rather than the vector table.

         It seems that there isn't any illegal exception.

    2.The following suggestion is from support <support@arm.com>.

    Please can you confirm the following at the point that the ERET is executed:

    1) SCR_EL3.RW is set to 1

    2) HCR_EL2.RW is cleared to 0

    3) SCTLR_EL2 is cleared to 0

    4) SCTLR_EL1 is cleared to 0

    3.I modified the code following the suggestion.

    start64:                                 //entry point

        MRS  X0, SCR_EL3

        ORR  X0, X0, #(1 << 10)    // Set SCR_EL3.RW

        MSR  SCR_EL3, X0

        MRS  X1, HCR_EL2

        AND  X1, X1, #~(1 << 31)   // Clear HCR_EL2.RW

        MSR  HCR_EL2, X1

        MSR  SCTLR_EL2, XZR

        MSR  SCTLR_EL1, XZR

        ISB

        //read the system control registers

        mrs x1, SCR_EL3

        mrs x2, HCR_EL2

        mrs x3, SCTLR_EL2

        mrs x4, SCTLR_EL1

    drop_primary_to_el1_:

        ldr x1, lit___main

        msr ELR_EL3, x1

        mov x1, #(AArch32_Mode_SVC | \

                  AARCH64_SPSR_F   | \

                  AARCH64_SPSR_I   | \

                  AARCH64_SPSR_A)

        msr SPSR_EL3, x1

        eret

    4.It also failed to switch from EL3 to SVC mode. The result is the same as last time.

  • Hello,

    Please can you confirm the value defined for the 'AArch32_Mode_SVC' constant? It should be 0b10011. Note that this is a 5-bit constant, *NOT* a 4-bit constant.

    It's possible that 'AArch32_Mode_SVC' has only been defined as 0b0011, which does correspond to AArch32 Supervisor mode, but that will fail to set bit M[4] of SPSR_EL3, which is required when performing an exception return to AArch32 state.

    Ash.

  • __mike wrote:

    Hi Martin:

    1. Will illegal exception result in branching to vector table entry pointed by the VBAR ? The PC register changed to the value of __main rather than the vector table.

         It seems that there isn't any illegal exception.

    Eventually, yes, it will take you the vector table.

    When you perform an illegal exception return, the PC gets set to the ELR_ELn value but with PSTATE.IL=1.  Meaning that it then triggers an exception, taking you to the vector table.  This is why the ELR_ELn from this exception points at the destination of the illegal exception return and not the ERET.

    So, you can still see the PC going to the destination - but if you checked the current EL/execution state it will still be the EL/execution state from before the ERET.

  • 1.Yes,you are right! I chech the PSTATE.IL and it becomes 1'b1 after the eret is executed. I set the PC againt to the entry point. The PC will go to the vector table after one step.

    2.I check these registers again and find that HCR_EL2.TGE,bit[27] is 1'b1. The V8 architecture document shows that an exception return to EL1 is treated as an illegal exception return if

       this bit is set.

    3.I clear HCR_EL2.TGE before eret and it succeeded to switch from EL3 to SVC mode.