Why am I getting garbage in my CPSR when I switch to custom mode?
When loading the toy kernel, I use this code to switch to user mode:
mrs r1, CPSR @ Switch to System mode
orr r1, r1, #0xc
msr CPSR, r1
ldr sp, =gUsrStackBase @ Setup USR stack (shared with System mode)
mov r1, #0x10 @ Get user-mode CPSR into SPSR
msr SPSR, r1
movs pc, r0 @ Switch to USR mode and branch
But after the command, movs
instead of the user mode CPSR value, I set (0x10) random garbage in CPSR. Why might this be?
source to share
I banged my head about this question a long, long time ago [1]! Finally I found the cause of the problem. In the ARM Architecture Reference Manual (ARMv7A-R updated only!) [2]:
MSR (register) executed in system mode is NOT POSSIBLE if it tries to update the SPSR.
(This is also true for MSR
with immediate).
The solution is to switch to supervisor (or other privileged) mode before configuring SPSR.
[1] very
[2] Here you can get ARMv7-ARM (you will need to register): http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406c/index.html
source to share