Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2412 → Rev 2413

/branches/arm/kernel/arch/arm32/src/userspace.c
30,12 → 30,16
* @{
*/
/** @file
* @brief Userspace.
* @brief Userspace switch.
*/
 
#include <userspace.h>
 
/** Struct to hold general purpose register values */
 
/** Struct for holding all general purpose registers.
*
* Used to set registers when going to userspace.
*/
typedef struct {
uint32_t r0;
uint32_t r1;
74,37 → 78,25
ustate.r9 = ustate.r10 = ustate.r11 = ustate.r12 =
ustate.lr = 0;
 
//set user stack
ustate.sp = ((uint32_t)kernel_uarg->uspace_stack) +
PAGE_SIZE - sizeof(void*);
// set user stack
ustate.sp = ((uint32_t)kernel_uarg->uspace_stack) + PAGE_SIZE;
 
//set where uspace execution starts
// set where uspace execution starts
ustate.pc = (uintptr_t) kernel_uarg->uspace_entry;
 
//status register in user mode
ipl_t cpsr = current_status_reg_read();
cpsr &= ~STATUS_REG_MODE_MASK | USER_MODE;
// status register in user mode
ipl_t user_mode = current_status_reg_read() & (~STATUS_REG_MODE_MASK | USER_MODE);
 
ipl_t tmpsr = (cpsr & ~STATUS_REG_MODE_MASK) | SUPERVISOR_MODE;
 
// set user mode, set registers, jump
asm __volatile__ (
// save pointer into ustate struct
"mov r0, %0 \n"
// save cspr
"mov r1, %1 \n"
// change mode into any exception mode
"msr cpsr_c, %2 \n"
// set saved cpsr
"msr spsr_c, r1 \n"
 
"mov sp, r0 \n"
// replace almost all registers
"ldmfd sp!, {r0-r12, sp, lr}^\n"
//jump to the usermode
"ldmfd sp!, {pc}^"
: // no output
: "r"(&ustate), "r"(cpsr), "r"(tmpsr) //
: "r0","r1"
"mov r0, %0 \n"
"msr spsr_c, %1 \n"
"ldmfd r0!, {r0-r12, sp, lr}^ \n"
"ldmfd r0!, {pc}^"
:
: "r"(&ustate), "r"(user_mode)
: "r0", "r1"
);
 
// unreachable
/branches/arm/kernel/arch/arm32/src/start.S
37,9 → 37,10
 
kernel_image_start:
# switch to system mode
# switch to supervisor mode
mrs r3, cpsr
orr r3, r3, #0x1f
bic r3, r3, #0x1f
orr r3, r3, #0x13
msr cpsr_c, r3
ldr sp, =temp_stack