/kernel/trunk/generic/include/proc/thread.h |
---|
43,8 → 43,6 |
#define THREAD_STACK_SIZE STACK_SIZE |
#define THREAD_USER_STACK 1 |
enum state { |
Invalid, /**< It is an error, if thread is found in this state. */ |
Running, /**< State of a thread that is currently executing on some CPU. */ |
59,10 → 57,10 |
#define X_WIRED (1<<0) |
#define X_STOLEN (1<<1) |
#define THREAD_NAME_BUFLEN 20 |
/** Thread structure. There is one per thread. */ |
struct thread { |
char *name; |
link_t rq_link; /**< Run queue link. */ |
link_t wq_link; /**< Wait queue link. */ |
link_t th_link; /**< Links to threads within containing task. */ |
76,6 → 74,8 |
*/ |
SPINLOCK_DECLARE(lock); |
char name[THREAD_NAME_BUFLEN]; |
void (* thread_code)(void *); /**< Function implementing the thread. */ |
void *thread_arg; /**< Argument passed to thread_code() function. */ |
117,6 → 117,12 |
__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. |
139,8 → 145,11 |
extern void thread_print_list(void); |
extern void thread_destroy(thread_t *t); |
/* Fpu context slab cache */ |
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); |
#endif |
/kernel/trunk/generic/include/userspace.h |
---|
29,8 → 29,10 |
#ifndef __USERSPACE_H__ |
#define __USERSPACE_H__ |
#include <proc/thread.h> |
#include <arch/types.h> |
extern void userspace(__address entry) __attribute__ ((noreturn)); /**< Switch to user-space (CPU user priviledge level) */ |
/** Switch to user-space (CPU user priviledge level) */ |
extern void userspace(uspace_arg_t *uarg) __attribute__ ((noreturn)); |
#endif |
/kernel/trunk/generic/include/syscall/syscall.h |
---|
30,8 → 30,9 |
#define __SYSCALL_H__ |
typedef enum { |
SYS_CTL = 0, |
SYS_IO, |
SYS_IO = 0, |
SYS_THREAD_CREATE, |
SYS_THREAD_EXIT, |
SYS_MMAP, |
SYS_MREMAP, |
SYS_IPC_CALL_SYNC_FAST, |
/kernel/trunk/generic/include/ipc/ipc.h |
---|
78,7 → 78,7 |
* so that it can start initiating new messages. |
* |
* The protocol for negotiating is: |
* - sys_connecttome - sends a message IPC_M_CONNECTTOME |
* - sys_connect_to_me - sends a message IPC_M_CONNECTTOME |
* - sys_wait_for_call - upon receipt tries to allocate new phone |
* - if it fails, responds with ELIMIT |
* - passes call to userspace. If userspace |
/kernel/trunk/generic/src/proc/task.c |
---|
115,6 → 115,7 |
int rc; |
thread_t *t; |
task_t *task; |
uspace_arg_t *uarg; |
as = as_create(0); |
124,9 → 125,12 |
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; |
task = task_create(as, name); |
t = thread_create(uinit, (void *)((elf_header_t *)program_addr)->e_entry, |
task, 0, "uinit"); |
t = thread_create(uinit, uarg, task, 0, "uinit"); |
/* |
* Create the data as_area. |
/kernel/trunk/generic/src/proc/thread.c |
---|
53,6 → 53,7 |
#include <print.h> |
#include <mm/slab.h> |
#include <debug.h> |
#include <main/uinit.h> |
char *thread_states[] = {"Invalid", "Running", "Sleeping", "Ready", "Entering", "Exiting"}; /**< Thread states */ |
280,7 → 281,8 |
t->saved_context.ipl = interrupts_read(); |
interrupts_restore(ipl); |
t->name = name; |
memcpy(t->name, name, THREAD_NAME_BUFLEN); |
t->thread_code = func; |
t->thread_arg = arg; |
t->ticks = -1; |
423,3 → 425,40 |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
} |
/** Process syscall to create new thread. |
* |
*/ |
__native sys_thread_create(__address function, void *arg, void *stack, char *name) |
{ |
thread_t *t; |
char namebuf[THREAD_NAME_BUFLEN]; |
uspace_arg_t *uarg; |
__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; |
if ((t = thread_create(uinit, uarg, TASK, 0, namebuf))) { |
tid = t->tid; |
thread_ready(t); |
return (__native) tid; |
} else { |
free(namebuf); |
} |
return (__native) -1; |
} |
/** Process syscall to terminate thread. |
* |
*/ |
__native sys_thread_exit(int status) |
{ |
thread_exit(); |
/* Unreachable */ |
return 0; |
} |
/kernel/trunk/generic/src/main/uinit.c |
---|
30,10 → 30,21 |
#include <arch/types.h> |
#include <proc/thread.h> |
#include <userspace.h> |
#include <mm/slab.h> |
#include <print.h> |
/** Thread used to bring up userspace thread. |
* |
* @param arg Pointer to structure containing userspace entry and stack addresses. |
*/ |
void uinit(void *arg) |
{ |
printf("USER task, uinit thread: kernel mode\n"); |
userspace((__address)(arg)); |
uspace_arg_t uarg; |
uarg.uspace_entry = ((uspace_arg_t *) arg)->uspace_entry; |
uarg.uspace_stack = ((uspace_arg_t *) arg)->uspace_stack; |
free((uspace_arg_t *) arg); |
userspace(&uarg); |
} |
/kernel/trunk/generic/src/syscall/syscall.c |
---|
37,13 → 37,6 |
#include <debug.h> |
#include <ipc/sysipc.h> |
static __native sys_ctl(void) { |
printf("Thread finished\n"); |
thread_exit(); |
/* Unreachable */ |
return 0; |
} |
static __native sys_io(int fd, const void * buf, size_t count) { |
// TODO: buf sanity checks and a lot of other stuff ... |
56,7 → 49,6 |
return count; |
} |
static __native sys_mmap(void *address, size_t size, int flags) |
{ |
if (as_area_create(AS, flags, size, (__address) address)) |
71,8 → 63,9 |
} |
syshandler_t syscall_table[SYSCALL_END] = { |
sys_ctl, |
sys_io, |
sys_thread_create, |
sys_thread_exit, |
sys_mmap, |
sys_mremap, |
sys_ipc_call_sync_fast, |
/kernel/trunk/arch/ia64/src/ia64.c |
---|
41,6 → 41,7 |
#include <config.h> |
#include <userspace.h> |
#include <console/console.h> |
#include <proc/thread.h> |
void arch_pre_mm_init(void) |
{ |
72,7 → 73,7 |
} |
/** Enter userspace and never return. */ |
void userspace(__address entry) |
void userspace(uspace_arg_t *uarg) |
{ |
psr_t psr; |
rsc_t rsc; |
90,7 → 91,7 |
rsc.pl = PL_USER; |
rsc.mode = 3; /* eager mode */ |
switch_to_userspace(entry, USTACK_ADDRESS+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT), USTACK_ADDRESS, psr.value, rsc.value); |
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); |
while (1) { |
; |
/kernel/trunk/arch/amd64/src/userspace.c |
---|
39,7 → 39,7 |
* Change CPU protection level to 3, enter userspace. |
* |
*/ |
void userspace(__address entry) |
void userspace(uspace_arg_t *uarg) |
{ |
ipl_t ipl; |
46,22 → 46,18 |
ipl = interrupts_disable(); |
__asm__ volatile ("" |
"movq %0, %%rax;" |
"movq %1, %%rbx;" |
"movq %2, %%rcx;" |
"movq %3, %%rdx;" |
"movq %4, %%rsi;" |
"pushq %%rax;" |
"pushq %%rbx;" |
"pushq %%rcx;" |
"pushq %%rdx;" |
"pushq %%rsi;" |
"iretq;" |
: : "i" (gdtselector(UDATA_DES) | PL_USER), |
"i" (USTACK_ADDRESS+THREAD_STACK_SIZE), |
"pushq %0\n" |
"pushq %1\n" |
"pushq %2\n" |
"pushq %3\n" |
"pushq %4\n" |
"iretq\n" |
: : |
"i" (gdtselector(UDATA_DES) | PL_USER), |
"r" (uarg->uspace_stack+THREAD_STACK_SIZE), |
"r" (ipl), |
"i" (gdtselector(UTEXT_DES) | PL_USER), |
"r" (entry)); |
"r" (uarg->uspace_entry)); |
/* Unreachable */ |
for(;;); |
/kernel/trunk/arch/mips32/src/mips32.c |
---|
120,14 → 120,14 |
*/ |
__address supervisor_sp __attribute__ ((section (".text"))); |
void userspace(__address entry) |
void userspace(uspace_arg_t *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(entry); |
userspace_asm(USTACK_ADDRESS+PAGE_SIZE); |
cp0_epc_write(uarg->uspace_entry); |
userspace_asm(uarg->uspace_stack+PAGE_SIZE); |
while (1) |
; |
} |
/kernel/trunk/arch/ia32/include/fpu_context.h |
---|
39,7 → 39,6 |
struct fpu_context { |
/* TODO: We need malloc that aligns structures on 16-byte boundary */ |
__u8 fpu[512]; /* FXSAVE & FXRSTOR storage area */ |
}; |
/kernel/trunk/arch/ia32/src/userspace.c |
---|
39,7 → 39,7 |
* Change CPU protection level to 3, enter userspace. |
* |
*/ |
void userspace(__address entry) |
void userspace(uspace_arg_t *uarg) |
{ |
ipl_t ipl; |
60,7 → 60,8 |
"pushl %4\n" |
"iret" |
: |
: "i" (selector(UDATA_DES) | PL_USER), "r" (USTACK_ADDRESS+(THREAD_STACK_SIZE)), "r" (ipl), "i" (selector(UTEXT_DES) | PL_USER), "r" (entry) |
: "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) |
: "eax"); |
/* Unreachable */ |