Implemented OSThreadCreate system call

This commit is contained in:
Ali Mashtizadeh 2015-01-16 17:57:21 -08:00
parent 114b35bbbc
commit 5a3d86aa7b
8 changed files with 44 additions and 25 deletions

View File

@ -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); int OSReadDir(uint64_t fd, char *buf, size_t length, uint64_t *offset);
// Threads // Threads
int OSThreadCreate(uint64_t rip); int OSThreadCreate(uint64_t rip, uint64_t arg);
int OSThreadExit(uint64_t status); int OSThreadExit(uint64_t status);
int OSThreadSleep(uint64_t time); int OSThreadSleep(uint64_t time);
int OSThreadWait(uint64_t tid); int OSThreadWait(uint64_t tid);

View File

@ -92,9 +92,9 @@ OSReadDir(uint64_t fd, char *buf, size_t length, uint64_t *offset)
} }
int int
OSThreadCreate(uint64_t rip) OSThreadCreate(uint64_t rip, uint64_t arg)
{ {
return syscall(SYSCALL_THREADCREATE, rip); return syscall(SYSCALL_THREADCREATE, rip, arg);
} }
int int

View File

@ -33,6 +33,9 @@
#define MEM_USERSPACE_LEN 0x0000800000000000ULL #define MEM_USERSPACE_LEN 0x0000800000000000ULL
#define MEM_USERSPACE_TOP (MEM_USERSPACE_BASE + MEM_USERSPACE_LEN) #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_BASE 0xFFFF800000000000ULL
#define MEM_DIRECTMAP_LEN 0x0000010000000000ULL #define MEM_DIRECTMAP_LEN 0x0000010000000000ULL
#define MEM_XMAP_BASE 0xFFFF810000000000ULL #define MEM_XMAP_BASE 0xFFFF810000000000ULL

View File

@ -11,6 +11,7 @@
#include <machine/amd64.h> #include <machine/amd64.h>
#include <machine/amd64op.h> #include <machine/amd64op.h>
#include <machine/trap.h> #include <machine/trap.h>
#include <machine/pmap.h>
extern void ThreadKThreadEntry(TrapFrame *tf); extern void ThreadKThreadEntry(TrapFrame *tf);
extern void switchstack(uint64_t *oldrsp, uint64_t rsp); extern void switchstack(uint64_t *oldrsp, uint64_t rsp);
@ -22,7 +23,8 @@ Thread_InitArch(Thread *thr)
} }
void 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 // Initialize stack
uint64_t stacktop = thr->kstack + PGSIZE; uint64_t stacktop = thr->kstack + PGSIZE;
@ -46,30 +48,34 @@ Thread_SetupKThread(Thread *thr, void (*f)(void *), void *arg)
tf->rsp = stacktop; tf->rsp = stacktop;
tf->cs = SEL_KCS; tf->cs = SEL_KCS;
tf->rip = (uint64_t)f; 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; tf->rflags = RFLAGS_IF;
} }
static void static void
ThreadEnterUserLevelCB(void *arg) ThreadEnterUserLevelCB(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
{ {
TrapFrame tf; TrapFrame tf;
memset(&tf, 0, sizeof(tf)); memset(&tf, 0, sizeof(tf));
tf.ds = SEL_UDS | 3; tf.ds = SEL_UDS | 3;
tf.rip = (uint64_t)arg; tf.rip = (uint64_t)arg1;
tf.cs = SEL_UCS | 3; tf.cs = SEL_UCS | 3;
tf.rsp = 0x70000000 + PGSIZE; tf.rsp = (uint64_t)arg2 + MEM_USERSPACE_STKLEN;
tf.ss = SEL_UDS | 3; tf.ss = SEL_UDS | 3;
tf.rflags = RFLAGS_IF; tf.rflags = RFLAGS_IF;
tf.rdi = (uint64_t)arg3; /* Userspace Argument */
Trap_Pop(&tf); Trap_Pop(&tf);
} }
void 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]; extern TaskStateSegment64 TSS[MAX_CPUS];

View File

