Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1077 → Rev 1078

/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 */