ref: 57f8b3d1acf273a88568c49d0b83b6863485b9e0
dir: /sys/src/9/kw/lproc.s/
#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] */