aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/kapi/platform.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/kapi/platform.cpp')
-rw-r--r--arch/x86_64/kapi/platform.cpp70
1 files changed, 70 insertions, 0 deletions
diff --git a/arch/x86_64/kapi/platform.cpp b/arch/x86_64/kapi/platform.cpp
new file mode 100644
index 0000000..2e7c7e4
--- /dev/null
+++ b/arch/x86_64/kapi/platform.cpp
@@ -0,0 +1,70 @@
+#include "kapi/platform.hpp"
+
+#include "kapi/acpi.hpp"
+#include "kapi/devices.hpp"
+#include "kapi/memory.hpp"
+
+#include "arch/devices/local_apic.hpp"
+
+#include <kstd/memory>
+#include <kstd/print>
+
+#include <cstddef>
+#include <cstdint>
+
+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<std::byte const *>(madt.get()) + sizeof(kapi::acpi::madt_header);
+ auto const * end = reinterpret_cast<std::byte const *>(madt.get()) + madt->length();
+
+ auto bsp_found = false;
+ auto core_count = 0uz;
+
+ while (current < end)
+ {
+ auto const * sub_table = reinterpret_cast<kapi::acpi::madt_subtable_header const *>(current);
+ if (sub_table->type() == 0)
+ {
+ 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;
+
+ 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<devices::device>
+ {
+ return kstd::make_unique<arch::devices::local_apic>(major, minor, hardware_id, default_lapic_address);
+ }
+
+} // namespace kapi::platform \ No newline at end of file