feat: introduce bootloader-agnostic Boot Contract, add btlist command to list connected Bluetooth devices
This commit is contained in:
+21
-23
@@ -17,11 +17,7 @@
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <CppLib/Stream.hpp>
|
||||
#include <Timekeeping/ApicTimer.hpp>
|
||||
#include <limine.h>
|
||||
|
||||
// Defined in Platform/Limine.hpp (included only by Main.cpp to avoid
|
||||
// duplicating the LIMINE_BASE_REVISION tag).
|
||||
extern volatile limine_mp_request mp_request;
|
||||
#include <Boot/BootInfo.hpp>
|
||||
#include <Libraries/Memory.hpp>
|
||||
|
||||
// Verify assembly offsets match struct layout
|
||||
@@ -153,14 +149,15 @@ namespace Smp {
|
||||
|
||||
// ====================================================================
|
||||
// AP entry point
|
||||
// Called by Limine when goto_address is written.
|
||||
// RDI = pointer to limine_mp_info for this CPU.
|
||||
// Runs on a 64KiB Limine-provided stack.
|
||||
// Invoked by the boot contract (montauk::boot::SmpInfo::startCpu) when
|
||||
// the AP is woken. Receives the BootCpu for this processor; the kernel
|
||||
// stashed this CPU's CpuData* in BootCpu::extraArgument before starting
|
||||
// it. Runs on a bootloader-provided stack.
|
||||
// ====================================================================
|
||||
|
||||
static void ApEntry(limine_mp_info* info) {
|
||||
// Find our CpuData (stored in extra_argument by BootAPs)
|
||||
CpuData* cpu = (CpuData*)info->extra_argument;
|
||||
static void ApEntry(montauk::boot::BootCpu* bootCpu) {
|
||||
// Find our CpuData (stashed in extraArgument by BootAPs)
|
||||
CpuData* cpu = (CpuData*)bootCpu->extraArgument;
|
||||
|
||||
// --- Load per-CPU GDT ---
|
||||
Hal::GDTPointer gdtPtr {
|
||||
@@ -223,17 +220,16 @@ namespace Smp {
|
||||
// Boot all APs
|
||||
// ====================================================================
|
||||
|
||||
void BootAPs() {
|
||||
if (mp_request.response == nullptr) {
|
||||
KernelLogStream(WARNING, "SMP") << "No MP response from bootloader - single CPU mode";
|
||||
void BootAPs(const montauk::boot::SmpInfo& smp) {
|
||||
if (smp.cpus == nullptr || smp.startCpu == nullptr) {
|
||||
KernelLogStream(WARNING, "SMP") << "No SMP info from bootloader - single CPU mode";
|
||||
return;
|
||||
}
|
||||
|
||||
auto* resp = mp_request.response;
|
||||
uint64_t cpuCount = resp->cpu_count;
|
||||
uint64_t cpuCount = smp.cpuCount;
|
||||
|
||||
KernelLogStream(INFO, "SMP") << "Bootloader reports " << cpuCount << " CPU(s), BSP LAPIC ID "
|
||||
<< (uint64_t)resp->bsp_lapic_id;
|
||||
<< (uint64_t)smp.bspLapicId;
|
||||
|
||||
if (cpuCount <= 1) {
|
||||
KernelLogStream(INFO, "SMP") << "Single CPU system - no APs to boot";
|
||||
@@ -251,23 +247,25 @@ namespace Smp {
|
||||
// - Each AP's init is purely local (GDT, TSS, APIC, MSRs)
|
||||
int apIndex = 1; // BSP is index 0
|
||||
for (uint64_t i = 0; i < cpuCount; i++) {
|
||||
limine_mp_info* info = resp->cpus[i];
|
||||
montauk::boot::BootCpu& info = smp.cpus[i];
|
||||
|
||||
if (info->lapic_id == resp->bsp_lapic_id) continue;
|
||||
if (info.lapicId == smp.bspLapicId) continue;
|
||||
if (apIndex >= MaxCPUs) break;
|
||||
|
||||
CpuData& ap = g_cpus[apIndex];
|
||||
ap.selfPtr = (uint64_t)≈
|
||||
ap.cpuIndex = apIndex;
|
||||
ap.lapicId = info->lapic_id;
|
||||
ap.lapicId = info.lapicId;
|
||||
ap.currentSlot = -1;
|
||||
ap.started = false;
|
||||
|
||||
SetupPerCpuGdtTss(ap);
|
||||
info->extra_argument = (uint64_t)≈
|
||||
|
||||
// Wake this AP (it runs ApEntry in parallel with other APs)
|
||||
__atomic_store_n(&info->goto_address, (limine_goto_address)ApEntry, __ATOMIC_SEQ_CST);
|
||||
// Stash this AP's CpuData* where ApEntry will recover it, then
|
||||
// ask the bootloader to wake the AP into ApEntry. APs run in
|
||||
// parallel with each other.
|
||||
info.extraArgument = (uint64_t)≈
|
||||
smp.startCpu(&info, ApEntry);
|
||||
|
||||
apIndex++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user