aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/kapi/platform.cpp49
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;
}