85927ce8c1
Signed-off-by: Chloe M <chloe@mensia.org>
103 lines
2.1 KiB
C
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);
|
|
}
|