diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-04-16 10:17:19 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-04-16 10:17:19 +0200 |
| commit | 3c210c07c60fbe9378cfb720847e8c1d3c763ead (patch) | |
| tree | c83b1aa99dd7435a9fd033772e973ade637b464d /kernel | |
| parent | 888471f23e7f07749b4bc9a2fa70992062b6e4d0 (diff) | |
| parent | f9dde928add359a1dff0db402dc1454e72aea633 (diff) | |
| download | teachos-3c210c07c60fbe9378cfb720847e8c1d3c763ead.tar.xz teachos-3c210c07c60fbe9378cfb720847e8c1d3c763ead.zip | |
Merge branch 'fmorgner/develop-BA-FS26/acpi-refactor' into develop-BA-FS26
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/include/kernel/acpi/manager.hpp | 6 | ||||
| -rw-r--r-- | kernel/kapi/acpi.cpp | 2 | ||||
| -rw-r--r-- | kernel/src/acpi/manager.cpp | 48 |
3 files changed, 27 insertions, 29 deletions
diff --git a/kernel/include/kernel/acpi/manager.hpp b/kernel/include/kernel/acpi/manager.hpp index 420b44a..860d609 100644 --- a/kernel/include/kernel/acpi/manager.hpp +++ b/kernel/include/kernel/acpi/manager.hpp @@ -18,12 +18,12 @@ namespace kernel::acpi auto load_tables() -> bool; - auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const>; + auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::table_header const>; private: ::acpi::rsdp const * m_sdp{}; - ::acpi::sdt const * m_rsdt{}; - kstd::flat_map<std::string_view, ::acpi::sdt const *> m_tables{}; + ::acpi::table_header const * m_rsdt{}; + kstd::flat_map<std::string_view, ::acpi::table_header const *> m_tables{}; bool m_extended{}; }; diff --git a/kernel/kapi/acpi.cpp b/kernel/kapi/acpi.cpp index df2bf05..5a2f227 100644 --- a/kernel/kapi/acpi.cpp +++ b/kernel/kapi/acpi.cpp @@ -32,7 +32,7 @@ namespace kapi::acpi return manager->load_tables(); } - auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const> + auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::table_header const> { return manager->get_table(signature); } diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 501ce92..5876799 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -8,8 +8,10 @@ #include <acpi/acpi.hpp> +#include <algorithm> #include <cstddef> #include <cstdint> +#include <ranges> #include <string_view> namespace kernel::acpi @@ -32,7 +34,7 @@ namespace kernel::acpi } auto physical_extended_table_address = kapi::memory::physical_address{xsdp->table_address()}; auto linear_extended_table_address = kapi::memory::hhdm_to_linear(physical_extended_table_address); - m_rsdt = static_cast<::acpi::sdt const *>(linear_extended_table_address); + m_rsdt = static_cast<::acpi::xsdt const *>(linear_extended_table_address); m_extended = true; } else @@ -43,7 +45,7 @@ namespace kernel::acpi } auto physical_root_table_address = kapi::memory::physical_address{m_sdp->table_address()}; auto linear_root_table_address = kapi::memory::hhdm_to_linear(physical_root_table_address); - m_rsdt = static_cast<::acpi::sdt const *>(linear_root_table_address); + m_rsdt = static_cast<::acpi::rsdt const *>(linear_root_table_address); } } @@ -54,29 +56,12 @@ namespace kernel::acpi kapi::system::panic("[OS:ACPI] Invalid RSDT checksum!"); } - auto entry_size = m_extended ? sizeof(std::uint64_t) : sizeof(std::uint32_t); - auto entry_count = (m_rsdt->length().value - sizeof(::acpi::sdt)) / entry_size; - auto entries_base = reinterpret_cast<std::byte const *>(m_rsdt) + sizeof(::acpi::sdt); + auto check_and_register_table = [&](auto table_address) -> void { + auto physical_table_address = kapi::memory::physical_address{reinterpret_cast<std::uintptr_t>(table_address)}; + auto mapped_table = kapi::memory::hhdm_to_linear(physical_table_address); + auto table = static_cast<::acpi::table_header const *>(mapped_table); - 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<::acpi::sdt const *>(linear_table_address); - - if (!::acpi::validate_checksum({reinterpret_cast<std::byte const *>(table), table->length().value})) + if (!::acpi::validate_checksum({static_cast<std::byte const *>(mapped_table), table->length().value})) { kstd::println(kstd::print_sink::stderr, "[OS:ACPI] Invalid table checksum!"); } @@ -85,12 +70,25 @@ namespace kernel::acpi kstd::println("[OS:ACPI] Found '{}' ACPI table", table->signature()); m_tables.emplace(table->signature(), table); } + }; + + if (m_extended) + { + auto xsdt = static_cast<::acpi::xsdt const *>(m_rsdt); + std::ranges::for_each(*xsdt | std::views::transform([](auto const & entry) { return entry.address(); }), + check_and_register_table); + } + else + { + auto rsdt = static_cast<::acpi::rsdt const *>(m_rsdt); + std::ranges::for_each(*rsdt | std::views::transform([](auto const & entry) { return entry.address(); }), + check_and_register_table); } return !m_tables.empty(); } - auto manager::get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const> + auto manager::get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::table_header const> { if (m_tables.contains(signature)) { |
