Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#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] */