#include "kapi/platform.hpp" #include "kapi/acpi.hpp" #include "kapi/devices.hpp" #include "kapi/memory.hpp" #include "arch/devices/local_apic.hpp" #include #include #include #include namespace kapi::platform { namespace { constexpr auto default_lapic_address = kapi::memory::physical_address{0xFEE0'0000}; } auto discover_cpu_topology(kapi::devices::bus & bus) -> bool { auto madt = kapi::acpi::get_table("APIC"); if (!madt) { kstd::println("[x86_64:PLT] Failed to find ACPI APIC table"); return false; } auto const * current = reinterpret_cast(madt.get()) + sizeof(kapi::acpi::madt_header); auto const * 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; if (kapi::platform::cpu_detected(bus, local_apic->processor_id(), is_bsp)) { ++core_count; } } } current += sub_table->length(); } kstd::println("[x86_64:PLT] Found {} CPU cores", core_count); return core_count > 0; } auto create_core_interrupt_controller(std::size_t major, std::size_t minor, std::uint64_t hardware_id) -> kstd::unique_ptr { return kstd::make_unique(major, minor, hardware_id, default_lapic_address); } } // namespace kapi::platform