66 lines
2.2 KiB
C++
66 lines
2.2 KiB
C++
/*
|
|
* SmpBoot.hpp
|
|
* Symmetric Multiprocessing bootstrap and per-CPU data
|
|
* Copyright (c) 2026 Daniel Hammer
|
|
*/
|
|
|
|
#pragma once
|
|
#include <cstdint>
|
|
#include <Hal/GDT.hpp>
|
|
|
|
// ====================================================================
|
|
// Assembly-visible offsets into CpuData
|
|
// These MUST match the struct layout below. Verified by static_assert
|
|
// in SmpBoot.cpp.
|
|
// ====================================================================
|
|
#define CPUDATA_SELF_PTR 0
|
|
#define CPUDATA_KERNEL_RSP 8
|
|
#define CPUDATA_USER_RSP 16
|
|
#define CPUDATA_CURRENT_SLOT 24
|
|
|
|
namespace Smp {
|
|
|
|
static constexpr int MaxCPUs = 64;
|
|
|
|
struct CpuData {
|
|
// === Fields accessed by assembly (offsets defined above) ===
|
|
uint64_t selfPtr; // offset 0: pointer to self
|
|
uint64_t kernelRsp; // offset 8: kernel stack top for SYSCALL
|
|
uint64_t userRspScratch; // offset 16: scratch for saving user RSP
|
|
int32_t currentSlot; // offset 24: process table slot, -1 = idle
|
|
int32_t _pad0; // offset 28: padding
|
|
|
|
// === C++-only fields ===
|
|
int cpuIndex; // 0-based CPU index
|
|
uint32_t lapicId; // local APIC ID
|
|
uint64_t idleSavedRsp; // RSP saved when switching from idle to process
|
|
volatile bool started; // set by AP after init is complete
|
|
|
|
Hal::TSS64* tss; // pointer to this CPU's TSS
|
|
bool hasMwait; // CPU supports MONITOR/MWAIT
|
|
|
|
// Per-CPU GDT and TSS (APs use these; BSP uses globals)
|
|
Hal::BasicGDT cpuGdt __attribute__((aligned(16)));
|
|
Hal::TSS64 cpuTss __attribute__((aligned(16)));
|
|
};
|
|
|
|
// Get the current CPU's data (reads gs:0 which holds the self-pointer)
|
|
inline CpuData* GetCurrentCpuData() {
|
|
CpuData* ptr;
|
|
asm volatile("mov %%gs:0, %0" : "=r"(ptr));
|
|
return ptr;
|
|
}
|
|
|
|
// Get CPU data by index
|
|
CpuData* GetCpuData(int index);
|
|
|
|
// Number of online CPUs
|
|
int GetCpuCount();
|
|
|
|
// Initialize BSP per-CPU data (call before interrupts are enabled)
|
|
void InitBsp();
|
|
|
|
// Boot all Application Processors (call after all subsystems ready)
|
|
void BootAPs();
|
|
}
|