d4390c6a1b
Signed-off-by: Chloe M. <chloe@mensia.org>
102 lines
2.6 KiB
C
102 lines
2.6 KiB
C
/*
|
|
* Copyright (c) 2026, Chloe M.
|
|
* Provided under the BSD-3 clause.
|
|
*
|
|
* Description: Kernel processor control region
|
|
* Author: Chloe M.
|
|
*/
|
|
|
|
#include <hal/kpcr.h>
|
|
#include <ke/bugcheck.h>
|
|
#include <machine/idt.h>
|
|
#include <machine/trap.h>
|
|
#include <machine/msr.h>
|
|
#include <machine/lapic.h>
|
|
#include <machine/gdt.h>
|
|
|
|
/* Externs */
|
|
extern GDT_ENTRY g_GDT[GDT_ENTRY_COUNT];
|
|
|
|
/*
|
|
* Initialize interrupts for the current processor
|
|
*/
|
|
static VOID
|
|
InitInterrupts(VOID)
|
|
{
|
|
MdIdtSetGate(0x00, (UPTR)TrapDivError, IDT_TRAP_GATE, 0);
|
|
MdIdtSetGate(0x01, (UPTR)TrapDebugException, IDT_TRAP_GATE, 0);
|
|
MdIdtSetGate(0x02, (UPTR)TrapNmi, IDT_TRAP_GATE, IST_NMI);
|
|
MdIdtSetGate(0x03, (UPTR)TrapBreakPoint, IDT_TRAP_GATE, 0);
|
|
MdIdtSetGate(0x04, (UPTR)TrapOverflow, IDT_TRAP_GATE, 0);
|
|
MdIdtSetGate(0x05, (UPTR)TrapBoundRange, IDT_TRAP_GATE, 0);
|
|
MdIdtSetGate(0x06, (UPTR)TrapInvalidOpcode, IDT_TRAP_GATE, 0);
|
|
MdIdtSetGate(0x07, (UPTR)TrapNoCoprocessor, IDT_TRAP_GATE, 0);
|
|
MdIdtSetGate(0x08, (UPTR)TrapDoubleFault, IDT_TRAP_GATE, 0);
|
|
MdIdtSetGate(0x09, (UPTR)TrapReserved, IDT_TRAP_GATE, 0);
|
|
MdIdtSetGate(0x0A, (UPTR)TrapInvalidTss, IDT_TRAP_GATE, 0);
|
|
MdIdtSetGate(0x0B, (UPTR)TrapSegNotPresent, IDT_TRAP_GATE, 0);
|
|
MdIdtSetGate(0x0C, (UPTR)TrapStackSegmentFault, IDT_TRAP_GATE, 0);
|
|
MdIdtSetGate(0x0D, (UPTR)TrapGeneralProtection, IDT_TRAP_GATE, 0);
|
|
MdIdtSetGate(0x0E, (UPTR)TrapPageFault, IDT_TRAP_GATE, 0);
|
|
MdIdtSetGate(0x2E, (UPTR)TrapLegacySyscall, IDT_USER_GATE, 0);
|
|
MdIdtLoad();
|
|
}
|
|
|
|
KPCR *
|
|
HalKpcrCurrent(VOID)
|
|
{
|
|
KPCR *Kpcr;
|
|
|
|
Kpcr = (KPCR *)MdRdmsr(IA32_GS_BASE);
|
|
if (Kpcr == NULL) {
|
|
KeBugCheck(
|
|
BUGCHECK_UNBOUND_RESRC,
|
|
"KPCR not bound in IA32_GS_BASE\n"
|
|
);
|
|
}
|
|
|
|
return Kpcr;
|
|
}
|
|
|
|
VOID
|
|
HalKpcrP1Init(KPCR *Kpcr)
|
|
{
|
|
/* Initialize interrupts for this core */
|
|
InitInterrupts();
|
|
|
|
/* Save the current KPCR */
|
|
MdWrmsr(IA32_GS_BASE, (UPTR)Kpcr);
|
|
}
|
|
|
|
VOID
|
|
HalKpcrP2Init(KPCR *Kpcr)
|
|
{
|
|
TSS_DESCRIPTOR *TssDesc;
|
|
|
|
/* Initialize per-processor pools */
|
|
ExPoolRegionInit(&Kpcr->PoolRegion);
|
|
|
|
/* Initialize the Local APIC unit */
|
|
MdLapicInit(Kpcr);
|
|
|
|
/* Load the Task State Segment */
|
|
TssDesc = (TSS_DESCRIPTOR *)&g_GDT[GDT_TSS_INDEX];
|
|
MdTssInit(TssDesc);
|
|
ASMV(
|
|
"mov %0, %%ax\n"
|
|
"ltr %%ax\n"
|
|
:
|
|
: "i" (GDT_TSS)
|
|
: "memory"
|
|
);
|
|
|
|
/* Setup interrupt stacks */
|
|
MdTssAllocIst(IST_NMI, 1024);
|
|
|
|
/* Initialize the scheduler queue */
|
|
SCHED_QUEUE_INIT(&Kpcr->SchedQueue);
|
|
|
|
/* Enable interrupts */
|
|
ASMV("sti");
|
|
}
|