aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-04-16 09:37:41 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-04-16 09:37:41 +0200
commitb31c47b32d91b0b85245ed30f1751cd5cbc397cf (patch)
treea9a1f0a4c63b654b1feadbed94be0ad7d63f76a8
parent89f1c730fb9daf4a5da0748934ca5befd90eb731 (diff)
downloadteachos-b31c47b32d91b0b85245ed30f1751cd5cbc397cf.tar.xz
teachos-b31c47b32d91b0b85245ed30f1751cd5cbc397cf.zip
acpi: add rsdt type
-rw-r--r--libs/acpi/CMakeLists.txt2
-rw-r--r--libs/acpi/acpi/data/rsdt.cpp37
-rw-r--r--libs/acpi/acpi/data/rsdt.hpp42
-rw-r--r--libs/acpi/acpi/data/rsdt.test.cpp46
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));
+ }
+ }
+ }
+}