#include "kapi/platform.hpp" #include "kapi/acpi.hpp" #include "kapi/devices.hpp" #include "arch/devices/local_apic.hpp" #include #include #include #include namespace kapi::platform { auto discover_cpu_topology(kapi::devices::bus & bus) -> bool { auto static const core_major = kapi::devices::allocate_major_number(); auto static const interrupt_controller_major = kapi::devices::allocate_major_number(); auto static core_index = 0uz; auto madt = kapi::acpi::get_table("APIC"); if (!madt) { kstd::println("[x86_64:PLT] Failed to find ACPI APIC table"); return false; } auto real_madt = static_cast(madt.get()); auto current = reinterpret_cast(madt.get()) + sizeof(kapi::acpi::madt_header); auto end = reinterpret_cast(madt.get()) + madt->length(); auto bsp_found = false; auto core_count = 0uz; while (current < end) { auto const * sub_table = reinterpret_cast(current); if (sub_table->type() == 0) { auto const * local_apic = reinterpret_cast(sub_table); if (local_apic->flags() & 0b11) { auto is_bsp = !bsp_found; bsp_found = true; auto lapic = kstd::make_unique(interrupt_controller_major, core_index, local_apic->apic_id(), real_madt->local_interrupt_controller_address()); if (kapi::platform::cpu_detected(bus, core_major, core_index, local_apic->processor_id(), is_bsp, std::move(lapic))) { ++core_count; } } } current += sub_table->length(); } kstd::println("[x86_64:PLT] Found {} CPU cores", core_count); return core_count > 0; } } // namespace kapi::platform