Hello,
I'm working on Raspberry PI2, ARMv7 and now specifically trying the secure modes.
I managed to get the PI start in secure state, then here I can set the SP for all the modes I intend to use in secure state, like IRQ, SVC, etc.
But I also would like to set the SP of these modes in NON secure state (I understand secure and non secure mode have their respective separate SP).
Currently, I trigger a Monitor call to set the NS bit (I will leave the secure state) then I try setting the SP with:
@ Prepare NS modes usage : set NS bit
mrc p15, 0, r4, c1, c1, 0 @ R4 = SCR
orr r4, r4, #0x0001 @ Set NS
mcr p15, 0, r4, c1, c1, 0 @ write SCR (with NS bit set)
isb
@ Set IRQ Mode non secure SP
mov r0, #(CPSR_MODE_IRQ+CPSR_IRQ_INHIBIT+CPSR_FIQ_INHIBIT)
msr cpsr_c, r0 @ UNDEF EXCEPTION TRIGGERRED HERE !!!!
ldr sp, =__nsIRQ_stack_core0
However, this does not work properly: the MSR triggers here an undef exception. Strangely, when I later read sp_irq, it seems it took the desired value.Also, when latter I return in secure state, the secure SP (eg IRQ one here) seems to be lost: value of sp_irq is the one set above.
Do you know the reason of this undef ?
Thanks for any hints here, I'm very confused with the stacks settings/usage between secure and non secure mode.
Alexandre
The manual says that "The ARM core registers and the processor status registers are not Banked between the Secure and the Non-secure states. ARM expects that, when switching execution between the Non-secure and Secure states, a kernel running mostly in Monitor mode will switch the values of these registers."
sp_mon is a banked register available in the monitor /mode/ (which always runs in the secure /state/), but a register such as sp_irq is not banked between secure and non-secure states of the irq mode.
Also from the manual is the recommendation: "The usual mechanism for changing from Secure to Non-secure state is an exception return.To return to Non-secure state, software executing in Monitor mode sets SCR.NS to 1 and then performs the exception return."
Thanks a lot for this extract... I read it but did not realize SP was a core register :/This makes sense for many of my concerns and fixes some erroneous ideas I had...
I still wonder however why that MSR triggers an Undef. It should not be SP related here... and surprisingly the SP is properly modified for the IRQ mode. Seems the Undef (which I recover in the Undef handler) does not prevent the CPSR update... Something still unclear here.
The MSR does touch the CPSR.I and CPSR.F, the access to which is controlled be SCR and HCR registers. Does the exception still occur if we read cpsr_c, modify only the mode biyd and write cprs_c back?
I removed this from my code, but tried it anyway...It seems better when just playing with the mode 5 bits and the CPSR_C can be set without exception.However my test code got stuck quickly after, I think for some other reasons (not ready yet). I will keep trying and you're right, I think setting the bit F caused the exception. But I want to experiment/check it further. I'll come back soon here.
Thanks for your highlights till now :)