Hi,
I am working on bootloader porting to ARM v8 platform. I am facing a problem in enabling MMU in execution level-1 EL1.
I am not able to set sctlr_el1.M bit when ever i try to set this bit the instruction won't complete. I think it is raising an exception where as i have not enabled the interrupts to capture. apart form sctlr_el1.M
bit i am able to set all other bits like sctlr.C, sctlr_el1.I. Can some one please help regarding this issue? thanks in advance.
Hello,
I think it is raising an exception where as i have not enabled the interrupts to capture.
Keep in mind that you cannot mask synchronous exceptions, such as those caused by the MMU. The "DAIF" in DAIFSet and DAIFClr special registers only allow you to mask/unmask Debug, SError, IRQ, and FIQ exceptions.
I am not able to set sctlr_el1.M bit when ever i try to set this bit the instruction won't complete.
The most likely issue is that you have either misconfigured your translation regime (through the TCR_EL1 register), or you have misconfigured your translation tables, or a combination of both. You might be getting an Instruction Abort because the core fails to translate the virtual address of the next instruction, which would take you to your vector table, except the translation for that instruction may also fail, which would result in the core entering a recursive exception.
The simplest way to narrow down what is going wrong is to check the value of the ESR_EL1 register (Exception Syndrome Register EL1) in a debugger immediately after single-stepping the write to SCTLR_EL1.M.
Please can you try this and provide the value of ESR_EL1?
Ash.
Thank you Mr. Ash,
That was an TCR configuration fault because of wrong page size. Now i have enabled the interrupts to catch ESR value.
I have one more question! being in EL-1/2 is there any way to know the current state of the system (secure/nonsecure)?
No problem. Architecturally speaking I don't think there's a reliable mechanism for software running at EL1 to check whether it is in the secure or non-secure state. However, EL2 will always be non-secure. Generally speaking, software running at EL1 shouldn't need to know whether it's in the secure or non-secure state. Out of interest, what use case do you have for trying to check this?
Hi Ash,
Ya sure i am trying to enable the secondary code and run some code on it. this experiment i am doing it in boot-loader which is currently running in EL-3 mode. I had checked the linux implementation for this, they do it using a trusted firmware by just executing smc instruction with proper inputs, in my case i had to follow the same procedure because i don't have access to firmware code. when i call initialize_firmware function it does the initial settings and do a "eret" which takes the control to EL-2 mode. now i don't know if those initial settings put system into secure mode or non secure mode. this is why i wanted to know is there any way to check the current state of the system.
By your statement "However, EL2 will always be non-secure. " we can i assume the system is in non secure state since the "ERET" instruction from EL-3 is taking me to EL-2! where as in secure system it should directly take me to EL-1! is my understanding correct?
Harish
Hello Harish,
Ah, I understand now. I thought you were asking whether there is a way for EL1/EL2 to know whether it is in the Secure state, to which the answer is, architecturally, no. However, EL3 controls the security state through the SCR_EL3.NS bit (bit [0]).
From the ARM Architecture Reference Manual (ARM DDI 0487A.f) Section D7.2.80 "SCR_EL3, Secure Configuration Register":
NS, bit [0] Non-secure bit. 0 Indicates that EL0 and EL1 are in Secure state, and so memory accesses from those Exception levels can access Secure memory. 1 Indicates that EL0 and EL1 are in Non-secure state, and so memory accesses from those Exception levels cannot access Secure memory.
NS, bit [0]
Non-secure bit.
0 Indicates that EL0 and EL1 are in Secure state, and so memory accesses from those Exception levels can access Secure memory.
1 Indicates that EL0 and EL1 are in Non-secure state, and so memory accesses from those Exception levels cannot access Secure memory.
So setting the NS bit and performing an exception return to EL1 or EL0 from EL3 will drop you to Non-secure EL1/EL0, whereas having the NS bit cleared would drop you to Secure EL1/EL0.
Not quite. When performing the exception return from EL3, you will configure the SPSR_EL3.M[3:0] field from the following table:
If you were to set SPSR_EL3.M[3:0] to either of the EL2 modes (0b1000 or 0b1001) and perform an exception return with the SCR_EL3.NS bit cleared, i.e. you attempt to perform an exception return to Secure EL2, this is treated as an illegal exception return, so you will actually stay at EL3 and the PSTATE.IL bit will be set, causing the next instruction to be illegal and cause a synchronous exception, taking you to your EL3 vector table.
More information on this can be found in the ARM Architecture Reference Manual (ARM DDI 0487A.f) Section D1.11.2 "Illegal return events from AArch64 state". As listed there under the situations that cause an illegal exception return:
A return to EL2 when EL3 is implemented and the value of the SCR_EL3.NS bit is 0.
I hope that helps,
Hi ,
I have the same problem to you in enabling MMU in execution EL3. However, I can't capture the exception. DAIF is clear, so exception is not masked. Other exception can be captured OK, so my exception code is OK.
Can you help regarding this issue? thanks in advance.