#include "kernel/devices/cpu.hpp" #include "kapi/acpi.hpp" #include "kapi/devices.hpp" #include #include #include #include #include namespace kernel::devices { namespace { auto process_madt(kstd::observer_ptr madt, kapi::devices::bus & cpu) -> void { auto static const core_major = kapi::devices::allocate_major_number(); auto static const lapic_major = kapi::devices::allocate_major_number(); auto lapic_address = madt->local_interrupt_controller_address(); 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_index = 0; 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; auto apic_id = local_apic->apic_id(); auto core = kstd::make_unique(core_major, core_index, apic_id, is_bsp); auto lapic = kapi::acpi::create_local_interrupt_controller(lapic_major, core_index, apic_id, lapic_address); core->add_child(std::move(lapic)); cpu.add_child(std::move(core)); ++core_index; } } current += sub_table->length(); } kstd::println("[OS:DEV] Discovered {} CPU cores", core_index); } } // namespace cpu::core::core(std::size_t major_number, std::size_t minor_number, std::uint64_t hardware_id, bool is_bsp) : kapi::devices::bus{major_number, minor_number, "cpu_core"} , m_hardware_id{hardware_id} , m_is_bsp{is_bsp} {} auto cpu::core::hardware_id() const -> std::uint64_t { return m_hardware_id; } auto cpu::core::is_bsp() const -> bool { return m_is_bsp; } cpu::cpu(std::size_t major_number) : kapi::devices::bus{major_number, 0, "cpu"} {} auto cpu::probe() -> bool { auto madt = kapi::acpi::get_table("APIC"); if (!madt) { kstd::println("[OS:DEV] Failed to find ACPI APIC table"); return false; } auto madt_header = static_cast(madt.get()); process_madt(kstd::make_observer(madt_header), *this); return true; } } // namespace kernel::devices