47 lines
1.3 KiB
ArmAsm
47 lines
1.3 KiB
ArmAsm
#include "mem.h"
|
|
#include "arm.h"
|
|
|
|
/*
|
|
* This is the first jump from kernel to user mode.
|
|
* Fake a return from interrupt.
|
|
*
|
|
* Enter with R0 containing the user stack pointer.
|
|
* UTZERO + 0x20 is always the entry point.
|
|
*
|
|
*/
|
|
TEXT touser(SB), 1, $-4
|
|
/* store the user stack pointer into the USR_r13 */
|
|
MOVM.DB.W [R0], (R13)
|
|
/* avoid the ambiguity described in notes/movm.w. */
|
|
// MOVM.S.IA.W (R13), [R13]
|
|
MOVM.S (R13), [R13]
|
|
ADD $4, R13
|
|
|
|
/* set up a PSR for user level */
|
|
MOVW $(PsrMusr), R0
|
|
MOVW R0, SPSR
|
|
|
|
/* save the PC on the stack */
|
|
MOVW $(UTZERO+0x20), R0
|
|
MOVM.DB.W [R0], (R13)
|
|
|
|
/*
|
|
* note that 5a's RFE is not the v6 arch. instruction (0xe89d0a00,
|
|
* I think), which loads CPSR from the word after the PC at (R13),
|
|
* but rather the pre-v6 simulation `MOVM.IA.S.W (R13), [R15]'
|
|
* (0xe8fd8000 since MOVM is LDM in this case), which loads CPSR
|
|
* not from memory but from SPSR due to `.S'.
|
|
*/
|
|
RFE
|
|
|
|
/*
|
|
* here to jump to a newly forked process
|
|
*/
|
|
TEXT forkret(SB), 1, $-4
|
|
ADD $(4*15), R13 /* make r13 point to ureg->type */
|
|
MOVW 8(R13), R14 /* restore link */
|
|
MOVW 4(R13), R0 /* restore SPSR */
|
|
MOVW R0, SPSR /* ... */
|
|
MOVM.DB.S (R13), [R0-R14] /* restore registers */
|
|
ADD $8, R13 /* pop past ureg->{type+psr} */
|
|
RFE /* MOVM.IA.S.W (R13), [R15] */
|