Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2463 → Rev 2464

/branches/arm/kernel/arch/arm32/src/userspace.c
35,7 → 35,6
 
#include <userspace.h>
 
 
/** Struct for holding all general purpose registers.
*
* Used to set registers when going to userspace.
59,50 → 58,48
uint32_t pc;
} ustate_t;
 
 
/** Changes processor mode and jumps to the address specified in the first parameter.
/** Changes processor mode and jumps to the address specified in the first
* parameter.
*
* @param kernel_uarg Userspace settings (entry point, stack, ...).
*/
void userspace(uspace_arg_t *kernel_uarg)
{
 
volatile ustate_t ustate;
 
// set first parameter
/* set first parameter */
ustate.r0 = (uintptr_t) kernel_uarg->uspace_uarg;
 
// clear other registers
ustate.r1 = ustate.r2 = ustate.r3 = ustate.r4 =
ustate.r5 = ustate.r6 = ustate.r7 = ustate.r8 =
ustate.r9 = ustate.r10 = ustate.r11 = ustate.r12 =
ustate.lr = 0;
/* clear other registers */
ustate.r1 = ustate.r2 = ustate.r3 = ustate.r4 = ustate.r5 =
ustate.r6 = ustate.r7 = ustate.r8 = ustate.r9 = ustate.r10 =
ustate.r11 = ustate.r12 = ustate.lr = 0;
 
// set user stack
/* 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 user_mode = current_status_reg_read() & (~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);
 
// set user mode, set registers, jump
asm __volatile__ (
"mov r0, %0 \n"
"msr spsr_c, %1 \n"
"ldmfd r0!, {r0-r12, sp, lr}^ \n"
"ldmfd r0!, {pc}^"
/* set user mode, set registers, jump */
asm volatile (
"mov r0, %0 \n"
"msr spsr_c, %1 \n"
"ldmfd r0!, {r0-r12, sp, lr}^ \n"
"ldmfd r0!, {pc}^\n"
:
: "r"(&ustate), "r"(user_mode)
: "r" (&ustate), "r" (user_mode)
: "r0", "r1"
);
 
// unreachable
while(1) ;
/* unreachable */
while(1)
;
}
 
 
/** @}
*/