Subversion Repositories HelenOS

Rev

Rev 2411 | Rev 2464 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2411 Rev 2413
Line 28... Line 28...
28
 
28
 
29
/** @addtogroup arm32
29
/** @addtogroup arm32
30
 * @{
30
 * @{
31
 */
31
 */
32
/** @file
32
/** @file
33
 *  @brief Userspace.
33
 *  @brief Userspace switch.
34
 */
34
 */
35
 
35
 
36
#include <userspace.h>
36
#include <userspace.h>
37
 
37
 
-
 
38
 
38
/** Struct to hold general purpose register values */
39
/** Struct for holding all general purpose registers.
-
 
40
 *  
-
 
41
 *  Used to set registers when going to userspace.
-
 
42
 */
39
typedef struct {
43
typedef struct {
40
    uint32_t r0;
44
    uint32_t r0;
41
    uint32_t r1;
45
    uint32_t r1;
42
    uint32_t r2;
46
    uint32_t r2;
43
    uint32_t r3;
47
    uint32_t r3;
Line 72... Line 76...
72
    ustate.r1 = ustate.r2  = ustate.r3  = ustate.r4  =
76
    ustate.r1 = ustate.r2  = ustate.r3  = ustate.r4  =
73
        ustate.r5 = ustate.r6  = ustate.r7  = ustate.r8  =
77
        ustate.r5 = ustate.r6  = ustate.r7  = ustate.r8  =
74
        ustate.r9 = ustate.r10 = ustate.r11 = ustate.r12 =
78
        ustate.r9 = ustate.r10 = ustate.r11 = ustate.r12 =
75
        ustate.lr = 0;
79
        ustate.lr = 0;
76
 
80
 
77
    //set user stack
81
    // set user stack
78
    ustate.sp = ((uint32_t)kernel_uarg->uspace_stack) +
82
    ustate.sp = ((uint32_t)kernel_uarg->uspace_stack) + PAGE_SIZE;
79
            PAGE_SIZE - sizeof(void*);
-
 
80
 
83
 
81
    //set where uspace execution starts
84
    // set where uspace execution starts
82
    ustate.pc = (uintptr_t) kernel_uarg->uspace_entry;
85
    ustate.pc = (uintptr_t) kernel_uarg->uspace_entry;
83
 
86
 
84
    //status register in user mode
87
    // status register in user mode
85
    ipl_t cpsr = current_status_reg_read();
-
 
86
    cpsr &= ~STATUS_REG_MODE_MASK | USER_MODE;
-
 
87
 
-
 
88
    ipl_t tmpsr = (cpsr & ~STATUS_REG_MODE_MASK) | SUPERVISOR_MODE;
88
    ipl_t user_mode = current_status_reg_read() & (~STATUS_REG_MODE_MASK | USER_MODE);
89
 
89
 
-
 
90
    // set user mode, set registers, jump
90
    asm __volatile__ (
91
    asm __volatile__ (
91
        // save pointer into ustate struct
-
 
92
        "mov r0, %0         \n"
92
        "mov r0, %0         \n"    
93
        // save cspr
-
 
94
        "mov r1, %1         \n"
-
 
95
        // change mode into any exception mode
-
 
96
        "msr cpsr_c, %2         \n"
-
 
97
        // set saved cpsr
-
 
98
        "msr spsr_c, r1 \n"
93
        "msr spsr_c, %1     \n"
99
 
-
 
100
        "mov sp, r0 \n"
-
 
101
        // replace almost all registers
-
 
102
        "ldmfd sp!, {r0-r12, sp, lr}^\n"
94
        "ldmfd r0!, {r0-r12, sp, lr}^  \n"
103
        //jump to the usermode
-
 
104
        "ldmfd sp!, {pc}^"
95
        "ldmfd r0!, {pc}^"
-
 
96
       
105
    : // no output
97
        :
106
    : "r"(&ustate), "r"(cpsr), "r"(tmpsr) //
98
        : "r"(&ustate), "r"(user_mode)
107
    : "r0","r1"
99
        : "r0", "r1"
108
    );
100
    );
109
 
101
 
110
    // unreachable
102
    // unreachable
111
    while(1) ;
103
    while(1) ;
112
}
104
}