aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-04-06 18:43:28 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-04-06 18:43:28 +0200
commitf50815110789a0f8f6e5ca66ffd49b26578791a9 (patch)
tree992b3c344e69fab4dc56872566bc7323e8892913
parent8d08b3b905d211e989848e1abf3a8ff2535836c8 (diff)
downloadteachos-f50815110789a0f8f6e5ca66ffd49b26578791a9.tar.xz
teachos-f50815110789a0f8f6e5ca66ffd49b26578791a9.zip
kernel: generalize CPU discovery
-rw-r--r--arch/x86_64/CMakeLists.txt1
-rw-r--r--arch/x86_64/kapi/acpi.cpp13
-rw-r--r--arch/x86_64/kapi/platform.cpp70
-rw-r--r--kapi/include/kapi/acpi.hpp4
-rw-r--r--kapi/include/kapi/platform.hpp37
-rw-r--r--kernel/CMakeLists.txt1
-rw-r--r--kernel/kapi/devices.cpp11
-rw-r--r--kernel/kapi/platform.cpp32
-rw-r--r--kernel/src/devices/cpu.cpp58
9 files changed, 147 insertions, 80 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt
index 62a2aad..87cb98c 100644
--- a/arch/x86_64/CMakeLists.txt
+++ b/arch/x86_64/CMakeLists.txt
@@ -19,6 +19,7 @@ target_sources("x86_64" PRIVATE
"kapi/devices.cpp"
"kapi/interrupts.cpp"
"kapi/memory.cpp"
+ "kapi/platform.cpp"
"kapi/system.cpp"
# CPU Initialization
diff --git a/arch/x86_64/kapi/acpi.cpp b/arch/x86_64/kapi/acpi.cpp
index 9766154..ec38aee 100644
--- a/arch/x86_64/kapi/acpi.cpp
+++ b/arch/x86_64/kapi/acpi.cpp
@@ -1,16 +1,9 @@
#include "kapi/acpi.hpp"
-#include "kapi/devices.hpp"
-#include "kapi/memory.hpp"
-
#include "arch/boot/boot.hpp"
-#include "arch/devices/local_apic.hpp"
#include <kstd/memory>
-#include <cstddef>
-#include <cstdint>
-
namespace kapi::acpi
{
@@ -34,10 +27,4 @@ namespace kapi::acpi
return kstd::make_observer(system_description_pointer);
}
- auto create_local_interrupt_controller(std::size_t major, std::size_t minor, std::uint64_t hardware_id,
- memory::physical_address address) -> kstd::unique_ptr<devices::device>
- {
- return kstd::make_unique<arch::devices::local_apic>(major, minor, hardware_id, address);
- }
-
} // namespace kapi::acpi \ No newline at end of file
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
diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp
index 5d55d08..75b6c48 100644
--- a/kapi/include/kapi/acpi.hpp
+++ b/kapi/include/kapi/acpi.hpp
@@ -1,7 +1,6 @@
#ifndef TEACHOS_KAPI_ACPI_HPP
#define TEACHOS_KAPI_ACPI_HPP
-#include "kapi/devices.hpp"
#include "kapi/memory.hpp"
#include <kstd/memory>
@@ -128,9 +127,6 @@ namespace kapi::acpi
auto get_root_pointer() -> kstd::observer_ptr<root_system_description_pointer const>;
- auto create_local_interrupt_controller(std::size_t major, std::size_t minor, std::uint64_t hardware_id,
- memory::physical_address address) -> kstd::unique_ptr<devices::device>;
-
//! @}
} // namespace kapi::acpi
diff --git a/kapi/include/kapi/platform.hpp b/kapi/include/kapi/platform.hpp
new file mode 100644
index 0000000..6aae795
--- /dev/null
+++ b/kapi/include/kapi/platform.hpp
@@ -0,0 +1,37 @@
+#ifndef TEACHOS_KAPI_PLATFORM_HPP
+#define TEACHOS_KAPI_PLATFORM_HPP
+
+#include "kapi/devices.hpp"
+
+#include <kstd/memory>
+
+#include <cstddef>
+#include <cstdint>
+
+namespace kapi::platform
+{
+
+ //! @addtogroup kapi-platform-kernel-defined
+ //! @{
+
+ auto cpu_detected(kapi::devices::bus & bus, std::uint64_t hardware_id, bool is_bsp) -> bool;
+
+ //! @}
+
+ //! @addtogroup kapi-platform-platform-defined
+ //! @{
+
+ //! 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_cpu_topology(kapi::devices::bus & bus) -> bool;
+
+ auto create_core_interrupt_controller(std::size_t major, std::size_t minor, std::uint64_t hardware_id)
+ -> kstd::unique_ptr<devices::device>;
+
+ //! @}
+
+} // namespace kapi::platform
+
+#endif \ No newline at end of file
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index 6e081bd..22513ea 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -9,6 +9,7 @@ add_library("kernel_objs" OBJECT
"kapi/devices/device.cpp"
"kapi/interrupts.cpp"
"kapi/memory.cpp"
+ "kapi/platform.cpp"
"kapi/system.cpp"
# KSTD OS Implementation
diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp
index b2911b0..dad1fe4 100644
--- a/kernel/kapi/devices.cpp
+++ b/kernel/kapi/devices.cpp
@@ -1,6 +1,5 @@
#include "kapi/devices.hpp"
-#include "kapi/acpi.hpp"
#include "kapi/system.hpp"
#include "kernel/devices/cpu.hpp"
@@ -38,13 +37,9 @@ namespace kapi::devices
register_device(bus);
bus.init();
- auto madt = kapi::acpi::get_table("APIC");
- if (madt)
- {
- auto cpu_major = allocate_major_number();
- auto cpu = kstd::make_unique<kernel::devices::cpu>(cpu_major);
- bus.add_child(std::move(cpu));
- }
+ auto cpu_major = allocate_major_number();
+ auto cpu = kstd::make_unique<kernel::devices::cpu>(cpu_major);
+ bus.add_child(std::move(cpu));
}
auto get_root_bus() -> bus &
diff --git a/kernel/kapi/platform.cpp b/kernel/kapi/platform.cpp
new file mode 100644
index 0000000..deb72de
--- /dev/null
+++ b/kernel/kapi/platform.cpp
@@ -0,0 +1,32 @@
+#include "kapi/platform.hpp"
+
+#include "kapi/devices.hpp"
+
+#include "kernel/devices/cpu.hpp"
+
+#include <kstd/memory>
+
+#include <cstdint>
+#include <utility>
+
+namespace kapi::platform
+{
+
+ auto cpu_detected(kapi::devices::bus & bus, std::uint64_t hardware_id, bool is_bsp) -> 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 core = kstd::make_unique<kernel::devices::cpu::core>(core_major, core_index, hardware_id, is_bsp);
+ auto lapic = kapi::platform::create_core_interrupt_controller(interrupt_controller_major, core_index, hardware_id);
+
+ core->add_child(std::move(lapic));
+ bus.add_child(std::move(core));
+
+ ++core_index;
+
+ return true;
+ }
+
+} // namespace kapi::platform \ No newline at end of file
diff --git a/kernel/src/devices/cpu.cpp b/kernel/src/devices/cpu.cpp
index 7147368..eb10d74 100644
--- a/kernel/src/devices/cpu.cpp
+++ b/kernel/src/devices/cpu.cpp
@@ -1,64 +1,16 @@
#include "kernel/devices/cpu.hpp"
-#include "kapi/acpi.hpp"
#include "kapi/devices.hpp"
+#include "kapi/platform.hpp"
-#include <kstd/memory>
#include <kstd/print>
#include <cstddef>
#include <cstdint>
-#include <utility>
namespace kernel::devices
{
- namespace
- {
-
- auto process_madt(kstd::observer_ptr<kapi::acpi::madt_header const> 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<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_index = 0;
-
- 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 apic_id = local_apic->apic_id();
- auto core = kstd::make_unique<kernel::devices::cpu::core>(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}
@@ -81,16 +33,12 @@ namespace kernel::devices
auto cpu::probe() -> bool
{
- auto madt = kapi::acpi::get_table("APIC");
- if (!madt)
+ if (!kapi::platform::discover_cpu_topology(*this))
{
- kstd::println("[OS:DEV] Failed to find ACPI APIC table");
+ kstd::println("[OS:DEV] Failed to discover CPU topology");
return false;
}
- auto madt_header = static_cast<kapi::acpi::madt_header const *>(madt.get());
- process_madt(kstd::make_observer(madt_header), *this);
-
return true;
}