Implemented OSThreadCreate system call
This commit is contained in:
parent
114b35bbbc
commit
5a3d86aa7b
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <machine/amd64.h>
|
||||
#include <machine/amd64op.h>
|
||||
#include <machine/trap.h>
|
||||
#include <machine/pmap.h>
|
||||
|
||||
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];
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
|
Loading…
Reference in New Issue
Block a user