/kernel/trunk/generic/include/proc/uarg.h |
---|
0,0 → 1,43 |
/* |
* Copyright (C) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef __UARG_H__ |
#define __UARG_H__ |
/** Structure passed to uinit kernel thread as argument. */ |
typedef struct uspace_arg { |
void *uspace_entry; |
void *uspace_stack; |
void (* uspace_thread_function)(); |
void *uspace_thread_arg; |
struct uspace_arg *uspace_uarg; |
} uspace_arg_t; |
#endif |
/kernel/trunk/generic/include/proc/thread.h |
---|
40,6 → 40,7 |
#include <config.h> |
#include <adt/list.h> |
#include <mm/slab.h> |
#include <proc/uarg.h> |
#define THREAD_STACK_SIZE STACK_SIZE |
117,12 → 118,6 |
__u8 *kstack; /**< Thread's kernel stack. */ |
}; |
/** Structure passed to uinit kernel thread as argument. */ |
typedef struct uspace_arg { |
__address uspace_entry; |
__address uspace_stack; |
} uspace_arg_t; |
/** Thread list lock. |
* |
* This lock protects all link_t structures chained in threads_head. |
149,7 → 144,7 |
extern slab_cache_t *fpu_context_slab; |
/** Thread syscall prototypes. */ |
__native sys_thread_create(__address function, void *arg, void *stack, char *name); |
__native sys_thread_exit(int status); |
__native sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name); |
__native sys_thread_exit(int uspace_status); |
#endif |
/kernel/trunk/generic/src/proc/task.c |
---|
29,9 → 29,9 |
#include <main/uinit.h> |
#include <proc/thread.h> |
#include <proc/task.h> |
#include <proc/uarg.h> |
#include <mm/as.h> |
#include <mm/slab.h> |
#include <synch/spinlock.h> |
#include <arch.h> |
#include <panic.h> |
39,7 → 39,6 |
#include <ipc/ipc.h> |
#include <memstr.h> |
#include <print.h> |
#include <elf.h> |
SPINLOCK_INITIALIZE(tasks_lock); |
115,7 → 114,7 |
int rc; |
thread_t *t; |
task_t *task; |
uspace_arg_t *uarg; |
uspace_arg_t *kernel_uarg; |
as = as_create(0); |
125,12 → 124,15 |
return NULL; |
} |
uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0); |
uarg->uspace_entry = (__address) ((elf_header_t *) program_addr)->e_entry; |
uarg->uspace_stack = USTACK_ADDRESS; |
kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0); |
kernel_uarg->uspace_entry = (void *) ((elf_header_t *) program_addr)->e_entry; |
kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS; |
kernel_uarg->uspace_thread_function = NULL; |
kernel_uarg->uspace_thread_arg = NULL; |
kernel_uarg->uspace_uarg = NULL; |
task = task_create(as, name); |
t = thread_create(uinit, uarg, task, 0, "uinit"); |
t = thread_create(uinit, kernel_uarg, task, 0, "uinit"); |
/* |
* Create the data as_area. |
/kernel/trunk/generic/src/proc/thread.c |
---|
29,6 → 29,7 |
#include <proc/scheduler.h> |
#include <proc/thread.h> |
#include <proc/task.h> |
#include <proc/uarg.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <arch/asm.h> |
429,25 → 430,24 |
/** Process syscall to create new thread. |
* |
*/ |
__native sys_thread_create(__address function, void *arg, void *stack, char *name) |
__native sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name) |
{ |
thread_t *t; |
char namebuf[THREAD_NAME_BUFLEN]; |
uspace_arg_t *uarg; |
uspace_arg_t *kernel_uarg; /* TODO: store kernel_uarg in thread_t */ |
__u32 tid; |
copy_from_uspace(namebuf, name, THREAD_NAME_BUFLEN); |
uarg = (uspace_arg_t *) malloc(sizeof(uarg), 0); |
uarg->uspace_entry = function; |
uarg->uspace_stack = (__address) stack; |
copy_from_uspace(namebuf, uspace_name, THREAD_NAME_BUFLEN); |
if ((t = thread_create(uinit, uarg, TASK, 0, namebuf))) { |
kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0); |
copy_from_uspace(kernel_uarg, uspace_uarg, sizeof(uspace_arg_t)); |
if ((t = thread_create(uinit, kernel_uarg, TASK, 0, namebuf))) { |
tid = t->tid; |
thread_ready(t); |
return (__native) tid; |
} else { |
free(namebuf); |
free(kernel_uarg); |
} |
return (__native) -1; |
456,7 → 456,7 |
/** Process syscall to terminate thread. |
* |
*/ |
__native sys_thread_exit(int status) |
__native sys_thread_exit(int uspace_status) |
{ |
thread_exit(); |
/* Unreachable */ |
/kernel/trunk/generic/src/main/uinit.c |
---|
43,6 → 43,9 |
uarg.uspace_entry = ((uspace_arg_t *) arg)->uspace_entry; |
uarg.uspace_stack = ((uspace_arg_t *) arg)->uspace_stack; |
uarg.uspace_uarg = ((uspace_arg_t *) arg)->uspace_uarg; |
uarg.uspace_thread_function = NULL; |
uarg.uspace_thread_arg = NULL; |
free((uspace_arg_t *) arg); |
/kernel/trunk/arch/ia64/include/faddr.h |
---|
31,8 → 31,6 |
#include <arch/types.h> |
static __address FADDR(void (* fptr)(void)); |
/** |
* |
* Calculate absolute address of function |
41,18 → 39,9 |
* @param fptr Function pointer. |
* |
*/ |
inline __address FADDR(void (* fptr)(void)) { |
static inline __address FADDR(void (* fptr)()) { |
__address faddr; |
/*Deprecated assembler version*/ |
/* |
__asm__( |
"ld8 %0 = [%1]\n\t" |
: "=r" (faddr) |
: "r" (fptr) |
); |
*/ |
faddr = *((__address *)(fptr));; |
return faddr; |
} |
/kernel/trunk/arch/ia64/include/asm.h |
---|
258,6 → 258,6 |
extern void cpu_sleep(void); |
extern void asm_delay_loop(__u32 t); |
extern void switch_to_userspace(__address entry, __address sp, __address bsp, __u64 ipsr, __u64 rsc); |
extern void switch_to_userspace(__address entry, __address sp, __address bsp, __address uspace_uarg, __u64 ipsr, __u64 rsc); |
#endif |
/kernel/trunk/arch/ia64/src/asm.S |
---|
54,17 → 54,18 |
* @param in0 Userspace entry point address. |
* @param in1 Userspace stack pointer address. |
* @param in2 Userspace register stack pointer address. |
* @param in3 Value to be stored in IPSR. |
* @param in4 Value to be stored in RSC. |
* @param in3 Userspace address of thread uspace_arg_t structure. |
* @param in4 Value to be stored in IPSR. |
* @param in5 Value to be stored in RSC. |
*/ |
.global switch_to_userspace |
switch_to_userspace: |
alloc loc0 = ar.pfs, 5, 3, 0, 0 |
alloc loc0 = ar.pfs, 6, 3, 0, 0 |
rsm (PSR_IC_MASK | PSR_I_MASK) /* disable interruption collection and interrupts */ |
srlz.d ;; |
srlz.i ;; |
mov cr.ipsr = in3 |
mov cr.ipsr = in4 |
mov cr.iip = in0 |
mov r12 = in1 |
84,6 → 85,8 |
flushrs ;; |
mov ar.bspstore = in2 ;; |
mov ar.rsc = in4 ;; |
mov ar.rsc = in5 ;; |
mov r8 = in3 |
rfi ;; |
/kernel/trunk/arch/ia64/src/ia64.c |
---|
41,7 → 41,7 |
#include <config.h> |
#include <userspace.h> |
#include <console/console.h> |
#include <proc/thread.h> |
#include <proc/uarg.h> |
void arch_pre_mm_init(void) |
{ |
73,7 → 73,7 |
} |
/** Enter userspace and never return. */ |
void userspace(uspace_arg_t *uarg) |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
psr_t psr; |
rsc_t rsc; |
91,7 → 91,11 |
rsc.pl = PL_USER; |
rsc.mode = 3; /* eager mode */ |
switch_to_userspace(uarg->uspace_entry, uarg->uspace_stack+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT), uarg->uspace_stack, psr.value, rsc.value); |
switch_to_userspace((__address) kernel_uarg->uspace_entry, |
((__address) kernel_uarg->uspace_stack)+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT), |
(__address) kernel_uarg->uspace_stack, |
(__address) kernel_uarg->uspace_uarg, |
psr.value, rsc.value); |
while (1) { |
; |
/kernel/trunk/arch/amd64/src/userspace.c |
---|
30,7 → 30,7 |
#include <arch/pm.h> |
#include <arch/types.h> |
#include <arch.h> |
#include <proc/thread.h> |
#include <proc/uarg.h> |
#include <mm/as.h> |
39,7 → 39,7 |
* Change CPU protection level to 3, enter userspace. |
* |
*/ |
void userspace(uspace_arg_t *uarg) |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
ipl_t ipl; |
51,14 → 51,19 |
"pushq %2\n" |
"pushq %3\n" |
"pushq %4\n" |
"movq %5, %%rax\n" |
"iretq\n" |
: : |
"i" (gdtselector(UDATA_DES) | PL_USER), |
"r" (uarg->uspace_stack+THREAD_STACK_SIZE), |
"r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE), |
"r" (ipl), |
"i" (gdtselector(UTEXT_DES) | PL_USER), |
"r" (uarg->uspace_entry)); |
"r" (kernel_uarg->uspace_entry), |
"r" (kernel_uarg->uspace_uarg) |
: "rax" |
); |
/* Unreachable */ |
for(;;); |
for(;;) |
; |
} |
/kernel/trunk/arch/mips32/include/asm.h |
---|
57,6 → 57,6 |
extern void cpu_halt(void); |
extern void asm_delay_loop(__u32 t); |
extern void userspace_asm(__address ustack); |
extern void userspace_asm(__address ustack, __address uspace_uarg); |
#endif |
/kernel/trunk/arch/mips32/src/mips32.c |
---|
37,6 → 37,7 |
#include <arch/console.h> |
#include <memstr.h> |
#include <proc/thread.h> |
#include <proc/uarg.h> |
#include <print.h> |
#include <arch/interrupt.h> |
120,14 → 121,14 |
*/ |
__address supervisor_sp __attribute__ ((section (".text"))); |
void userspace(uspace_arg_t *uarg) |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
/* EXL=1, UM=1, IE=1 */ |
cp0_status_write(cp0_status_read() | (cp0_status_exl_exception_bit | |
cp0_status_um_bit | |
cp0_status_ie_enabled_bit)); |
cp0_epc_write(uarg->uspace_entry); |
userspace_asm(uarg->uspace_stack+PAGE_SIZE); |
cp0_epc_write((__address) kernel_uarg->uspace_entry); |
userspace_asm(((__address) kernel_uarg->uspace_stack+PAGE_SIZE), (__address) kernel_uarg->uspace_uarg); |
while (1) |
; |
} |
/kernel/trunk/arch/mips32/src/start.S |
---|
226,6 → 226,7 |
userspace_asm: |
add $sp, $a0, 0 |
add $v0, $a1, 0 |
eret |
nop |
/kernel/trunk/arch/ia32/src/userspace.c |
---|
30,7 → 30,7 |
#include <arch/pm.h> |
#include <arch/types.h> |
#include <arch.h> |
#include <proc/thread.h> |
#include <proc/uarg.h> |
#include <mm/as.h> |
39,7 → 39,7 |
* Change CPU protection level to 3, enter userspace. |
* |
*/ |
void userspace(uspace_arg_t *uarg) |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
ipl_t ipl; |
46,10 → 46,12 |
ipl = interrupts_disable(); |
__asm__ volatile ( |
/* CLNT */ |
/* |
* Clear nested task flag. |
*/ |
"pushfl\n" |
"pop %%eax\n" |
"and $0xffffbfff,%%eax\n" |
"and $0xffffbfff, %%eax\n" |
"push %%eax\n" |
"popfl\n" |
58,10 → 60,12 |
"pushl %2\n" |
"pushl %3\n" |
"pushl %4\n" |
"movl %5, %%eax\n" |
"iret" |
: |
: "i" (selector(UDATA_DES) | PL_USER), "r" (uarg->uspace_stack+THREAD_STACK_SIZE), |
"r" (ipl), "i" (selector(UTEXT_DES) | PL_USER), "r" (uarg->uspace_entry) |
: "i" (selector(UDATA_DES) | PL_USER), "r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE), |
"r" (ipl), "i" (selector(UTEXT_DES) | PL_USER), "r" (kernel_uarg->uspace_entry), |
"r" (kernel_uarg->uspace_uarg) |
: "eax"); |
/* Unreachable */ |