From 3dcd14a0570fef3bcc68d7df42fe3ff4cd496f93 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 14:47:37 +0200 Subject: kapi: hook ACPI initialization up to boot process --- kernel/src/acpi/manager.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 kernel/src/acpi/manager.cpp (limited to 'kernel/src/acpi/manager.cpp') diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp new file mode 100644 index 0000000..6a17920 --- /dev/null +++ b/kernel/src/acpi/manager.cpp @@ -0,0 +1,54 @@ +#include "kernel/acpi/manager.hpp" + +#include "kapi/acpi.hpp" +#include "kapi/memory.hpp" +#include "kapi/system.hpp" + +#include + +namespace kernel::acpi +{ + + manager::manager(kapi::acpi::root_system_description_pointer const & sdp) + : m_sdp{&sdp} + { + if (m_sdp->signature() != "RSD PTR ") + { + kapi::system::panic("[OS:ACPI] Invalid RSDP signature!"); + } + + if (m_sdp->revision() >= 2) + { + auto const xsdp = static_cast(m_sdp); + if (!xsdp->validate()) + { + kapi::system::panic("[OS:ACPI] Invalid XSDP signature!"); + } + auto physical_extended_table_address = xsdp->table_address(); + auto linear_extended_table_address = kapi::memory::hhdm_to_linear(physical_extended_table_address); + m_rsdt = static_cast(linear_extended_table_address); + m_extended = true; + } + else + { + if (!m_sdp->validate()) + { + kapi::system::panic("[OS:ACPI] Invalid RSDP checksum!"); + } + auto physical_root_table_address = m_sdp->table_address(); + auto linear_root_table_address = kapi::memory::hhdm_to_linear(physical_root_table_address); + m_rsdt = static_cast(linear_root_table_address); + } + } + + auto manager::load_tables() -> bool + { + if (!kapi::acpi::validate_checksum({reinterpret_cast(m_rsdt), m_rsdt->length})) + { + kapi::system::panic("[OS:ACPI] Invalid RSDT checksum!"); + } + + return false; + } + +} // namespace kernel::acpi -- cgit v1.2.3 From 4d938cd31a35cd4322fe914edd568faa5391c9c2 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 15:10:04 +0200 Subject: kernel/acpi: implement basic table discovery --- kernel/src/acpi/manager.cpp | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) (limited to 'kernel/src/acpi/manager.cpp') 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 + #include +#include namespace kernel::acpi { @@ -43,12 +46,47 @@ namespace kernel::acpi auto manager::load_tables() -> bool { - if (!kapi::acpi::validate_checksum({reinterpret_cast(m_rsdt), m_rsdt->length})) + if (!kapi::acpi::validate_checksum({reinterpret_cast(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(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(entries_base + (i * entry_size)); + physical_table_address = kapi::memory::physical_address{*entry}; + } + else + { + auto entry = reinterpret_cast(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(linear_table_address); + + if (!kapi::acpi::validate_checksum({reinterpret_cast(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 -- cgit v1.2.3 From f456f1674d48932846eb7b5ec1df630ad67e7e3d Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 17:24:36 +0200 Subject: kernel/acpi: discover local interrupt controllers --- kernel/src/acpi/manager.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'kernel/src/acpi/manager.cpp') diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 180d458..300b85e 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -4,10 +4,12 @@ #include "kapi/memory.hpp" #include "kapi/system.hpp" +#include #include #include #include +#include namespace kernel::acpi { @@ -80,8 +82,7 @@ namespace kernel::acpi } 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()); + kstd::println("[OS:ACPI] Found '{}' ACPI table", table->signature()); m_tables.emplace(table->signature(), table); } } @@ -89,4 +90,14 @@ namespace kernel::acpi return !m_tables.empty(); } + auto manager::get_table(std::string_view signature) + -> kstd::observer_ptr + { + if (m_tables.contains(signature)) + { + return kstd::make_observer(m_tables.at(signature)); + } + return nullptr; + } + } // namespace kernel::acpi -- cgit v1.2.3 From c3f7b747f02a79b34ed914c54ce74be973b17af1 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 10 Apr 2026 17:39:14 +0200 Subject: kapi: extract ACPI functionality to libs --- kernel/src/acpi/manager.cpp | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'kernel/src/acpi/manager.cpp') diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 300b85e..501ce92 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -1,12 +1,13 @@ #include "kernel/acpi/manager.hpp" -#include "kapi/acpi.hpp" #include "kapi/memory.hpp" #include "kapi/system.hpp" #include #include +#include + #include #include #include @@ -14,7 +15,7 @@ namespace kernel::acpi { - manager::manager(kapi::acpi::root_system_description_pointer const & sdp) + manager::manager(::acpi::rsdp const & sdp) : m_sdp{&sdp} { if (m_sdp->signature() != "RSD PTR ") @@ -24,14 +25,14 @@ namespace kernel::acpi if (m_sdp->revision() >= 2) { - auto const xsdp = static_cast(m_sdp); + auto const xsdp = static_cast<::acpi::xsdp const *>(m_sdp); if (!xsdp->validate()) { kapi::system::panic("[OS:ACPI] Invalid XSDP signature!"); } - auto physical_extended_table_address = xsdp->table_address(); + 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(linear_extended_table_address); + m_rsdt = static_cast<::acpi::sdt const *>(linear_extended_table_address); m_extended = true; } else @@ -40,23 +41,22 @@ namespace kernel::acpi { kapi::system::panic("[OS:ACPI] Invalid RSDP checksum!"); } - auto physical_root_table_address = m_sdp->table_address(); + 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(linear_root_table_address); + m_rsdt = static_cast<::acpi::sdt const *>(linear_root_table_address); } } auto manager::load_tables() -> bool { - if (!kapi::acpi::validate_checksum({reinterpret_cast(m_rsdt), m_rsdt->length().value})) + if (!::acpi::validate_checksum({reinterpret_cast(m_rsdt), m_rsdt->length().value})) { 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(kapi::acpi::system_description_table_header)) / entry_size; - auto entries_base = - reinterpret_cast(m_rsdt) + sizeof(kapi::acpi::system_description_table_header); + auto entry_count = (m_rsdt->length().value - sizeof(::acpi::sdt)) / entry_size; + auto entries_base = reinterpret_cast(m_rsdt) + sizeof(::acpi::sdt); for (std::size_t i = 0; i < entry_count; ++i) { @@ -74,9 +74,9 @@ namespace kernel::acpi } auto linear_table_address = kapi::memory::hhdm_to_linear(physical_table_address); - auto table = static_cast(linear_table_address); + auto table = static_cast<::acpi::sdt const *>(linear_table_address); - if (!kapi::acpi::validate_checksum({reinterpret_cast(table), table->length().value})) + if (!::acpi::validate_checksum({reinterpret_cast(table), table->length().value})) { kstd::println(kstd::print_sink::stderr, "[OS:ACPI] Invalid table checksum!"); } @@ -90,8 +90,7 @@ namespace kernel::acpi return !m_tables.empty(); } - auto manager::get_table(std::string_view signature) - -> kstd::observer_ptr + auto manager::get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const> { if (m_tables.contains(signature)) { -- cgit v1.2.3 From 252df23b061b2bf54206da73e41faca600541ccc Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 16 Apr 2026 09:26:52 +0200 Subject: acpi: introduce VLA table --- kernel/src/acpi/manager.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'kernel/src/acpi/manager.cpp') diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 501ce92..41469c2 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -32,7 +32,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::table_header const *>(linear_extended_table_address); m_extended = true; } else @@ -43,7 +43,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::table_header const *>(linear_root_table_address); } } @@ -55,8 +55,8 @@ namespace kernel::acpi } 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(m_rsdt) + sizeof(::acpi::sdt); + auto entry_count = (m_rsdt->length().value - sizeof(::acpi::table_header)) / entry_size; + auto entries_base = reinterpret_cast(m_rsdt) + sizeof(::acpi::table_header); for (std::size_t i = 0; i < entry_count; ++i) { @@ -74,7 +74,7 @@ namespace kernel::acpi } auto linear_table_address = kapi::memory::hhdm_to_linear(physical_table_address); - auto table = static_cast<::acpi::sdt const *>(linear_table_address); + auto table = static_cast<::acpi::table_header const *>(linear_table_address); if (!::acpi::validate_checksum({reinterpret_cast(table), table->length().value})) { @@ -90,7 +90,7 @@ namespace kernel::acpi 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)) { -- cgit v1.2.3 From 28cae58fe117e5fcfc46fd6378e19387cd73b2fe Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 16 Apr 2026 09:40:12 +0200 Subject: acpi: derive basic table from table header --- kernel/src/acpi/manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel/src/acpi/manager.cpp') diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 41469c2..2f2a1bd 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -43,7 +43,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::table_header const *>(linear_root_table_address); + m_rsdt = static_cast<::acpi::rsdt const *>(linear_root_table_address); } } -- cgit v1.2.3 From 776ab2749d5af0a34fd2aa6103a377ddc04d4c53 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 16 Apr 2026 10:03:35 +0200 Subject: acpi: introduce XSDT type --- kernel/src/acpi/manager.cpp | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) (limited to 'kernel/src/acpi/manager.cpp') diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 2f2a1bd..5876799 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -8,8 +8,10 @@ #include +#include #include #include +#include #include 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::table_header const *>(linear_extended_table_address); + m_rsdt = static_cast<::acpi::xsdt const *>(linear_extended_table_address); m_extended = true; } else @@ -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::table_header)) / entry_size; - auto entries_base = reinterpret_cast(m_rsdt) + sizeof(::acpi::table_header); + auto check_and_register_table = [&](auto table_address) -> void { + auto physical_table_address = kapi::memory::physical_address{reinterpret_cast(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(entries_base + (i * entry_size)); - physical_table_address = kapi::memory::physical_address{*entry}; - } - else - { - auto entry = reinterpret_cast(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::table_header const *>(linear_table_address); - - if (!::acpi::validate_checksum({reinterpret_cast(table), table->length().value})) + if (!::acpi::validate_checksum({static_cast(mapped_table), table->length().value})) { kstd::println(kstd::print_sink::stderr, "[OS:ACPI] Invalid table checksum!"); } @@ -85,6 +70,19 @@ 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(); -- cgit v1.2.3 From 2d8fed40bd0d0f8144783b6b344dc79944291b72 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 23 Apr 2026 13:31:17 +0200 Subject: chore: organize includes --- kernel/src/acpi/manager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel/src/acpi/manager.cpp') diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 5876799..f17c9cb 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -3,11 +3,11 @@ #include "kapi/memory.hpp" #include "kapi/system.hpp" +#include + #include #include -#include - #include #include #include -- cgit v1.2.3 From f6f10575f75ac23d06e1d94f7861611503daa7af Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 23 Apr 2026 14:03:28 +0200 Subject: chore: banish relative includes --- kernel/src/acpi/manager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'kernel/src/acpi/manager.cpp') diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index f17c9cb..99c8860 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -1,7 +1,7 @@ -#include "kernel/acpi/manager.hpp" +#include -#include "kapi/memory.hpp" -#include "kapi/system.hpp" +#include +#include #include -- cgit v1.2.3 From d3e02e6d9de4751910a8c51079e9489bd15948c7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 30 Apr 2026 18:42:08 +0200 Subject: kernel/acpi: simplify manager constructor --- kernel/src/acpi/manager.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'kernel/src/acpi/manager.cpp') diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 99c8860..bb895fd 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -20,22 +20,19 @@ namespace kernel::acpi manager::manager(::acpi::rsdp const & sdp) : m_sdp{&sdp} { - if (m_sdp->signature() != "RSD PTR ") + if (!m_sdp->validate()) { kapi::system::panic("[OS:ACPI] Invalid RSDP signature!"); } - if (m_sdp->revision() >= 2) + m_extended = m_sdp->revision() >= 2; + + if (m_extended) { - auto const xsdp = static_cast<::acpi::xsdp const *>(m_sdp); - if (!xsdp->validate()) + if (!static_cast<::acpi::xsdp const *>(m_sdp)->validate()) { kapi::system::panic("[OS:ACPI] Invalid XSDP signature!"); } - 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::xsdt const *>(linear_extended_table_address); - m_extended = true; } else { @@ -43,10 +40,11 @@ namespace kernel::acpi { kapi::system::panic("[OS:ACPI] Invalid RSDP checksum!"); } - 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::rsdt const *>(linear_root_table_address); } + + auto physical_address = kapi::memory::physical_address{m_sdp->table_address()}; + auto linear_address = kapi::memory::hhdm_to_linear(physical_address); + m_rsdt = static_cast<::acpi::table_header const *>(linear_address); } auto manager::load_tables() -> bool -- cgit v1.2.3