From dd8dfa3e674d05927e9ed4b7efcb634a634bfdcc Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 10 Apr 2026 10:30:32 +0200 Subject: kapi: move CPU to kapi --- arch/x86_64/include/arch/cpu/initialization.hpp | 5 ++- arch/x86_64/kapi/cpu.cpp | 26 ++++++++------ kapi/include/kapi/cpu.hpp | 16 +-------- kapi/include/kapi/devices.hpp | 1 + kapi/include/kapi/devices/cpu.hpp | 37 ++++++++++++++++++++ kernel/CMakeLists.txt | 2 +- kernel/include/kernel/devices/cpu.hpp | 33 ------------------ kernel/kapi/cpu.cpp | 19 ----------- kernel/kapi/devices.cpp | 7 ++-- kernel/kapi/devices/cpu.cpp | 31 +++++++++++++++++ kernel/src/devices/cpu.cpp | 45 ------------------------- kernel/src/test_support/kapi/cpu.cpp | 3 +- 12 files changed, 93 insertions(+), 132 deletions(-) create mode 100644 kapi/include/kapi/devices/cpu.hpp delete mode 100644 kernel/include/kernel/devices/cpu.hpp create mode 100644 kernel/kapi/devices/cpu.cpp delete mode 100644 kernel/src/devices/cpu.cpp diff --git a/arch/x86_64/include/arch/cpu/initialization.hpp b/arch/x86_64/include/arch/cpu/initialization.hpp index 71186d4..564c544 100644 --- a/arch/x86_64/include/arch/cpu/initialization.hpp +++ b/arch/x86_64/include/arch/cpu/initialization.hpp @@ -1,4 +1,5 @@ -#pragma once +#ifndef TEACHOS_ARCH_X86_64_CPU_INITIALIZATION_HPP +#define TEACHOS_ARCH_X86_64_CPU_INITIALIZATION_HPP namespace arch::cpu { @@ -7,3 +8,5 @@ namespace arch::cpu auto initialize_legacy_interrupts() -> void; } // namespace arch::cpu + +#endif diff --git a/arch/x86_64/kapi/cpu.cpp b/arch/x86_64/kapi/cpu.cpp index 1382e08..726ec6a 100644 --- a/arch/x86_64/kapi/cpu.cpp +++ b/arch/x86_64/kapi/cpu.cpp @@ -2,6 +2,7 @@ #include "kapi/acpi.hpp" #include "kapi/devices.hpp" +#include "kapi/devices/cpu.hpp" #include "kapi/system.hpp" #include "arch/cpu/initialization.hpp" @@ -42,8 +43,9 @@ namespace kapi::cpu __builtin_unreachable(); } - auto discover_topology(kapi::devices::bus & bus) -> bool + auto discover_topology() -> bool { + auto static const cpu_major = kapi::devices::allocate_major_number(); auto static const core_major = kapi::devices::allocate_major_number(); auto static const interrupt_controller_major = kapi::devices::allocate_major_number(); @@ -54,10 +56,6 @@ namespace kapi::cpu return false; } - auto bsp_found = false; - auto core_count = 0uz; - auto local_apic_address = madt->local_interrupt_controller_address(); - 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) { @@ -66,18 +64,24 @@ namespace kapi::cpu return static_cast(entry.active_flags() & candidate_flags); }); + auto bsp_found = false; + auto core_count = 0uz; + auto local_apic_address = madt->local_interrupt_controller_address(); + auto cpu_bus = kstd::make_unique(cpu_major, 0); + for (auto const & apic : lapic_entries) { auto is_bsp = !bsp_found; bsp_found = true; - auto instance = kstd::make_unique(interrupt_controller_major, core_count, - apic.apic_id(), local_apic_address, is_bsp); - if (core_detected(bus, core_major, core_count, apic.processor_id(), is_bsp, std::move(instance))) - { - ++core_count; - } + auto core = kstd::make_unique(core_major, core_count, apic.processor_id(), is_bsp); + core->add_child(kstd::make_unique(interrupt_controller_major, core_count, + apic.apic_id(), local_apic_address, is_bsp)); + cpu_bus->add_child(std::move(core)); + ++core_count; } + devices::get_root_bus().add_child(std::move(cpu_bus)); + kstd::println("[x86_64:PLT] Found {} CPU cores", core_count); return core_count > 0; } diff --git a/kapi/include/kapi/cpu.hpp b/kapi/include/kapi/cpu.hpp index c643cd7..e736be1 100644 --- a/kapi/include/kapi/cpu.hpp +++ b/kapi/include/kapi/cpu.hpp @@ -1,13 +1,11 @@ #ifndef TEACHOS_KAPI_CPU_HPP #define TEACHOS_KAPI_CPU_HPP -#include "kapi/devices.hpp" #include "kapi/memory.hpp" #include #include -#include #include namespace kapi::cpu @@ -75,17 +73,6 @@ namespace kapi::cpu //! @return Whether the exception was handled. [[nodiscard]] auto dispatch(exception const & context) -> bool; - //! A hook that is called when the platform detects a CPU core during topology discovery. - //! - //! @param bus The bus the CPU was detected on. - //! @param major The major number of the CPU device. - //! @param minor The minor number of the CPU device. - //! @param hardware_id The hardware specific ID of the CPU core. - //! @param is_bsp Whether the reported CPU is the the bootstrap processor. - //! @param core_interrupt_controller The local interrupt controller of this CPU core. - auto core_detected(kapi::devices::bus & bus, std::size_t major, std::size_t minor, std::uint64_t hardware_id, - bool is_bsp, kstd::unique_ptr core_interrupt_controller) -> bool; - //! @} //! @addtogroup kapi-cpu-platform-defined @@ -104,9 +91,8 @@ namespace kapi::cpu //! Discover the CPU topology of the platform and attach it to the given CPU bus. //! - //! @param bus The bus to attach the CPU topology to. //! @return true iff. the CPU topology was discovered successfully, false otherwise. - auto discover_topology(kapi::devices::bus & bus) -> bool; + auto discover_topology() -> bool; //! @} diff --git a/kapi/include/kapi/devices.hpp b/kapi/include/kapi/devices.hpp index c26efb9..ec154a5 100644 --- a/kapi/include/kapi/devices.hpp +++ b/kapi/include/kapi/devices.hpp @@ -2,6 +2,7 @@ #define TEACHOS_KAPI_DEVICES_HPP #include "kapi/devices/bus.hpp" // IWYU pragma: export +#include "kapi/devices/cpu.hpp" // IWYU pragma: export #include "kapi/devices/device.hpp" // IWYU pragma: export #include "kapi/devices/manager.hpp" // IWYU pragma: export diff --git a/kapi/include/kapi/devices/cpu.hpp b/kapi/include/kapi/devices/cpu.hpp new file mode 100644 index 0000000..00766b5 --- /dev/null +++ b/kapi/include/kapi/devices/cpu.hpp @@ -0,0 +1,37 @@ +#ifndef TEACHOS_KAPI_DEVICES_CPU_HPP +#define TEACHOS_KAPI_DEVICES_CPU_HPP + +#include "kapi/devices/bus.hpp" + +#include +#include + +namespace kapi::devices +{ + + //! A virtual CPU bus to host all CPUs in the system. + struct cpu final : kapi::devices::bus + { + //! A virtual CPU Core to host all core local devices. + struct core final : kapi::devices::bus + { + explicit core(std::size_t major_number, std::size_t minor_number, std::uint64_t hardware_id, bool is_bsp); + + [[nodiscard]] auto hardware_id() const -> std::uint64_t; + [[nodiscard]] auto is_bsp() const -> bool; + + private: + std::uint64_t m_hardware_id; + bool m_is_bsp; + }; + + //! Create a new CPU with the given major and minor numbers. + //! + //! @param major The major number of this CPU + //! @param minor The minor number of this CPU, identifying the physical CPU + cpu(std::size_t major, std::size_t minor); + }; + +} // namespace kapi::devices + +#endif \ No newline at end of file diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index ca8fae7..b9e01eb 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -9,6 +9,7 @@ add_library("kernel_objs" OBJECT "kapi/cpu.cpp" "kapi/devices.cpp" "kapi/devices/bus.cpp" + "kapi/devices/cpu.cpp" "kapi/devices/device.cpp" "kapi/interrupts.cpp" "kapi/memory.cpp" @@ -26,7 +27,6 @@ add_library("kernel_objs" OBJECT "src/memory.cpp" "src/devices/block_device.cpp" "src/devices/block_device_utils.cpp" - "src/devices/cpu.cpp" "src/devices/root_bus.cpp" "src/devices/storage/controller.cpp" "src/devices/storage/management.cpp" diff --git a/kernel/include/kernel/devices/cpu.hpp b/kernel/include/kernel/devices/cpu.hpp deleted file mode 100644 index b056665..0000000 --- a/kernel/include/kernel/devices/cpu.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef TEACHOS_KERNEL_DEVICES_CPU_HPP -#define TEACHOS_KERNEL_DEVICES_CPU_HPP - -#include "kapi/devices.hpp" - -#include -#include - -namespace kernel::devices -{ - - struct cpu final : kapi::devices::bus - { - struct core final : kapi::devices::bus - { - explicit core(std::size_t major_number, std::size_t minor_number, std::uint64_t hardware_id, bool is_bsp); - - [[nodiscard]] auto hardware_id() const -> std::uint64_t; - [[nodiscard]] auto is_bsp() const -> bool; - - private: - std::uint64_t m_hardware_id; - bool m_is_bsp; - }; - - explicit cpu(std::size_t major_number); - - auto probe() -> bool final; - }; - -} // namespace kernel::devices - -#endif \ No newline at end of file diff --git a/kernel/kapi/cpu.cpp b/kernel/kapi/cpu.cpp index d632628..13de584 100644 --- a/kernel/kapi/cpu.cpp +++ b/kernel/kapi/cpu.cpp @@ -1,17 +1,9 @@ #include "kapi/cpu.hpp" -#include "kapi/devices.hpp" #include "kapi/system.hpp" -#include "kernel/devices/cpu.hpp" - -#include #include -#include -#include -#include - namespace kapi::cpu { @@ -40,15 +32,4 @@ namespace kapi::cpu } } - auto core_detected(kapi::devices::bus & bus, std::size_t major, std::size_t minor, std::uint64_t hardware_id, - bool is_bsp, kstd::unique_ptr core_interrupt_controller) -> bool - { - auto core = kstd::make_unique(major, minor, hardware_id, is_bsp); - - core->add_child(std::move(core_interrupt_controller)); - bus.add_child(std::move(core)); - - return true; - } - } // namespace kapi::cpu \ No newline at end of file diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp index dad1fe4..b8aa44b 100644 --- a/kernel/kapi/devices.cpp +++ b/kernel/kapi/devices.cpp @@ -1,8 +1,8 @@ #include "kapi/devices.hpp" +#include "kapi/cpu.hpp" #include "kapi/system.hpp" -#include "kernel/devices/cpu.hpp" #include "kernel/devices/root_bus.hpp" #include @@ -17,7 +17,6 @@ namespace kapi::devices { - namespace { auto constinit next_major_number = std::atomic_size_t{1}; @@ -37,9 +36,7 @@ namespace kapi::devices register_device(bus); bus.init(); - auto cpu_major = allocate_major_number(); - auto cpu = kstd::make_unique(cpu_major); - bus.add_child(std::move(cpu)); + kapi::cpu::discover_topology(); } auto get_root_bus() -> bus & diff --git a/kernel/kapi/devices/cpu.cpp b/kernel/kapi/devices/cpu.cpp new file mode 100644 index 0000000..9de5f94 --- /dev/null +++ b/kernel/kapi/devices/cpu.cpp @@ -0,0 +1,31 @@ +#include "kapi/devices/cpu.hpp" + +#include "kapi/devices.hpp" + +#include +#include + +namespace kapi::devices +{ + + 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, std::size_t minor) + : kapi::devices::bus{major, minor, "cpu"} + {} + +} // namespace kapi::devices \ No newline at end of file diff --git a/kernel/src/devices/cpu.cpp b/kernel/src/devices/cpu.cpp deleted file mode 100644 index 85f4d47..0000000 --- a/kernel/src/devices/cpu.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "kernel/devices/cpu.hpp" - -#include "kapi/cpu.hpp" -#include "kapi/devices.hpp" - -#include - -#include -#include - -namespace kernel::devices -{ - - 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 - { - if (!kapi::cpu::discover_topology(*this)) - { - kstd::println("[OS:DEV] Failed to discover CPU topology"); - return false; - } - - return true; - } - -} // namespace kernel::devices \ No newline at end of file diff --git a/kernel/src/test_support/kapi/cpu.cpp b/kernel/src/test_support/kapi/cpu.cpp index a89bec8..671097e 100644 --- a/kernel/src/test_support/kapi/cpu.cpp +++ b/kernel/src/test_support/kapi/cpu.cpp @@ -1,6 +1,5 @@ #include "kernel/test_support/cpu.hpp" -#include "kapi/devices.hpp" #include #include @@ -29,7 +28,7 @@ namespace kapi::cpu throw kernel::tests::cpu::halt{}; } - auto discover_topology(devices::bus &) -> bool + auto discover_topology() -> bool { // TODO: implement more meaningful simulated CPU topology discovery return true; -- cgit v1.2.3