diff --git a/include/syscall.h b/include/syscall.h index f0c76c7..4421aec 100644 --- a/include/syscall.h +++ b/include/syscall.h @@ -26,7 +26,7 @@ int OSStat(const char *path, struct stat *sb); int OSReadDir(uint64_t fd, char *buf, size_t length, uint64_t *offset); // Threads -int OSThreadCreate(uint64_t rip); +int OSThreadCreate(uint64_t rip, uint64_t arg); int OSThreadExit(uint64_t status); int OSThreadSleep(uint64_t time); int OSThreadWait(uint64_t tid); diff --git a/lib/libc/syscall.c b/lib/libc/syscall.c index 6a98c09..bd153c4 100644 --- a/lib/libc/syscall.c +++ b/lib/libc/syscall.c @@ -92,9 +92,9 @@ OSReadDir(uint64_t fd, char *buf, size_t length, uint64_t *offset) } int -OSThreadCreate(uint64_t rip) +OSThreadCreate(uint64_t rip, uint64_t arg) { - return syscall(SYSCALL_THREADCREATE, rip); + return syscall(SYSCALL_THREADCREATE, rip, arg); } int diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h index da380b6..218b0bf 100644 --- a/sys/amd64/include/pmap.h +++ b/sys/amd64/include/pmap.h @@ -33,6 +33,9 @@ #define MEM_USERSPACE_LEN 0x0000800000000000ULL #define MEM_USERSPACE_TOP (MEM_USERSPACE_BASE + MEM_USERSPACE_LEN) +#define MEM_USERSPACE_STKBASE 0x0000000070000000ULL +#define MEM_USERSPACE_STKLEN 0x0000000000010000ULL + #define MEM_DIRECTMAP_BASE 0xFFFF800000000000ULL #define MEM_DIRECTMAP_LEN 0x0000010000000000ULL #define MEM_XMAP_BASE 0xFFFF810000000000ULL diff --git a/sys/amd64/thread.c b/sys/amd64/thread.c index 60fe53b..2df6f4a 100644 --- a/sys/amd64/thread.c +++ b/sys/amd64/thread.c @@ -11,6 +11,7 @@ #include #include #include +#include extern void ThreadKThreadEntry(TrapFrame *tf); extern void switchstack(uint64_t *oldrsp, uint64_t rsp); @@ -22,7 +23,8 @@ Thread_InitArch(Thread *thr) } void -Thread_SetupKThread(Thread *thr, void (*f)(void *), void *arg) +Thread_SetupKThread(Thread *thr, void (*f)(), + uintptr_t arg1, uintptr_t arg2, uintptr_t arg3) { // Initialize stack uint64_t stacktop = thr->kstack + PGSIZE; @@ -46,30 +48,34 @@ Thread_SetupKThread(Thread *thr, void (*f)(void *), void *arg) tf->rsp = stacktop; tf->cs = SEL_KCS; tf->rip = (uint64_t)f; - tf->rdi = (uint64_t)arg; + tf->rdi = (uint64_t)arg1; + tf->rsi = (uint64_t)arg2; + tf->rdx = (uint64_t)arg3; tf->rflags = RFLAGS_IF; } static void -ThreadEnterUserLevelCB(void *arg) +ThreadEnterUserLevelCB(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3) { TrapFrame tf; memset(&tf, 0, sizeof(tf)); tf.ds = SEL_UDS | 3; - tf.rip = (uint64_t)arg; + tf.rip = (uint64_t)arg1; tf.cs = SEL_UCS | 3; - tf.rsp = 0x70000000 + PGSIZE; + tf.rsp = (uint64_t)arg2 + MEM_USERSPACE_STKLEN; tf.ss = SEL_UDS | 3; tf.rflags = RFLAGS_IF; + tf.rdi = (uint64_t)arg3; /* Userspace Argument */ Trap_Pop(&tf); } void -Thread_SetupUThread(Thread *thr, uint64_t rip) +Thread_SetupUThread(Thread *thr, uintptr_t rip, uintptr_t arg) { - Thread_SetupKThread(thr, ThreadEnterUserLevelCB, (void *)rip); + Thread_SetupKThread(thr, ThreadEnterUserLevelCB, rip, + thr->ustack, arg); } extern TaskStateSegment64 TSS[MAX_CPUS]; diff --git a/sys/include/thread.h b/sys/include/thread.h index 467c7f6..263ba0f 100644 --- a/sys/include/thread.h +++ b/sys/include/thread.h @@ -22,6 +22,7 @@ typedef struct Thread { ThreadArch arch; AS *space; uintptr_t kstack; + uintptr_t ustack; uint64_t tid; // Process struct Process *proc; @@ -43,6 +44,7 @@ typedef struct Thread { typedef struct Process { uint64_t pid; AS *space; + uintptr_t ustackNext; // Next user stack TAILQ_ENTRY(Process) processList; // Threads uint64_t threads; @@ -57,7 +59,7 @@ Thread *Thread_Current(); Process *Thread_CreateProcess(); Thread *Thread_Create(Process *proc); Thread *Thread_KThreadCreate(void (*f)(void*), void *arg); -Thread *Thread_UThreadCreate(Thread *oldThr, uint64_t rip); +Thread *Thread_UThreadCreate(Thread *oldThr, uint64_t rip, uint64_t arg); void Thread_SetRunnable(Thread *thr); void Thread_SetWaiting(Thread *thr); void Thread_SetZombie(Thread *thr); @@ -73,8 +75,9 @@ void Process_Destroy(Process *proc); // Platform functions void Thread_InitArch(Thread *thr); -void Thread_SetupKThread(Thread *thr, void (*f)(void *), void *arg); -void Thread_SetupUThread(Thread *thr, uint64_t rip); +void Thread_SetupKThread(Thread *thr, void (*f)(), + uintptr_t arg1, uintptr_t arg2, uintptr_t arg3); +void Thread_SetupUThread(Thread *thr, uint64_t rip, uint64_t arg); void Thread_SwitchArch(Thread *oldthr, Thread *newthr); // Handle Functions diff --git a/sys/kern/loader.c b/sys/kern/loader.c index 11a6077..bac700c 100644 --- a/sys/kern/loader.c +++ b/sys/kern/loader.c @@ -78,8 +78,7 @@ Loader_LoadFirst(Thread *thr, VNode *vn, void *buf, uint64_t len) } } - void *stack = PAlloc_AllocPage(); - PMap_Map(as, (uint64_t)DMVA2PA(stack), 0x70000000, 1, 0); + PMap_AllocMap(as, MEM_USERSPACE_STKBASE, MEM_USERSPACE_STKLEN, PTE_W); PMap_LoadAS(as); // Reload CR3 for (i = 0; i < ehdr->e_phnum; i++) @@ -101,9 +100,10 @@ Loader_LoadFirst(Thread *thr, VNode *vn, void *buf, uint64_t len) tf.ds = SEL_UDS | 3; tf.rip = ehdr->e_entry; tf.cs = SEL_UCS | 3; - tf.rsp = 0x70000000 + PGSIZE; + tf.rsp = MEM_USERSPACE_STKBASE + MEM_USERSPACE_STKLEN; tf.ss = SEL_UDS | 3; tf.rflags = RFLAGS_IF; + tf.rdi = 0; Trap_Pop(&tf); return true; @@ -243,8 +243,7 @@ Loader_Load(Thread *thr, VNode *vn, void *buf, uint64_t len) } } - void *stack = PAlloc_AllocPage(); - PMap_Map(as, (uint64_t)DMVA2PA(stack), 0x70000000, 1, 0); + PMap_AllocMap(as, MEM_USERSPACE_STKBASE, MEM_USERSPACE_STKLEN, PTE_W); for (i = 0; i < ehdr->e_phnum; i++) { @@ -260,7 +259,7 @@ Loader_Load(Thread *thr, VNode *vn, void *buf, uint64_t len) } } - Thread_SetupUThread(thr, ehdr->e_entry); + Thread_SetupUThread(thr, ehdr->e_entry, 0); return true; } diff --git a/sys/kern/syscall.c b/sys/kern/syscall.c index a97b3bc..971461e 100644 --- a/sys/kern/syscall.c +++ b/sys/kern/syscall.c @@ -285,11 +285,11 @@ Syscall_ReadDir(uint64_t fd, char *user_buf, size_t len, uintptr_t user_off) } uint64_t -Syscall_ThreadCreate(uint64_t rip) +Syscall_ThreadCreate(uint64_t rip, uint64_t arg) { uint64_t threadId; Thread *curThread = Thread_Current(); - Thread *newThread = Thread_UThreadCreate(curThread, rip); + Thread *newThread = Thread_UThreadCreate(curThread, rip, arg); if (newThread == NULL) { return -1; } @@ -386,7 +386,7 @@ Syscall_Entry(uint64_t syscall, uint64_t a1, uint64_t a2, case SYSCALL_READDIR: return Syscall_ReadDir(a1, (char *)a2, a3, a4); case SYSCALL_THREADCREATE: - return Syscall_ThreadCreate(a1); + return Syscall_ThreadCreate(a1, a2); case SYSCALL_THREADEXIT: Syscall_ThreadExit(a1); return 0; diff --git a/sys/kern/thread.c b/sys/kern/thread.c index a3eb4db..16e6b46 100644 --- a/sys/kern/thread.c +++ b/sys/kern/thread.c @@ -83,6 +83,9 @@ Thread_Create(Process *proc) if (proc != NULL) { // XXX: Add to thread list proc->threads++; + + thr->ustack = proc->ustackNext; + proc->ustackNext += MEM_USERSPACE_STKLEN; } if ((proc != NULL) && (proc->space != NULL)) { @@ -124,6 +127,7 @@ Thread_CreateProcess() Slab_Free(&processSlab, proc); return NULL; } + proc->ustackNext = MEM_USERSPACE_STKBASE; Handle_Init(proc); @@ -139,13 +143,13 @@ Thread_KThreadCreate(void (*f)(void *), void *arg) if (!thr) return NULL; - Thread_SetupKThread(thr, f, arg); + Thread_SetupKThread(thr, f, (uintptr_t)arg, 0, 0); return thr; } Thread * -Thread_UThreadCreate(Thread *oldThr, uint64_t rip) +Thread_UThreadCreate(Thread *oldThr, uint64_t rip, uint64_t arg) { Process *proc = oldThr->proc; Thread *thr = (Thread *)Slab_Alloc(&threadSlab); @@ -165,10 +169,14 @@ Thread_UThreadCreate(Thread *oldThr, uint64_t rip) thr->space = oldThr->space; thr->schedState = SCHED_STATE_NULL; + thr->ustack = proc->ustackNext; + proc->ustackNext += MEM_USERSPACE_STKLEN; + PMap_AllocMap(thr->space, thr->ustack, MEM_USERSPACE_STKLEN, PTE_W); + Thread_InitArch(thr); // Initialize queue - Thread_SetupUThread(thr, rip); + Thread_SetupUThread(thr, rip, arg); thr->proc = proc; proc->threads++;