From b31c47b32d91b0b85245ed30f1751cd5cbc397cf Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 16 Apr 2026 09:37:41 +0200 Subject: acpi: add rsdt type --- libs/acpi/CMakeLists.txt | 2 ++ libs/acpi/acpi/data/rsdt.cpp | 37 +++++++++++++++++++++++++++++++ libs/acpi/acpi/data/rsdt.hpp | 42 +++++++++++++++++++++++++++++++++++ libs/acpi/acpi/data/rsdt.test.cpp | 46 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 libs/acpi/acpi/data/rsdt.cpp create mode 100644 libs/acpi/acpi/data/rsdt.hpp create mode 100644 libs/acpi/acpi/data/rsdt.test.cpp (limited to 'libs') diff --git a/libs/acpi/CMakeLists.txt b/libs/acpi/CMakeLists.txt index f6e484c..833dcea 100644 --- a/libs/acpi/CMakeLists.txt +++ b/libs/acpi/CMakeLists.txt @@ -22,6 +22,7 @@ target_sources("acpi" PRIVATE "acpi/common/checksum.cpp" "acpi/common/table_header.cpp" "acpi/data/madt.cpp" + "acpi/data/rsdt.cpp" "acpi/pointers.cpp" ) @@ -61,6 +62,7 @@ if(NOT CMAKE_CROSSCOMPILING) add_executable("acpi_tests" "acpi/common/table_header.test.cpp" "acpi/data/madt.test.cpp" + "acpi/data/rsdt.test.cpp" "acpi/pointers.test.cpp" "test_data/tables.S" diff --git a/libs/acpi/acpi/data/rsdt.cpp b/libs/acpi/acpi/data/rsdt.cpp new file mode 100644 index 0000000..8e20b6c --- /dev/null +++ b/libs/acpi/acpi/data/rsdt.cpp @@ -0,0 +1,37 @@ +#include + +#include +#include + +#include +#include + +namespace acpi +{ + + struct rsdt_entry_data + { + std::uint32_t address; + }; + + [[nodiscard]] auto rsdt_entry::address() const noexcept -> table_header * + { + using type = decltype(rsdt_entry_data::address); + + constexpr auto size = sizeof(type); + constexpr auto offset = offsetof(rsdt_entry_data, address); + + auto const data = std::span{m_data.data() + offset, size}; + auto value = type{}; + + kstd::libc::memcpy(&value, data.data(), size); + + return reinterpret_cast(static_cast(value)); + } + + [[nodiscard]] auto rsdt_entry::length() const noexcept -> std::size_t + { + return sizeof(m_data); + } + +} // namespace acpi \ No newline at end of file diff --git a/libs/acpi/acpi/data/rsdt.hpp b/libs/acpi/acpi/data/rsdt.hpp new file mode 100644 index 0000000..b43f066 --- /dev/null +++ b/libs/acpi/acpi/data/rsdt.hpp @@ -0,0 +1,42 @@ +#ifndef ACPI_DATA_RSDT_HPP +#define ACPI_DATA_RSDT_HPP + +#include +#include +#include +#include + +#include +#include + +namespace acpi +{ + + template<> + struct table_signature + { + constexpr char static const value[] = "RSDT"; // NOLINT + }; + + template<> + struct table_type> + { + using type = struct rsdt; + }; + + struct rsdt_entry + { + [[nodiscard]] auto address() const noexcept -> table_header *; + [[nodiscard]] auto length() const noexcept -> std::size_t; + + private: + std::array m_data{}; + }; + + struct rsdt : vla_table + { + }; + +} // namespace acpi + +#endif \ No newline at end of file diff --git a/libs/acpi/acpi/data/rsdt.test.cpp b/libs/acpi/acpi/data/rsdt.test.cpp new file mode 100644 index 0000000..e1bd1df --- /dev/null +++ b/libs/acpi/acpi/data/rsdt.test.cpp @@ -0,0 +1,46 @@ +#include + +#include +#include +#include +#include + +#include + +SCENARIO("RSDT parsing", "[rsdt]") +{ + GIVEN("The basic compiled RSDT containing 8 table pointers") + { + auto data = acpi::test_data::tables::basic_rsdt(); + + WHEN("parsing the table") + { + auto rsdt = reinterpret_cast(data.data()); + + THEN("the signature is correct") + { + REQUIRE(rsdt->signature() == "RSDT"); + } + + THEN("validate returns true") + { + REQUIRE(rsdt->validate()); + } + + THEN("there are 8 entries in the table") + { + REQUIRE(std::distance(rsdt->begin(), rsdt->end()) == 8); + } + + THEN("the first entry has address 0x10") + { + REQUIRE(rsdt->cbegin()->address() == reinterpret_cast(0x10)); + } + + THEN("the length is sizeof(rsdt) + 8 * sizeof(rsdt_entry)") + { + REQUIRE(rsdt->length() == sizeof(acpi::rsdt) + 8 * sizeof(acpi::rsdt_entry)); + } + } + } +} -- cgit v1.2.3