// ke_cpu.c - bootstrap/per-CPU state plumbing #include #include #define BOOTSTRAP_CPU_STACK_SIZE 0x4000u KCPU gCpus[KE_MAX_CPUS]; uint32_t gCpuCount = 0; static uint8_t gBootstrapCpuStack[BOOTSTRAP_CPU_STACK_SIZE]; void KeInitializeBootstrapCpu(void) { memset(gCpus, 0, sizeof(gCpus)); KCPU* cpu = &gCpus[0]; cpu->CpuIndex = 0; cpu->LapicId = 0; cpu->Present = 1; cpu->Online = 1; cpu->IsBsp = 1; cpu->CurrentIrql = PASSIVE_LEVEL; cpu->InterruptDepth = 0; cpu->ReschedulePending = 0; cpu->KernelStack = gBootstrapCpuStack; cpu->KernelStackTop = (uintptr_t)(gBootstrapCpuStack + sizeof(gBootstrapCpuStack)); memset(&cpu->Tss, 0, sizeof(cpu->Tss)); cpu->Tss.IoMapBase = sizeof(TSS64); cpu->Tss.RSP0 = cpu->KernelStackTop; gCpuCount = 1; } KCPU* KeGetCurrentCpu(void) { // SMP phase 1: only CPU0 is online. Later this becomes LAPIC-ID or // per-CPU-base based lookup once the bootloader parks APs for us. return &gCpus[0]; } KCPU* KeGetCpuByIndex(uint32_t index) { if (index >= KE_MAX_CPUS) return (KCPU*)0; return &gCpus[index]; } uint32_t KeGetCurrentCpuIndex(void) { return KeGetCurrentCpu()->CpuIndex; } TSS64* KeGetCurrentTss(void) { return &KeGetCurrentCpu()->Tss; }