diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-04-06 15:10:04 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-04-06 15:11:47 +0200 |
| commit | 4d938cd31a35cd4322fe914edd568faa5391c9c2 (patch) | |
| tree | 749af894d900cbb903ba9e51853a42f0c5427594 /kernel | |
| parent | 3dcd14a0570fef3bcc68d7df42fe3ff4cd496f93 (diff) | |
| download | teachos-4d938cd31a35cd4322fe914edd568faa5391c9c2.tar.xz teachos-4d938cd31a35cd4322fe914edd568faa5391c9c2.zip | |
kernel/acpi: implement basic table discovery
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/include/kernel/acpi/manager.hpp | 5 | ||||
| -rw-r--r-- | kernel/kapi/acpi.cpp | 45 | ||||
| -rw-r--r-- | kernel/src/acpi/manager.cpp | 42 |
3 files changed, 89 insertions, 3 deletions
diff --git a/kernel/include/kernel/acpi/manager.hpp b/kernel/include/kernel/acpi/manager.hpp index fc76685..437d4c8 100644 --- a/kernel/include/kernel/acpi/manager.hpp +++ b/kernel/include/kernel/acpi/manager.hpp @@ -3,8 +3,11 @@ #include "kapi/acpi.hpp" +#include <kstd/flat_map> #include <kstd/vector> +#include <string_view> + namespace kernel::acpi { @@ -17,7 +20,7 @@ namespace kernel::acpi private: kapi::acpi::root_system_description_pointer const * m_sdp{}; kapi::acpi::system_description_table_header const * m_rsdt{}; - kstd::vector<kapi::acpi::system_description_table_header> m_tables{}; + kstd::flat_map<std::string_view, kapi::acpi::system_description_table_header const *> m_tables{}; bool m_extended{}; }; diff --git a/kernel/kapi/acpi.cpp b/kernel/kapi/acpi.cpp index 787bcff..998d7a0 100644 --- a/kernel/kapi/acpi.cpp +++ b/kernel/kapi/acpi.cpp @@ -65,6 +65,51 @@ namespace kapi::acpi return validate_checksum({reinterpret_cast<std::byte const *>(this), m_length}); } + [[nodiscard]] auto system_description_table_header::checksum() const noexcept -> std::uint8_t + { + return m_checksum; + } + + [[nodiscard]] auto system_description_table_header::creator_revision() const noexcept -> std::uint32_t + { + return m_creator_revision; + } + + [[nodiscard]] auto system_description_table_header::creator_id() const noexcept -> std::uint32_t + { + return m_creator_id; + } + + [[nodiscard]] auto system_description_table_header::length() const noexcept -> kstd::units::bytes + { + return kstd::units::bytes{m_length}; + } + + [[nodiscard]] auto system_description_table_header::oem_id() const noexcept -> std::string_view + { + return {m_oem_id.data(), m_oem_id.size()}; + } + + [[nodiscard]] auto system_description_table_header::oem_revision() const noexcept -> std::uint32_t + { + return m_oem_revision; + } + + [[nodiscard]] auto system_description_table_header::oem_table_id() const noexcept -> std::string_view + { + return {m_oem_table_id.data(), m_oem_table_id.size()}; + } + + [[nodiscard]] auto system_description_table_header::revision() const noexcept -> std::uint8_t + { + return m_revision; + } + + [[nodiscard]] auto system_description_table_header::signature() const noexcept -> std::string_view + { + return {m_signature.data(), m_signature.size()}; + } + auto init(root_system_description_pointer const & sdp) -> bool { auto static constinit initialized = std::atomic_flag{}; diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 6a17920..180d458 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -4,7 +4,10 @@ #include "kapi/memory.hpp" #include "kapi/system.hpp" +#include <kstd/print> + #include <cstddef> +#include <cstdint> namespace kernel::acpi { @@ -43,12 +46,47 @@ namespace kernel::acpi auto manager::load_tables() -> bool { - if (!kapi::acpi::validate_checksum({reinterpret_cast<std::byte const *>(m_rsdt), m_rsdt->length})) + if (!kapi::acpi::validate_checksum({reinterpret_cast<std::byte const *>(m_rsdt), m_rsdt->length().value})) { kapi::system::panic("[OS:ACPI] Invalid RSDT checksum!"); } - return false; + auto entry_size = m_extended ? sizeof(std::uint64_t) : sizeof(std::uint32_t); + auto entry_count = (m_rsdt->length().value - sizeof(kapi::acpi::system_description_table_header)) / entry_size; + auto entries_base = + reinterpret_cast<std::byte const *>(m_rsdt) + sizeof(kapi::acpi::system_description_table_header); + + for (std::size_t i = 0; i < entry_count; ++i) + { + auto physical_table_address = kapi::memory::physical_address{}; + + if (m_extended) + { + auto entry = reinterpret_cast<std::uint64_t const *>(entries_base + (i * entry_size)); + physical_table_address = kapi::memory::physical_address{*entry}; + } + else + { + auto entry = reinterpret_cast<std::uint32_t const *>(entries_base + (i * entry_size)); + physical_table_address = kapi::memory::physical_address{*entry}; + } + + auto linear_table_address = kapi::memory::hhdm_to_linear(physical_table_address); + auto table = static_cast<kapi::acpi::system_description_table_header const *>(linear_table_address); + + if (!kapi::acpi::validate_checksum({reinterpret_cast<std::byte const *>(table), table->length().value})) + { + kstd::println(kstd::print_sink::stderr, "[OS:ACPI] Invalid table checksum!"); + } + else + { + kstd::println("[OS:ACPI] Found table: {}@{:#x}/{:#x} OEM: {} Rev: {}", table->signature(), linear_table_address, + physical_table_address, table->oem_id(), table->creator_revision()); + m_tables.emplace(table->signature(), table); + } + } + + return !m_tables.empty(); } } // namespace kernel::acpi |
