Files
PluralTechnology/service/ptos/arch/amd64/ps/thread.c
T
2026-07-15 01:10:39 -04:00

103 lines
2.1 KiB
C

/*
* Copyright (c) 2026, Chloe M.
* Provided under the BSD-3 clause.
*
* Description: MD thread management
* Author: Chloe M.
*/
#include <hal/thread.h>
#include <hal/page.h>
#include <ps/thread.h>
#include <ps/process.h>
#include <machine/gdt.h>
#include <machine/lapic.h>
#include <mm/vm.h>
#include <string.h>
/*
* Allocate a kernel stack for a thread
*/
static VOID *
ThreadAllocKStack(VOID)
{
MM_RANGE StackRange;
PT_STATUS Status;
Status = MmAllocatePages(1, &StackRange);
if (PT_ERROR(Status)) {
return NULL;
}
return RANGE_PTR(&StackRange);
}
/*
* Initialize a thread control block
*
* @Thread: Thread to initialize TCB of
* @Tcb: Thread control block to initialize
* @Ip: Instruction pointer value to start off with
*
* TODO: Support user threads
*/
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));
/* Initialize only whats needed */
Frame->Rflags = 0x202;
Frame->Rsp = Thread->StackBase + PAGESIZE;
Frame->Rip = Ip;
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;
}
PT_STATUS
HalThreadInit(THREAD *Thread, ULONG Flags, UPTR Ip)
{
TCB *Tcb;
if (Thread == NULL) {
return STATUS_INVALID_PARAM;
}
Tcb = &Thread->Tcb;
ThreadInitTcb(Thread, Tcb, Ip);
return STATUS_SUCCESS;
}
VOID
HalPrimeThreadTimer(ULONG Usec)
{
MdLapicTimerOneshotUs(Usec);
}