diff --git a/service/ptos/arch/amd64/ps/context.c b/service/ptos/arch/amd64/ps/context.c index fccbbbd..f0c9801 100644 --- a/service/ptos/arch/amd64/ps/context.c +++ b/service/ptos/arch/amd64/ps/context.c @@ -20,8 +20,12 @@ HalContextSwitch(TRAP_FRAME *Frame) PROCESS *NextParent; TCB *ThisTcb, *NextTcb; KPCR *Kpcr; + MCB *Mcb; + TSS_ENTRY *Tss; + UPTR KStackTop; Kpcr = HalKpcrCurrent(); + Mcb = &Kpcr->Mcb; ThisThread = Kpcr->CurrentThread; NextThread = NULL; @@ -54,6 +58,12 @@ HalContextSwitch(TRAP_FRAME *Frame) NextParent = NextThread->Parent; HalMmuWriteVas(&NextParent->Vas); + /* Update the task state segment with kstack */ + KStackTop = NextTcb->KStackBase + NextTcb->KStackLength; + Tss = Mcb->Tss; + Tss->Rsp0Low = KStackTop & 0xFFFFFFFF; + Tss->Rsp0High = (KStackTop >> 32) & 0xFFFFFFFF; + /* Context switch here */ Kpcr->CurrentThread = NextThread; NextTcb = &NextThread->Tcb; diff --git a/service/ptos/arch/amd64/ps/thread.c b/service/ptos/arch/amd64/ps/thread.c index 449aec2..bb01c41 100644 --- a/service/ptos/arch/amd64/ps/thread.c +++ b/service/ptos/arch/amd64/ps/thread.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -44,16 +45,25 @@ static PT_STATUS ThreadInitTcb(THREAD *Thread, TCB *Tcb, UPTR Ip) { TRAP_FRAME *Frame; + PROCESS *Parent; if (Thread == NULL || Tcb == NULL) { return STATUS_INVALID_PARAM; } + Parent = Thread->Parent; Thread->StackBase = (UPTR)ThreadAllocKStack(); if (Thread->StackBase == 0) { return STATUS_NO_MEMORY; } + Tcb->KStackLength = PAGESIZE; + Tcb->KStackBase = (UPTR)ThreadAllocKStack(); + if (Tcb->KStackBase == 0) { + /* TODO: Free Thread->StackBase */ + return STATUS_NO_MEMORY; + } + /* Zero the whole frame */ Frame = &Tcb->FrameSnapshot; RtlMemSet(Frame, 0, sizeof(*Frame)); @@ -62,8 +72,12 @@ ThreadInitTcb(THREAD *Thread, TCB *Tcb, UPTR Ip) Frame->Rflags = 0x202; Frame->Rsp = Thread->StackBase + PAGESIZE; Frame->Rip = Ip; - Frame->CodeSeg = GDT_KCODE; - Frame->StackSeg = GDT_KDATA; + Frame->CodeSeg = ISSET(Parent->Flags, PS_USER) + ? GDT_UCODE | 3 + : GDT_KCODE; + Frame->StackSeg = ISSET(Parent->Flags, PS_USER) + ? GDT_UDATA | 3 + : GDT_KDATA; return STATUS_SUCCESS; } diff --git a/service/ptos/head/arch/amd64/tcb.h b/service/ptos/head/arch/amd64/tcb.h index e49fb83..fe09d9d 100644 --- a/service/ptos/head/arch/amd64/tcb.h +++ b/service/ptos/head/arch/amd64/tcb.h @@ -17,9 +17,13 @@ * information. * * @FrameSnapshot: Processor state snapshot + * @KStackBase: TSS RSP0 base + * @KStackLength: TSS RSP0 length */ typedef struct { TRAP_FRAME FrameSnapshot; + UPTR KStackBase; + USIZE KStackLength; } TCB; #endif /* !_MACHINE_TCB_H_ */ diff --git a/service/ptos/ps/process.c b/service/ptos/ps/process.c index 9c0f47c..8c44405 100644 --- a/service/ptos/ps/process.c +++ b/service/ptos/ps/process.c @@ -25,11 +25,6 @@ PsCreateProcess(const CHAR *Name, ULONG Flags, PROCESS **Result) return STATUS_INVALID_PARAM; } - /* TODO: Support user-level processes */ - if (ISSET(Flags, PS_USER)) { - return STATUS_NOT_SUPPORTED; - } - NameLen = RtlStrLen(Name); if (NameLen >= PS_NAME_MAX - 1) { return STATUS_NAME_TOO_LONG;