Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1065 → Rev 1066

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