@ -22,6 +22,7 @@ typedef struct Thread {
ThreadArch arch; ThreadArch arch;
AS *space; AS *space;
uintptr_t kstack; uintptr_t kstack;
uintptr_t ustack;
uint64_t tid; uint64_t tid;
// Process // Process
struct Process *proc; struct Process *proc;
@ -43,6 +44,7 @@ typedef struct Thread {
typedef struct Process { typedef struct Process {
uint64_t pid; uint64_t pid;
AS *space; AS *space;
uintptr_t ustackNext; // Next user stack
TAILQ_ENTRY(Process) processList; TAILQ_ENTRY(Process) processList;
// Threads // Threads
uint64_t threads; uint64_t threads;
@ -57,7 +59,7 @@ Thread *Thread_Current();
Process *Thread_CreateProcess(); Process *Thread_CreateProcess();
Thread *Thread_Create(Process *proc); Thread *Thread_Create(Process *proc);
Thread *Thread_KThreadCreate(void (*f)(void*), void *arg); 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_SetRunnable(Thread *thr);
void Thread_SetWaiting(Thread *thr); void Thread_SetWaiting(Thread *thr);
void Thread_SetZombie(Thread *thr); void Thread_SetZombie(Thread *thr);
@ -73,8 +75,9 @@ void Process_Destroy(Process *proc);
// Platform functions // Platform functions
void Thread_InitArch(Thread *thr); void Thread_InitArch(Thread *thr);
void Thread_SetupKThread(Thread *thr, void (*f)(void *), void *arg); void Thread_SetupKThread(Thread *thr, void (*f)(),
void Thread_SetupUThread(Thread *thr, uint64_t rip); 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); void Thread_SwitchArch(Thread *oldthr, Thread *newthr);
// Handle Functions // Handle Functions

View File

@ -78,8 +78,7 @@ Loader_LoadFirst(Thread *thr, VNode *vn, void *buf, uint64_t len)
} }
} }
void *stack = PAlloc_AllocPage(); PMap_AllocMap(as, MEM_USERSPACE_STKBASE, MEM_USERSPACE_STKLEN, PTE_W);
PMap_Map(as, (uint64_t)DMVA2PA(stack), 0x70000000, 1, 0);
PMap_LoadAS(as); // Reload CR3 PMap_LoadAS(as); // Reload CR3
for (i = 0; i < ehdr->e_phnum; i++) 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.ds = SEL_UDS | 3;
tf.rip = ehdr->e_entry; tf.rip = ehdr->e_entry;
tf.cs = SEL_UCS | 3; tf.cs = SEL_UCS | 3;
tf.rsp = 0x70000000 + PGSIZE; tf.rsp = MEM_USERSPACE_STKBASE + MEM_USERSPACE_STKLEN;
tf.ss = SEL_UDS | 3; tf.ss = SEL_UDS | 3;
tf.rflags = RFLAGS_IF; tf.rflags = RFLAGS_IF;
tf.rdi = 0;
Trap_Pop(&tf); Trap_Pop(&tf);
return true; return true;
@ -243,8 +243,7 @@ Loader_Load(Thread *thr, VNode *vn, void *buf, uint64_t len)
} }
} }
void *stack = PAlloc_AllocPage(); PMap_AllocMap(as, MEM_USERSPACE_STKBASE, MEM_USERSPACE_STKLEN, PTE_W);
PMap_Map(as, (uint64_t)DMVA2PA(stack), 0x70000000, 1, 0);
for (i = 0; i < ehdr->e_phnum; i++) 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; return true;
} }

View File

@ -285,11 +285,11 @@ Syscall_ReadDir(uint64_t fd, char *user_buf, size_t len, uintptr_t user_off)
} }
uint64_t uint64_t
Syscall_ThreadCreate(uint64_t rip) Syscall_ThreadCreate(uint64_t rip, uint64_t arg)
{ {
uint64_t threadId; uint64_t threadId;
Thread *curThread = Thread_Current(); Thread *curThread = Thread_Current();
Thread *newThread = Thread_UThreadCreate(curThread, rip); Thread *newThread = Thread_UThreadCreate(curThread, rip, arg);
if (newThread == NULL) { if (newThread == NULL) {
return -1; return -1;
} }
@ -386,7 +386,7 @@ Syscall_Entry(uint64_t syscall, uint64_t a1, uint64_t a2,
case SYSCALL_READDIR: case SYSCALL_READDIR:
return Syscall_ReadDir(a1, (char *)a2, a3, a4); return Syscall_ReadDir(a1, (char *)a2, a3, a4);
case SYSCALL_THREADCREATE: case SYSCALL_THREADCREATE:
return Syscall_ThreadCreate(a1); return Syscall_ThreadCreate(a1, a2);
case SYSCALL_THREADEXIT: case SYSCALL_THREADEXIT:
Syscall_ThreadExit(a1); Syscall_ThreadExit(a1);
return 0; return 0;

View File

@ -83,6 +83,9 @@ Thread_Create(Process *proc)
if (proc != NULL) { if (proc != NULL) {
// XXX: Add to thread list // XXX: Add to thread list
proc->threads++; proc->threads++;
thr->ustack = proc->ustackNext;
proc->ustackNext += MEM_USERSPACE_STKLEN;
} }
if ((proc != NULL) && (proc->space != NULL)) { if ((proc != NULL) && (proc->space != NULL)) {
@ -124,6 +127,7 @@ Thread_CreateProcess()
Slab_Free(&processSlab, proc); Slab_Free(&processSlab, proc);
return NULL; return NULL;
} }
proc->ustackNext = MEM_USERSPACE_STKBASE;
Handle_Init(proc); Handle_Init(proc);
@ -139,13 +143,13 @@ Thread_KThreadCreate(void (*f)(void *), void *arg)
if (!thr) if (!thr)
return NULL; return NULL;
Thread_SetupKThread(thr, f, arg); Thread_SetupKThread(thr, f, (uintptr_t)arg, 0, 0);
return thr; return thr;
} }
Thread * Thread *
Thread_UThreadCreate(Thread *oldThr, uint64_t rip) Thread_UThreadCreate(Thread *oldThr, uint64_t rip, uint64_t arg)
{ {
Process *proc = oldThr->proc; Process *proc = oldThr->proc;
Thread *thr = (Thread *)Slab_Alloc(&threadSlab); Thread *thr = (Thread *)Slab_Alloc(&threadSlab);
@ -165,10 +169,14 @@ Thread_UThreadCreate(Thread *oldThr, uint64_t rip)
thr->space = oldThr->space; thr->space = oldThr->space;
thr->schedState = SCHED_STATE_NULL; 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); Thread_InitArch(thr);
// Initialize queue // Initialize queue
Thread_SetupUThread(thr, rip); Thread_SetupUThread(thr, rip, arg);
thr->proc = proc; thr->proc = proc;
proc->threads++; proc->threads++;