diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-04-16 09:37:41 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-04-16 09:37:41 +0200 |
| commit | b31c47b32d91b0b85245ed30f1751cd5cbc397cf (patch) | |
| tree | a9a1f0a4c63b654b1feadbed94be0ad7d63f76a8 /libs | |
| parent | 89f1c730fb9daf4a5da0748934ca5befd90eb731 (diff) | |
| download | teachos-b31c47b32d91b0b85245ed30f1751cd5cbc397cf.tar.xz teachos-b31c47b32d91b0b85245ed30f1751cd5cbc397cf.zip | |
acpi: add rsdt type
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/acpi/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | libs/acpi/acpi/data/rsdt.cpp | 37 | ||||
| -rw-r--r-- | libs/acpi/acpi/data/rsdt.hpp | 42 | ||||
| -rw-r--r-- | libs/acpi/acpi/data/rsdt.test.cpp | 46 |
4 files changed, 127 insertions, 0 deletions
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 <kstd/cstring> + +#include <acpi/common/table_header.hpp> +#include <acpi/data/rsdt.hpp> + +#include <cstddef> +#include <cstdint> + +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<std::byte const, size>{m_data.data() + offset, size}; + auto value = type{}; + + kstd::libc::memcpy(&value, data.data(), size); + + return reinterpret_cast<table_header *>(static_cast<uintptr_t>(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 <acpi/acpi.hpp> +#include <acpi/common/table_signature.hpp> +#include <acpi/common/table_type.hpp> +#include <acpi/common/vla_table.hpp> + +#include <array> +#include <cstddef> + +namespace acpi +{ + + template<> + struct table_signature<struct rsdt> + { + constexpr char static const value[] = "RSDT"; // NOLINT + }; + + template<> + struct table_type<table_signature_v<struct rsdt>> + { + 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<std::byte, 4> m_data{}; + }; + + struct rsdt : vla_table<rsdt_entry, rsdt> + { + }; + +} // 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 <kstd/units> + +#include <acpi/acpi.hpp> +#include <acpi/data/rsdt.hpp> +#include <catch2/catch_test_macros.hpp> +#include <test_data/tables.hpp> + +#include <iterator> + +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<acpi::rsdt const *>(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<acpi::table_header *>(0x10)); + } + + THEN("the length is sizeof(rsdt) + 8 * sizeof(rsdt_entry)") + { + REQUIRE(rsdt->length() == sizeof(acpi::rsdt) + 8 * sizeof(acpi::rsdt_entry)); + } + } + } +} |
