Files
nt-lite/code/kernel/include/kernel/ke_cpu.h
T

91 lines
2.8 KiB
C

// Kernel ke cpu declarations shared by implementation files and kernel clients.
#pragma once
// ke_cpu.h - per-CPU execution state
// Every processor that reaches kernel-owned state has a KCPU record. The record
// owns CPU-local scheduler, IRQL, GDT, and TSS state.
#include <stdint.h>
#include <kernel/ke_irql.h>
#include <kernel/ke_idt.h>
#define KE_MAX_CPUS 32u
#define KE_INVALID_CPU 0xFFFFFFFFu
struct THREAD;
typedef struct KCPU {
// GS:0 points back at the owning KCPU while executing in ring 0.
// User mode keeps its TEB in GS_BASE; swapgs restores this pointer on
// entry from user mode and parks the user TEB in IA32_KERNEL_GS_BASE.
struct KCPU* Self;
uint32_t CpuIndex;
uint32_t LapicId;
uint32_t AcpiProcessorId;
uint32_t BootProcessorIndex;
uint8_t Present;
uint8_t Started;
uint8_t Parked;
uint8_t Online;
uint8_t IsBsp;
// CPUID/MADT-derived SMT topology. PackageId/CoreId/ThreadId are decoded
// from the APIC ID using CPUID leaf 0x1F/0x0B when available, with a
// conservative CPUID(1)/CPUID(4) fallback. PhysicalCoreIndex is a compact
// kernel-local core number used by the scheduler. CoreSiblingMask contains
// all logical CPUs that share this physical core. PackageMask contains all
// logical CPUs in the same package. IsPrimaryThread is the scheduler's
// preferred logical CPU for a physical core, currently the lowest CpuIndex
// in that core.
uint32_t PackageId;
uint32_t CoreId;
uint32_t ThreadId;
uint32_t PhysicalCoreIndex;
uint64_t CoreSiblingMask;
uint64_t PackageMask;
uint8_t IsPrimaryThread;
uint8_t SmtThreadCount;
uint16_t TopologyFlags;
struct THREAD* CurrentThread;
struct THREAD* IdleThread;
struct THREAD* OutgoingThread;
// Do not store the scheduler post-switch unlock cookie here. It belongs
// to the suspended THREAD continuation that resumes after KeSwitchContext().
KIRQL CurrentIrql;
uint32_t InterruptDepth;
volatile long ReschedulePending;
// AP scheduler admission handshake. APs set SchedulerActive just before
// they leave the raw kernel park loop and enter their per-CPU idle thread.
volatile long SchedulerCommand;
volatile long SchedulerActive;
TSS64 Tss;
uint64_t Gdt[KE_GDT_ENTRIES];
KGDTR Gdtr;
void* KernelStack;
uintptr_t KernelStackTop;
uint64_t SchedulerTicks;
uint64_t ContextSwitches;
} KCPU;
extern KCPU gCpus[KE_MAX_CPUS];
extern uint32_t gCpuCount;
void KeInitializeBootstrapCpu(void);
void KeLoadKernelGsBase(KCPU* cpu);
void KeSetUserGsBase(uintptr_t userGsBase);
uintptr_t KeGetUserGsBase(void);
KCPU* KeGetCurrentCpu(void);
KCPU* KeGetCpuByIndex(uint32_t index);
uint32_t KeGetCurrentCpuIndex(void);
TSS64* KeGetCurrentTss(void);