aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/CMakeLists.txt4
-rw-r--r--arch/x86_64/include/arch/devices/init.hpp12
-rw-r--r--arch/x86_64/include/arch/devices/local_apic.hpp26
-rw-r--r--arch/x86_64/kapi/acpi.cpp30
-rw-r--r--arch/x86_64/kapi/devices.cpp27
-rw-r--r--arch/x86_64/kapi/platform.cpp71
-rw-r--r--arch/x86_64/src/devices/init.cpp39
-rw-r--r--arch/x86_64/src/devices/local_apic.cpp28
8 files changed, 213 insertions, 24 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt
index 83cae0b..87cb98c 100644
--- a/arch/x86_64/CMakeLists.txt
+++ b/arch/x86_64/CMakeLists.txt
@@ -12,12 +12,14 @@ target_link_libraries("x86_64" PUBLIC
target_sources("x86_64" PRIVATE
# Platform-dependent KAPI implementation
+ "kapi/acpi.cpp"
"kapi/boot_modules.cpp"
"kapi/cio.cpp"
"kapi/cpu.cpp"
"kapi/devices.cpp"
"kapi/interrupts.cpp"
"kapi/memory.cpp"
+ "kapi/platform.cpp"
"kapi/system.cpp"
# CPU Initialization
@@ -38,7 +40,9 @@ target_sources("x86_64" PRIVATE
"src/debug/qemu_output.cpp"
# Devices
+ "src/devices/init.cpp"
"src/devices/legacy_pit.cpp"
+ "src/devices/local_apic.cpp"
# Memory management
"src/memory/kernel_mapper.cpp"
diff --git a/arch/x86_64/include/arch/devices/init.hpp b/arch/x86_64/include/arch/devices/init.hpp
new file mode 100644
index 0000000..c5fbf37
--- /dev/null
+++ b/arch/x86_64/include/arch/devices/init.hpp
@@ -0,0 +1,12 @@
+#ifndef TEACHOS_ARCH_X86_64_DEVICES_INIT_HPP
+#define TEACHOS_ARCH_X86_64_DEVICES_INIT_HPP
+
+namespace arch::devices
+{
+
+ auto init_acpi_devices() -> void;
+ auto init_legacy_devices() -> void;
+
+} // namespace arch::devices
+
+#endif \ No newline at end of file
diff --git a/arch/x86_64/include/arch/devices/local_apic.hpp b/arch/x86_64/include/arch/devices/local_apic.hpp
new file mode 100644
index 0000000..71e9758
--- /dev/null
+++ b/arch/x86_64/include/arch/devices/local_apic.hpp
@@ -0,0 +1,26 @@
+#ifndef TEACHOS_ARCH_X86_64_DEVICES_LOCAL_APIC_HPP
+#define TEACHOS_ARCH_X86_64_DEVICES_LOCAL_APIC_HPP
+
+#include "kapi/devices/device.hpp"
+#include "kapi/memory.hpp"
+
+#include <cstddef>
+#include <cstdint>
+
+namespace arch::devices
+{
+
+ struct local_apic : kapi::devices::device
+ {
+ local_apic(std::size_t major, std::size_t minor, std::uint64_t hardware_id, kapi::memory::physical_address base);
+
+ auto init() -> bool override;
+
+ private:
+ std::uint64_t m_hardware_id{};
+ kapi::memory::physical_address m_base{};
+ };
+
+} // namespace arch::devices
+
+#endif \ No newline at end of file
diff --git a/arch/x86_64/kapi/acpi.cpp b/arch/x86_64/kapi/acpi.cpp
new file mode 100644
index 0000000..ec38aee
--- /dev/null
+++ b/arch/x86_64/kapi/acpi.cpp
@@ -0,0 +1,30 @@
+#include "kapi/acpi.hpp"
+
+#include "arch/boot/boot.hpp"
+
+#include <kstd/memory>
+
+namespace kapi::acpi
+{
+
+ auto get_root_pointer() -> kstd::observer_ptr<root_system_description_pointer const>
+ {
+ auto const & mbi = kapi::boot::bootstrap_information.mbi;
+ auto system_description_pointer = static_cast<kapi::acpi::root_system_description_pointer const *>(nullptr);
+
+ if (auto const & xsdp = mbi->maybe_acpi_xsdp())
+ {
+ auto data = xsdp->pointer().data();
+
+ system_description_pointer = reinterpret_cast<kapi::acpi::root_system_description_pointer const *>(data);
+ }
+ else if (auto const & rsdp = mbi->maybe_acpi_rsdp())
+ {
+ auto data = rsdp->pointer().data();
+ system_description_pointer = reinterpret_cast<kapi::acpi::root_system_description_pointer const *>(data);
+ }
+
+ return kstd::make_observer(system_description_pointer);
+ }
+
+} // namespace kapi::acpi \ No newline at end of file
diff --git a/arch/x86_64/kapi/devices.cpp b/arch/x86_64/kapi/devices.cpp
index b15503d..47c7f8c 100644
--- a/arch/x86_64/kapi/devices.cpp
+++ b/arch/x86_64/kapi/devices.cpp
@@ -1,35 +1,14 @@
#include "kapi/devices.hpp"
-#include "arch/bus/isa.hpp"
-#include "arch/devices/legacy_pit.hpp"
-
-#include <kstd/memory>
-#include <kstd/print>
-
-#include <cstdint>
-#include <utility>
+#include "arch/devices/init.hpp"
namespace kapi::devices
{
- namespace
- {
- constexpr auto pit_frequency_in_hz = std::uint32_t{100u};
- }
-
auto init_platform_devices() -> void
{
- kstd::println("[x86_64:devices] Initializing ISA bus...");
-
- auto isa_major_number = kapi::devices::allocate_major_number();
- auto isa_bus = kstd::make_unique<arch::bus::isa>(isa_major_number);
-
- auto pit_major_number = kapi::devices::allocate_major_number();
- auto pit = kstd::make_unique<arch::devices::legacy_pit>(pit_major_number, pit_frequency_in_hz);
- isa_bus->add_child(std::move(pit));
-
- auto & root_bus = get_root_bus();
- root_bus.add_child(std::move(isa_bus));
+ arch::devices::init_acpi_devices();
+ arch::devices::init_legacy_devices();
}
} // namespace kapi::devices \ 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..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
diff --git a/arch/x86_64/src/devices/init.cpp b/arch/x86_64/src/devices/init.cpp
new file mode 100644
index 0000000..6cba986
--- /dev/null
+++ b/arch/x86_64/src/devices/init.cpp
@@ -0,0 +1,39 @@
+#include "arch/devices/init.hpp"
+
+#include "kapi/devices.hpp"
+
+#include "arch/bus/isa.hpp"
+#include "arch/devices/legacy_pit.hpp"
+
+#include <kstd/memory>
+#include <kstd/print>
+
+#include <cstdint>
+#include <utility>
+
+namespace arch::devices
+{
+
+ namespace
+ {
+ constexpr auto pit_frequency_in_hz = std::uint32_t{100u};
+ }
+
+ auto init_acpi_devices() -> void {}
+
+ auto init_legacy_devices() -> void
+ {
+ kstd::println("[x86_64:DEV] Initializing ISA bus...");
+
+ auto isa_major_number = kapi::devices::allocate_major_number();
+ auto isa_bus = kstd::make_unique<arch::bus::isa>(isa_major_number);
+
+ auto pit_major_number = kapi::devices::allocate_major_number();
+ auto pit = kstd::make_unique<arch::devices::legacy_pit>(pit_major_number, pit_frequency_in_hz);
+ isa_bus->add_child(std::move(pit));
+
+ auto & root_bus = kapi::devices::get_root_bus();
+ root_bus.add_child(std::move(isa_bus));
+ }
+
+} // namespace arch::devices
diff --git a/arch/x86_64/src/devices/local_apic.cpp b/arch/x86_64/src/devices/local_apic.cpp
new file mode 100644
index 0000000..beb75ef
--- /dev/null
+++ b/arch/x86_64/src/devices/local_apic.cpp
@@ -0,0 +1,28 @@
+#include "arch/devices/local_apic.hpp"
+
+#include "kapi/devices.hpp"
+#include "kapi/memory.hpp"
+
+#include <kstd/print>
+
+#include <cstddef>
+#include <cstdint>
+
+namespace arch::devices
+{
+
+ local_apic::local_apic(std::size_t major, std::size_t minor, std::uint64_t hardware_id,
+ kapi::memory::physical_address base)
+ : kapi::devices::device{major, minor, "lapic"}
+ , m_hardware_id{hardware_id}
+ , m_base{base}
+ {}
+
+ auto local_apic::init() -> bool
+ {
+ kstd::println("[x86_64:DEV] Initializing local APIC on core {}", m_hardware_id);
+
+ return true;
+ }
+
+} // namespace arch::devices \ No newline at end of file