diff options
Diffstat (limited to 'arch/x86_64/kapi/platform.cpp')
| -rw-r--r-- | arch/x86_64/kapi/platform.cpp | 49 |
1 files changed, 23 insertions, 26 deletions
diff --git a/arch/x86_64/kapi/platform.cpp b/arch/x86_64/kapi/platform.cpp index 4ee35c7..fb27329 100644 --- a/arch/x86_64/kapi/platform.cpp +++ b/arch/x86_64/kapi/platform.cpp @@ -8,57 +8,54 @@ #include <kstd/memory> #include <kstd/print> -#include <cstddef> +#include <ranges> #include <utility> 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("APIC"); + auto madt = kapi::acpi::get_table<acpi::madt_table_signature>(); if (!madt) { kstd::println("[x86_64:PLT] Failed to find ACPI APIC table"); return false; } - auto real_madt = static_cast<acpi::madt_header const *>(madt.get()); - auto current = reinterpret_cast<std::byte const *>(madt.get()) + sizeof(kapi::acpi::madt_header); - auto end = reinterpret_cast<std::byte const *>(madt.get()) + madt->length(); - auto bsp_found = false; auto core_count = 0uz; + auto local_apic_address = madt->local_interrupt_controller_address(); - while (current < end) + 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<acpi::processor_local_apic const &>(entry); + }) | std::views::filter([](auto const & entry) { + return static_cast<bool>(entry.active_flags() & candidate_flags); + }); + + for (auto const & apic : lapic_entries) { - auto const * sub_table = reinterpret_cast<kapi::acpi::madt_subtable_header const *>(current); - if (sub_table->type() == 0) + auto is_bsp = !bsp_found; + bsp_found = true; + auto instance = kstd::make_unique<arch::devices::local_apic>(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))) { - auto const * local_apic = reinterpret_cast<kapi::acpi::madt_local_apic const *>(sub_table); - if (local_apic->flags() & 0b11) - { - auto is_bsp = !bsp_found; - bsp_found = true; - auto lapic = kstd::make_unique<arch::devices::local_apic>( - interrupt_controller_major, core_count, local_apic->apic_id(), - real_madt->local_interrupt_controller_address(), is_bsp); - if (kapi::platform::cpu_detected(bus, core_major, core_count, local_apic->processor_id(), is_bsp, - std::move(lapic))) - { - ++core_count; - } - } + ++core_count; } - - current += sub_table->length(); } kstd::println("[x86_64:PLT] Found {} CPU cores", core_count); - return core_count > 0; } |
