#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 { namespace { constexpr auto candidate_flags = acpi::processor_local_apic::flags::processor_enabled // | acpi::processor_local_apic::flags::online_capable; } 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 madt = kapi::acpi::get_table(); if (!madt) { kstd::println("[x86_64:PLT] Failed to find ACPI APIC table"); return false; } auto bsp_found = false; auto core_count = 0uz; auto local_apic_address = madt->local_interrupt_controller_address(); auto lapic_entries = *madt | std::views::filter([](auto const & entry) { return entry.type() == acpi::multiple_apic_description_table_entry::types::processor_local_apic; }) | std::views::transform([](auto const & entry) { return static_cast(entry); }) | std::views::filter([](auto const & entry) { return static_cast(entry.active_flags() & candidate_flags); }); for (auto const & apic : lapic_entries) { auto is_bsp = !bsp_found; bsp_found = true; auto instance = kstd::make_unique(interrupt_controller_major, core_count, apic.apic_id(), local_apic_address, is_bsp); if (kapi::platform::cpu_detected(bus, core_major, core_count, apic.processor_id(), is_bsp, std::move(instance))) { ++core_count; } } kstd::println("[x86_64:PLT] Found {} CPU cores", core_count); return core_count > 0; } } // namespace kapi::platform