/* * Copyright (c) 2026, Chloe M. * Provided under the BSD-3 clause. * * Description: Kernel processor control region * Author: Chloe M. */ #include #include #include #include #include #include #include #include /* 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); 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, PAGESIZE); /* Initialize the scheduler queue */ SCHED_QUEUE_INIT(&Kpcr->SchedQueue); /* Enable interrupts */ ASMV("sti"); }