1#include "mem.h" 2#include "arm.h" 3 4/* 5 * This is the first jump from kernel to user mode. 6 * Fake a return from interrupt. 7 * 8 * Enter with R0 containing the user stack pointer. 9 * UTZERO + 0x20 is always the entry point. 10 * 11 */ 12TEXT touser(SB), 1, $-4 13 /* store the user stack pointer into the USR_r13 */ 14 MOVM.DB.W [R0], (R13) 15 /* avoid the ambiguity described in notes/movm.w. */ 16// MOVM.S.IA.W (R13), [R13] 17 MOVM.S (R13), [R13] 18 ADD $4, R13 19 20 /* set up a PSR for user level */ 21 MOVW $(PsrMusr), R0 22 MOVW R0, SPSR 23 24 /* save the PC on the stack */ 25 MOVW $(UTZERO+0x20), R0 26 MOVM.DB.W [R0], (R13) 27 28 /* 29 * note that 5a's RFE is not the v6 arch. instruction (0xe89d0a00, 30 * I think), which loads CPSR from the word after the PC at (R13), 31 * but rather the pre-v6 simulation `MOVM.IA.S.W (R13), [R15]' 32 * (0xe8fd8000 since MOVM is LDM in this case), which loads CPSR 33 * not from memory but from SPSR due to `.S'. 34 */ 35 RFE 36 37/* 38 * here to jump to a newly forked process 39 */ 40TEXT forkret(SB), 1, $-4 41 ADD $(4*15), R13 /* make r13 point to ureg->type */ 42 MOVW 8(R13), R14 /* restore link */ 43 MOVW 4(R13), R0 /* restore SPSR */ 44 MOVW R0, SPSR /* ... */ 45 MOVM.DB.S (R13), [R0-R14] /* restore registers */ 46 ADD $8, R13 /* pop past ureg->{type+psr} */ 47 RFE /* MOVM.IA.S.W (R13), [R15] */ 48