91 lines
2.8 KiB
C
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);
|