aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-04-10 17:39:14 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-04-10 17:39:14 +0200
commitc3f7b747f02a79b34ed914c54ce74be973b17af1 (patch)
tree79526c34b3768562f3aa90f69a476cf504ebccc4
parent5a6b6ab376e67b173ef36f831445ccba7e86e038 (diff)
downloadteachos-c3f7b747f02a79b34ed914c54ce74be973b17af1.tar.xz
teachos-c3f7b747f02a79b34ed914c54ce74be973b17af1.zip
kapi: extract ACPI functionality to libs
-rw-r--r--arch/x86_64/kapi/acpi.cpp10
-rw-r--r--arch/x86_64/kapi/cpu.cpp15
-rw-r--r--kapi/CMakeLists.txt1
-rw-r--r--kapi/include/kapi/acpi.hpp25
-rw-r--r--kapi/include/kapi/acpi/table_iterator.hpp64
-rw-r--r--kapi/include/kapi/acpi/table_type.hpp22
-rw-r--r--kernel/CMakeLists.txt3
-rw-r--r--kernel/include/kernel/acpi/manager.hpp14
-rw-r--r--kernel/kapi/acpi.cpp18
-rw-r--r--kernel/kapi/acpi/multiple_apic_description_table.cpp70
-rw-r--r--kernel/kapi/acpi/pointers.cpp55
-rw-r--r--kernel/kapi/acpi/system_description_table_header.cpp51
-rw-r--r--kernel/src/acpi/manager.cpp29
-rw-r--r--libs/CMakeLists.txt3
-rw-r--r--libs/acpi/CMakeLists.txt29
-rw-r--r--libs/acpi/acpi/acpi.hpp10
-rw-r--r--libs/acpi/acpi/checksum.cpp19
-rw-r--r--libs/acpi/acpi/checksum.hpp20
-rw-r--r--libs/acpi/acpi/madt.cpp68
-rw-r--r--libs/acpi/acpi/madt.hpp (renamed from kapi/include/kapi/acpi/multiple_apic_description_table.hpp)42
-rw-r--r--libs/acpi/acpi/pointers.cpp55
-rw-r--r--libs/acpi/acpi/pointers.hpp (renamed from kapi/include/kapi/acpi/pointers.hpp)27
-rw-r--r--libs/acpi/acpi/sdt.cpp51
-rw-r--r--libs/acpi/acpi/sdt.hpp (renamed from kapi/include/kapi/acpi/system_description_table_header.hpp)81
-rw-r--r--libs/acpi/acpi/table_type.hpp17
25 files changed, 406 insertions, 393 deletions
diff --git a/arch/x86_64/kapi/acpi.cpp b/arch/x86_64/kapi/acpi.cpp
index ec38aee..40b7160 100644
--- a/arch/x86_64/kapi/acpi.cpp
+++ b/arch/x86_64/kapi/acpi.cpp
@@ -4,24 +4,26 @@
#include <kstd/memory>
+#include <acpi/acpi.hpp>
+
namespace kapi::acpi
{
- auto get_root_pointer() -> kstd::observer_ptr<root_system_description_pointer const>
+ auto get_root_pointer() -> kstd::observer_ptr<::acpi::rsdp const>
{
auto const & mbi = kapi::boot::bootstrap_information.mbi;
- auto system_description_pointer = static_cast<kapi::acpi::root_system_description_pointer const *>(nullptr);
+ auto system_description_pointer = static_cast<::acpi::rsdp 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);
+ system_description_pointer = reinterpret_cast<::acpi::xsdp 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);
+ system_description_pointer = reinterpret_cast<::acpi::rsdp const *>(data);
}
return kstd::make_observer(system_description_pointer);
diff --git a/arch/x86_64/kapi/cpu.cpp b/arch/x86_64/kapi/cpu.cpp
index 726ec6a..a836b20 100644
--- a/arch/x86_64/kapi/cpu.cpp
+++ b/arch/x86_64/kapi/cpu.cpp
@@ -3,6 +3,7 @@
#include "kapi/acpi.hpp"
#include "kapi/devices.hpp"
#include "kapi/devices/cpu.hpp"
+#include "kapi/memory.hpp"
#include "kapi/system.hpp"
#include "arch/cpu/initialization.hpp"
@@ -11,6 +12,8 @@
#include <kstd/memory>
#include <kstd/print>
+#include <acpi/acpi.hpp>
+
#include <atomic>
#include <ranges>
#include <utility>
@@ -20,8 +23,8 @@ namespace kapi::cpu
namespace
{
- constexpr auto candidate_flags = acpi::processor_local_apic::flags::processor_enabled //
- | acpi::processor_local_apic::flags::online_capable;
+ constexpr auto candidate_flags = ::acpi::processor_local_apic::flags::processor_enabled //
+ | ::acpi::processor_local_apic::flags::online_capable;
}
auto init() -> void
@@ -49,7 +52,7 @@ namespace kapi::cpu
auto static const core_major = kapi::devices::allocate_major_number();
auto static const interrupt_controller_major = kapi::devices::allocate_major_number();
- auto madt = kapi::acpi::get_table<acpi::madt_table_signature>();
+ auto madt = kapi::acpi::get_table<::acpi::madt_table_signature>();
if (!madt)
{
kstd::println("[x86_64:PLT] Failed to find ACPI APIC table");
@@ -57,16 +60,16 @@ namespace kapi::cpu
}
auto lapic_entries = *madt | std::views::filter([](auto const & entry) {
- return entry.type() == acpi::multiple_apic_description_table_entry::types::processor_local_apic;
+ return entry.type() == ::acpi::madt_entry::types::processor_local_apic;
}) | std::views::transform([](auto const & entry) {
- return static_cast<acpi::processor_local_apic const &>(entry);
+ return static_cast<::acpi::processor_local_apic const &>(entry);
}) | std::views::filter([](auto const & entry) {
return static_cast<bool>(entry.active_flags() & candidate_flags);
});
auto bsp_found = false;
auto core_count = 0uz;
- auto local_apic_address = madt->local_interrupt_controller_address();
+ auto local_apic_address = memory::physical_address{madt->local_interrupt_controller_address()};
auto cpu_bus = kstd::make_unique<devices::cpu>(cpu_major, 0);
for (auto const & apic : lapic_entries)
diff --git a/kapi/CMakeLists.txt b/kapi/CMakeLists.txt
index c9aa23f..99a8725 100644
--- a/kapi/CMakeLists.txt
+++ b/kapi/CMakeLists.txt
@@ -15,6 +15,7 @@ target_include_directories("kapi" INTERFACE
)
target_link_libraries("kapi" INTERFACE
+ "libs::acpi"
"libs::kstd"
"gcc"
diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp
index 5323fee..01fd113 100644
--- a/kapi/include/kapi/acpi.hpp
+++ b/kapi/include/kapi/acpi.hpp
@@ -1,16 +1,11 @@
#ifndef TEACHOS_KAPI_ACPI_HPP
#define TEACHOS_KAPI_ACPI_HPP
-#include "kapi/acpi/multiple_apic_description_table.hpp" // IWYU pragma: export
-#include "kapi/acpi/pointers.hpp" // IWYU pragma: export
-#include "kapi/acpi/system_description_table_header.hpp" // IWYU pragma: export
-#include "kapi/acpi/table_type.hpp"
-
#include <kstd/memory>
#include <kstd/units>
-#include <cstddef>
-#include <span>
+#include <acpi/acpi.hpp>
+
#include <string_view>
namespace kapi::acpi
@@ -22,28 +17,22 @@ namespace kapi::acpi
//! Initialize the ACPI subsystem and discover the available tables.
//!
//! @return true iff. a valid system description tabled was found, false otherwise.
- auto init(root_system_description_pointer const & sdp) -> bool;
-
- //! Validate and ACPI entity checksum.
- //!
- //! @param data The data to validate the checksum of.
- //! @return true iff. the checksum is valid, false otherwise.
- auto validate_checksum(std::span<std::byte const> data) -> bool;
+ auto init(::acpi::rsdp const & sdp) -> bool;
//! Get a pointer to an ACPI table by its signature.
//!
//! @param signature The signature of the table to get.
//! @return A pointer to the table if found, nullptr otherwise.
- auto get_table(std::string_view signature) -> kstd::observer_ptr<system_description_table_header const>;
+ auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const>;
//! Get a type-cast pointer to an ACPI table by its signature.
//!
//! @tparam Signature The signature of the table to get
//! @return A pointer to the table if found, nullptr otherwise.
template<char const * Signature>
- auto get_table() -> kstd::observer_ptr<table_type_t<Signature> const>
+ auto get_table() -> kstd::observer_ptr<::acpi::table_type_t<Signature> const>
{
- return kstd::make_observer(static_cast<table_type_t<Signature> const *>(get_table(Signature).get()));
+ return kstd::make_observer(static_cast<::acpi::table_type_t<Signature> const *>(get_table(Signature).get()));
}
//! @}
@@ -54,7 +43,7 @@ namespace kapi::acpi
//! Retrieve the RSDP or XSDP for this system.
//!
//! @return a pointer to either the RSDP or XSDP data structure, or @p nullptr if neither is present.
- auto get_root_pointer() -> kstd::observer_ptr<root_system_description_pointer const>;
+ auto get_root_pointer() -> kstd::observer_ptr<::acpi::rsdp const>;
//! @}
diff --git a/kapi/include/kapi/acpi/table_iterator.hpp b/kapi/include/kapi/acpi/table_iterator.hpp
deleted file mode 100644
index 998d6d6..0000000
--- a/kapi/include/kapi/acpi/table_iterator.hpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef TEACHOS_KAPI_ACPI_TABLE_ITERATOR_HPP
-#define TEACHOS_KAPI_ACPI_TABLE_ITERATOR_HPP
-
-#include <bit>
-#include <cstddef>
-#include <iterator>
-
-namespace kapi::acpi
-{
-
- template<typename EntryType>
- struct table_iterator
- {
- using iterator_category = std::forward_iterator_tag;
- using value_type = EntryType;
- using pointer = value_type *;
- using reference = value_type &;
- using difference_type = std::ptrdiff_t;
-
- constexpr table_iterator() noexcept = default;
-
- constexpr table_iterator(pointer entry, pointer limit) noexcept
- : m_entry{entry}
- , m_limit{limit}
- {}
-
- constexpr auto operator++() noexcept -> table_iterator &
- {
- auto decayed = std::bit_cast<std::byte *>(m_entry);
- decayed += m_entry->length();
- m_entry = std::bit_cast<pointer>(decayed);
- return *this;
- }
-
- constexpr auto operator++(int) noexcept -> table_iterator
- {
- auto copy = *this;
- ++*this;
- return copy;
- }
-
- constexpr auto operator*() const noexcept -> reference
- {
- return *m_entry;
- }
-
- constexpr auto operator==(table_iterator const & other) const noexcept -> bool
- {
- return m_entry == other.m_entry || (is_end() && other.is_end());
- }
-
- private:
- [[nodiscard]] constexpr auto is_end() const noexcept -> bool
- {
- return m_entry == m_limit;
- }
-
- pointer m_entry{};
- pointer m_limit{};
- };
-
-} // namespace kapi::acpi
-
-#endif
diff --git a/kapi/include/kapi/acpi/table_type.hpp b/kapi/include/kapi/acpi/table_type.hpp
deleted file mode 100644
index e088a24..0000000
--- a/kapi/include/kapi/acpi/table_type.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef TEACHOS_KAPI_ACPI_TABLE_TYPE_HPP
-#define TEACHOS_KAPI_ACPI_TABLE_TYPE_HPP
-
-// IWYU pragma: private
-
-namespace kapi::acpi
-{
-
- //! @addtogroup kapi-acpi-kernel-defined
- //! @{
-
- template<char const *>
- struct table_type;
-
- template<char const * Signature>
- using table_type_t = typename table_type<Signature>::type;
-
- //! @}
-
-} // namespace kapi::acpi
-
-#endif
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index b9e01eb..74233cb 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -1,9 +1,6 @@
add_library("kernel_objs" OBJECT
# Platform-independent KAPI implementation
"kapi/acpi.cpp"
- "kapi/acpi/multiple_apic_description_table.cpp"
- "kapi/acpi/pointers.cpp"
- "kapi/acpi/system_description_table_header.cpp"
"kapi/boot_modules.cpp"
"kapi/cio.cpp"
"kapi/cpu.cpp"
diff --git a/kernel/include/kernel/acpi/manager.hpp b/kernel/include/kernel/acpi/manager.hpp
index fae59a6..420b44a 100644
--- a/kernel/include/kernel/acpi/manager.hpp
+++ b/kernel/include/kernel/acpi/manager.hpp
@@ -1,12 +1,12 @@
#ifndef TEACHOS_KERNEL_ACPI_MANAGER_HPP
#define TEACHOS_KERNEL_ACPI_MANAGER_HPP
-#include "kapi/acpi.hpp"
-
#include <kstd/flat_map>
#include <kstd/memory>
#include <kstd/vector>
+#include <acpi/acpi.hpp>
+
#include <string_view>
namespace kernel::acpi
@@ -14,16 +14,16 @@ namespace kernel::acpi
struct manager
{
- explicit manager(kapi::acpi::root_system_description_pointer const & sdp);
+ explicit manager(::acpi::rsdp const & sdp);
auto load_tables() -> bool;
- auto get_table(std::string_view signature) -> kstd::observer_ptr<kapi::acpi::system_description_table_header const>;
+ auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const>;
private:
- kapi::acpi::root_system_description_pointer const * m_sdp{};
- kapi::acpi::system_description_table_header const * m_rsdt{};
- kstd::flat_map<std::string_view, kapi::acpi::system_description_table_header const *> m_tables{};
+ ::acpi::rsdp const * m_sdp{};
+ ::acpi::sdt const * m_rsdt{};
+ kstd::flat_map<std::string_view, ::acpi::sdt const *> m_tables{};
bool m_extended{};
};
diff --git a/kernel/kapi/acpi.cpp b/kernel/kapi/acpi.cpp
index e7c4921..df2bf05 100644
--- a/kernel/kapi/acpi.cpp
+++ b/kernel/kapi/acpi.cpp
@@ -6,12 +6,10 @@
#include <kstd/memory>
-#include <algorithm>
+#include <acpi/acpi.hpp>
+
#include <atomic>
-#include <cstddef>
-#include <cstdint>
#include <optional>
-#include <span>
#include <string_view>
namespace kapi::acpi
@@ -22,7 +20,7 @@ namespace kapi::acpi
auto constinit manager = std::optional<kernel::acpi::manager>{};
} // namespace
- auto init(root_system_description_pointer const & sdp) -> bool
+ auto init(::acpi::rsdp const & sdp) -> bool
{
auto static constinit initialized = std::atomic_flag{};
if (initialized.test_and_set())
@@ -34,15 +32,7 @@ namespace kapi::acpi
return manager->load_tables();
}
- auto validate_checksum(std::span<std::byte const> data) -> bool
- {
- auto sum = std::ranges::fold_left(data, std::uint8_t{}, [](auto acc, auto byte) {
- return static_cast<std::uint8_t>(acc + static_cast<std::uint8_t>(byte));
- });
- return sum == 0;
- }
-
- auto get_table(std::string_view signature) -> kstd::observer_ptr<system_description_table_header const>
+ auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const>
{
return manager->get_table(signature);
}
diff --git a/kernel/kapi/acpi/multiple_apic_description_table.cpp b/kernel/kapi/acpi/multiple_apic_description_table.cpp
deleted file mode 100644
index c0360a3..0000000
--- a/kernel/kapi/acpi/multiple_apic_description_table.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#include "kapi/acpi.hpp"
-#include "kapi/memory.hpp"
-
-#include <cstddef>
-#include <cstdint>
-
-namespace kapi::acpi
-{
-
- auto multiple_apic_description_table::local_interrupt_controller_address() const noexcept -> memory::physical_address
- {
- return memory::physical_address{static_cast<std::uintptr_t>(m_local_interrupt_controller_address)};
- }
-
- auto multiple_apic_description_table::flags() const noexcept -> std::uint32_t
- {
- return m_flags;
- }
-
- auto multiple_apic_description_table_entry::type() const noexcept -> types
- {
- return static_cast<types>(m_type);
- }
-
- auto multiple_apic_description_table_entry::length() const noexcept -> std::size_t
- {
- return m_length;
- }
-
- auto processor_local_apic::apic_id() const noexcept -> std::uint8_t
- {
- return m_apic_id;
- }
-
- auto processor_local_apic::active_flags() const noexcept -> flags
- {
- return static_cast<flags>(m_flags);
- }
-
- auto processor_local_apic::processor_id() const noexcept -> std::uint32_t
- {
- return m_processor_id;
- }
-
- auto multiple_apic_description_table::begin() const noexcept -> iterator
- {
- auto base = reinterpret_cast<std::byte const *>(this);
- base += sizeof(multiple_apic_description_table);
- auto limit = reinterpret_cast<std::byte const *>(this);
- limit += length().value;
- return iterator{reinterpret_cast<multiple_apic_description_table_entry const *>(base),
- reinterpret_cast<multiple_apic_description_table_entry const *>(limit)};
- }
-
- auto multiple_apic_description_table::cbegin() const noexcept -> iterator
- {
- return begin();
- }
-
- auto multiple_apic_description_table::end() const noexcept -> iterator
- {
- return {};
- }
-
- auto multiple_apic_description_table::cend() const noexcept -> iterator
- {
- return end();
- }
-
-} // namespace kapi::acpi
diff --git a/kernel/kapi/acpi/pointers.cpp b/kernel/kapi/acpi/pointers.cpp
deleted file mode 100644
index 63831e9..0000000
--- a/kernel/kapi/acpi/pointers.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "kapi/acpi.hpp"
-#include "kapi/memory.hpp"
-
-#include <kstd/units>
-
-#include <bit>
-#include <cstddef>
-#include <cstdint>
-#include <string_view>
-
-namespace kapi::acpi
-{
-
- auto root_system_description_pointer::oem_id() const noexcept -> std::string_view
- {
- return {m_oem_id.data(), m_oem_id.size()};
- }
-
- auto root_system_description_pointer::revision() const noexcept -> std::uint8_t
- {
- return m_revision;
- }
-
- auto root_system_description_pointer::signature() const noexcept -> std::string_view
- {
- return {m_signature.data(), m_signature.size()};
- }
-
- auto root_system_description_pointer::table_address() const noexcept -> memory::physical_address
- {
- auto raw = std::bit_cast<std::uint32_t>(m_rsdt_address);
- return memory::physical_address{static_cast<std::uintptr_t>(raw)};
- }
-
- auto root_system_description_pointer::validate() const noexcept -> bool
- {
- return validate_checksum({reinterpret_cast<std::byte const *>(this), sizeof(root_system_description_pointer)});
- }
-
- auto extended_system_description_pointer::length() const noexcept -> kstd::units::bytes
- {
- return kstd::units::bytes{m_length};
- }
-
- auto extended_system_description_pointer::table_address() const noexcept -> memory::physical_address
- {
- return memory::physical_address{std::bit_cast<std::uintptr_t>(m_xsdt_address)};
- }
-
- auto extended_system_description_pointer::validate() const noexcept -> bool
- {
- return validate_checksum({reinterpret_cast<std::byte const *>(this), m_length});
- }
-
-} // namespace kapi::acpi
diff --git a/kernel/kapi/acpi/system_description_table_header.cpp b/kernel/kapi/acpi/system_description_table_header.cpp
deleted file mode 100644
index f688b4d..0000000
--- a/kernel/kapi/acpi/system_description_table_header.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "kapi/acpi.hpp"
-
-#include <kstd/units>
-
-#include <cstdint>
-#include <string_view>
-
-namespace kapi::acpi
-{
-
- [[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()};
- }
-
-} // namespace kapi::acpi
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 <kstd/memory>
#include <kstd/print>
+#include <acpi/acpi.hpp>
+
#include <cstddef>
#include <cstdint>
#include <string_view>
@@ -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<kapi::acpi::extended_system_description_pointer const *>(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<kapi::acpi::system_description_table_header const *>(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<kapi::acpi::system_description_table_header const *>(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<std::byte const *>(m_rsdt), m_rsdt->length().value}))
+ if (!::acpi::validate_checksum({reinterpret_cast<std::byte const *>(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<std::byte const *>(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<std::byte const *>(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<kapi::acpi::system_description_table_header const *>(linear_table_address);
+ auto table = static_cast<::acpi::sdt const *>(linear_table_address);
- if (!kapi::acpi::validate_checksum({reinterpret_cast<std::byte const *>(table), table->length().value}))
+ if (!::acpi::validate_checksum({reinterpret_cast<std::byte const *>(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<kapi::acpi::system_description_table_header const>
+ auto manager::get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const>
{
if (m_tables.contains(signature))
{
diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt
index 58d9796..2b61992 100644
--- a/libs/CMakeLists.txt
+++ b/libs/CMakeLists.txt
@@ -1,3 +1,4 @@
+add_subdirectory("acpi" EXCLUDE_FROM_ALL SYSTEM)
add_subdirectory("elf" EXCLUDE_FROM_ALL SYSTEM)
add_subdirectory("kstd" EXCLUDE_FROM_ALL SYSTEM)
-add_subdirectory("multiboot2" EXCLUDE_FROM_ALL SYSTEM) \ No newline at end of file
+add_subdirectory("multiboot2" EXCLUDE_FROM_ALL SYSTEM)
diff --git a/libs/acpi/CMakeLists.txt b/libs/acpi/CMakeLists.txt
new file mode 100644
index 0000000..c6e63b9
--- /dev/null
+++ b/libs/acpi/CMakeLists.txt
@@ -0,0 +1,29 @@
+add_library("acpi" STATIC)
+add_library("libs::acpi" ALIAS "acpi")
+
+target_include_directories("acpi" PUBLIC
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+)
+
+file(GLOB_RECURSE ACPI_HEADERS
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ "acpi/*.hpp"
+)
+
+target_sources("acpi" PRIVATE
+ "acpi/checksum.cpp"
+ "acpi/madt.cpp"
+ "acpi/pointers.cpp"
+ "acpi/sdt.cpp"
+)
+
+target_sources("acpi" PUBLIC
+ FILE_SET HEADERS
+ BASE_DIRS "acpi"
+ FILES
+ ${ACPI_HEADERS}
+)
+
+target_link_libraries("acpi" PUBLIC
+ "libs::kstd"
+)
diff --git a/libs/acpi/acpi/acpi.hpp b/libs/acpi/acpi/acpi.hpp
new file mode 100644
index 0000000..fb358cc
--- /dev/null
+++ b/libs/acpi/acpi/acpi.hpp
@@ -0,0 +1,10 @@
+#ifndef ACPI_ACPI_HPP
+#define ACPI_ACPI_HPP
+
+#include <acpi/checksum.hpp> // IWYU pragma: export
+#include <acpi/madt.hpp> // IWYU pragma: export
+#include <acpi/pointers.hpp> // IWYU pragma: export
+#include <acpi/sdt.hpp> // IWYU pragma: export
+#include <acpi/table_type.hpp> // IWYU pragma: export
+
+#endif
diff --git a/libs/acpi/acpi/checksum.cpp b/libs/acpi/acpi/checksum.cpp
new file mode 100644
index 0000000..56275c8
--- /dev/null
+++ b/libs/acpi/acpi/checksum.cpp
@@ -0,0 +1,19 @@
+#include <acpi/checksum.hpp>
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <span>
+
+namespace acpi
+{
+
+ auto validate_checksum(std::span<std::byte const> data) -> bool
+ {
+ auto sum = std::ranges::fold_left(data, std::uint8_t{}, [](auto acc, auto byte) {
+ return static_cast<std::uint8_t>(acc + static_cast<std::uint8_t>(byte));
+ });
+ return sum == 0;
+ }
+
+} // namespace acpi
diff --git a/libs/acpi/acpi/checksum.hpp b/libs/acpi/acpi/checksum.hpp
new file mode 100644
index 0000000..a92c242
--- /dev/null
+++ b/libs/acpi/acpi/checksum.hpp
@@ -0,0 +1,20 @@
+#ifndef ACPI_CHECKSUM_HPP
+#define ACPI_CHECKSUM_HPP
+
+// IWYU pragma: private, include <acpi/acpi.hpp>
+
+#include <cstddef>
+#include <span>
+
+namespace acpi
+{
+
+ //! Validate and ACPI entity checksum.
+ //!
+ //! @param data The data to validate the checksum of.
+ //! @return true iff. the checksum is valid, false otherwise.
+ auto validate_checksum(std::span<std::byte const> data) -> bool;
+
+} // namespace acpi
+
+#endif
diff --git a/libs/acpi/acpi/madt.cpp b/libs/acpi/acpi/madt.cpp
new file mode 100644
index 0000000..40289cf
--- /dev/null
+++ b/libs/acpi/acpi/madt.cpp
@@ -0,0 +1,68 @@
+#include <acpi/madt.hpp>
+
+#include <cstddef>
+#include <cstdint>
+
+namespace acpi
+{
+
+ auto madt::local_interrupt_controller_address() const noexcept -> std::uintptr_t
+ {
+ return static_cast<std::uintptr_t>(m_local_interrupt_controller_address);
+ }
+
+ auto madt::flags() const noexcept -> std::uint32_t
+ {
+ return m_flags;
+ }
+
+ auto madt_entry::type() const noexcept -> types
+ {
+ return static_cast<types>(m_type);
+ }
+
+ auto madt_entry::length() const noexcept -> std::size_t
+ {
+ return m_length;
+ }
+
+ auto processor_local_apic::apic_id() const noexcept -> std::uint8_t
+ {
+ return m_apic_id;
+ }
+
+ auto processor_local_apic::active_flags() const noexcept -> flags
+ {
+ return static_cast<flags>(m_flags);
+ }
+
+ auto processor_local_apic::processor_id() const noexcept -> std::uint32_t
+ {
+ return m_processor_id;
+ }
+
+ auto madt::begin() const noexcept -> iterator
+ {
+ auto base = reinterpret_cast<std::byte const *>(this);
+ base += sizeof(madt);
+ auto limit = reinterpret_cast<std::byte const *>(this);
+ limit += length().value;
+ return iterator{reinterpret_cast<madt_entry const *>(base), reinterpret_cast<madt_entry const *>(limit)};
+ }
+
+ auto madt::cbegin() const noexcept -> iterator
+ {
+ return begin();
+ }
+
+ auto madt::end() const noexcept -> iterator
+ {
+ return {};
+ }
+
+ auto madt::cend() const noexcept -> iterator
+ {
+ return end();
+ }
+