diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-04-06 19:04:40 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-04-06 19:04:40 +0200 |
| commit | fe26083101537df306153e7bea7c291a041897f7 (patch) | |
| tree | 0f26687fb172fc1852e9c4d58c351a76e9ceb50c /arch/x86_64/kapi/platform.cpp | |
| parent | 2a3575a267dede6a364386c0bd6edcff92421f0d (diff) | |
| parent | d5c2e101d62f6b4b69c45c127e7a729d246da566 (diff) | |
| download | teachos-fe26083101537df306153e7bea7c291a041897f7.tar.xz teachos-fe26083101537df306153e7bea7c291a041897f7.zip | |
Merge branch 'fmorgner/develop-BA-FS26/apci' into develop-BA-FS26
This patchset introduces basic support for ACPI. Currently, the only
user of that support is the CPU discovery subsystem. It uses the
processed ACPI information to initialize CPU core devices and their
associated local APICs.
Diffstat (limited to 'arch/x86_64/kapi/platform.cpp')
| -rw-r--r-- | arch/x86_64/kapi/platform.cpp | 71 |
1 files changed, 71 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..380fc66 --- /dev/null +++ b/arch/x86_64/kapi/platform.cpp @@ -0,0 +1,71 @@ +#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 <utility> + +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 static const core_major = kapi::devices::allocate_major_number(); + auto static const interrupt_controller_major = kapi::devices::allocate_major_number(); + auto static core_index = 0uz; + + 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; + + auto lapic = kstd::make_unique<arch::devices::local_apic>(interrupt_controller_major, core_index, + local_apic->apic_id(), default_lapic_address); + if (kapi::platform::cpu_detected(bus, core_major, core_index, local_apic->processor_id(), is_bsp, + std::move(lapic))) + { + ++core_count; + } + } + } + + current += sub_table->length(); + } + + kstd::println("[x86_64:PLT] Found {} CPU cores", core_count); + + return core_count > 0; + } + +} // namespace kapi::platform
\ No newline at end of file |
