Rev 2413 | Rev 4018 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2413 | Rev 2464 | ||
---|---|---|---|
Line 33... | Line 33... | ||
33 | * @brief Userspace switch. |
33 | * @brief Userspace switch. |
34 | */ |
34 | */ |
35 | 35 | ||
36 | #include <userspace.h> |
36 | #include <userspace.h> |
37 | 37 | ||
38 | - | ||
39 | /** Struct for holding all general purpose registers. |
38 | /** Struct for holding all general purpose registers. |
40 | * |
39 | * |
41 | * Used to set registers when going to userspace. |
40 | * Used to set registers when going to userspace. |
42 | */ |
41 | */ |
43 | typedef struct { |
42 | typedef struct { |
Line 57... | Line 56... | ||
57 | uint32_t sp; |
56 | uint32_t sp; |
58 | uint32_t lr; |
57 | uint32_t lr; |
59 | uint32_t pc; |
58 | uint32_t pc; |
60 | } ustate_t; |
59 | } ustate_t; |
61 | 60 | ||
62 | - | ||
63 | /** Changes processor mode and jumps to the address specified in the first parameter. |
61 | /** Changes processor mode and jumps to the address specified in the first |
- | 62 | * parameter. |
|
64 | * |
63 | * |
65 | * @param kernel_uarg Userspace settings (entry point, stack, ...). |
64 | * @param kernel_uarg Userspace settings (entry point, stack, ...). |
66 | */ |
65 | */ |
67 | void userspace(uspace_arg_t *kernel_uarg) |
66 | void userspace(uspace_arg_t *kernel_uarg) |
68 | { |
67 | { |
69 | - | ||
70 | volatile ustate_t ustate; |
68 | volatile ustate_t ustate; |
71 | 69 | ||
72 | // set first parameter |
70 | /* set first parameter */ |
73 | ustate.r0 = (uintptr_t) kernel_uarg->uspace_uarg; |
71 | ustate.r0 = (uintptr_t) kernel_uarg->uspace_uarg; |
74 | 72 | ||
75 | // clear other registers |
73 | /* clear other registers */ |
76 | ustate.r1 = ustate.r2 = ustate.r3 = ustate.r4 = |
74 | ustate.r1 = ustate.r2 = ustate.r3 = ustate.r4 = ustate.r5 = |
77 | ustate.r5 = ustate.r6 = ustate.r7 = ustate.r8 = |
75 | ustate.r6 = ustate.r7 = ustate.r8 = ustate.r9 = ustate.r10 = |
78 | ustate.r9 = ustate.r10 = ustate.r11 = ustate.r12 = |
76 | ustate.r11 = ustate.r12 = ustate.lr = 0; |
79 | ustate.lr = 0; |
- | |
80 | 77 | ||
81 | // set user stack |
78 | /* set user stack */ |
82 | ustate.sp = ((uint32_t)kernel_uarg->uspace_stack) + PAGE_SIZE; |
79 | ustate.sp = ((uint32_t)kernel_uarg->uspace_stack) + PAGE_SIZE; |
83 | 80 | ||
84 | // set where uspace execution starts |
81 | /* set where uspace execution starts */ |
85 | ustate.pc = (uintptr_t) kernel_uarg->uspace_entry; |
82 | ustate.pc = (uintptr_t) kernel_uarg->uspace_entry; |
86 | 83 | ||
87 | // status register in user mode |
84 | /* status register in user mode */ |
88 | ipl_t user_mode = current_status_reg_read() & (~STATUS_REG_MODE_MASK | USER_MODE); |
85 | ipl_t user_mode = current_status_reg_read() & |
- | 86 | (~STATUS_REG_MODE_MASK | USER_MODE); |
|
89 | 87 | ||
90 | // set user mode, set registers, jump |
88 | /* set user mode, set registers, jump */ |
91 | asm __volatile__ ( |
89 | asm volatile ( |
92 | "mov r0, %0 \n" |
90 | "mov r0, %0 \n" |
93 | "msr spsr_c, %1 \n" |
91 | "msr spsr_c, %1 \n" |
94 | "ldmfd r0!, {r0-r12, sp, lr}^ \n" |
92 | "ldmfd r0!, {r0-r12, sp, lr}^ \n" |
95 | "ldmfd r0!, {pc}^" |
93 | "ldmfd r0!, {pc}^\n" |
96 | - | ||
97 | : |
94 | : |
98 | : "r"(&ustate), "r"(user_mode) |
95 | : "r" (&ustate), "r" (user_mode) |
99 | : "r0", "r1" |
96 | : "r0", "r1" |
100 | ); |
97 | ); |
101 | 98 | ||
102 | // unreachable |
99 | /* unreachable */ |
103 | while(1) ; |
100 | while(1) |
- | 101 | ; |
|
104 | } |
102 | } |
105 | 103 | ||
106 | - | ||
107 | /** @} |
104 | /** @} |
108 | */ |
105 | */ |