aboutsummaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-04-16 10:03:35 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-04-16 10:03:35 +0200
commit776ab2749d5af0a34fd2aa6103a377ddc04d4c53 (patch)
tree06b094e66f1a15a4282fc6294ab5d4751b792754 /libs
parent28cae58fe117e5fcfc46fd6378e19387cd73b2fe (diff)
downloadteachos-776ab2749d5af0a34fd2aa6103a377ddc04d4c53.tar.xz
teachos-776ab2749d5af0a34fd2aa6103a377ddc04d4c53.zip
acpi: introduce XSDT type
Diffstat (limited to 'libs')
-rw-r--r--libs/acpi/CMakeLists.txt3
-rw-r--r--libs/acpi/acpi/acpi.hpp1
-rw-r--r--libs/acpi/acpi/data/rsdt.hpp1
-rw-r--r--libs/acpi/acpi/data/xsdt.cpp38
-rw-r--r--libs/acpi/acpi/data/xsdt.hpp42
-rw-r--r--libs/acpi/acpi/data/xsdt.test.cpp46
-rw-r--r--libs/acpi/test_data/basic_xsdt.asl26
-rw-r--r--libs/acpi/test_data/tables.S1
-rw-r--r--libs/acpi/test_data/tables.hpp1
9 files changed, 159 insertions, 0 deletions
diff --git a/libs/acpi/CMakeLists.txt b/libs/acpi/CMakeLists.txt
index 833dcea..55d5b54 100644
--- a/libs/acpi/CMakeLists.txt
+++ b/libs/acpi/CMakeLists.txt
@@ -23,6 +23,7 @@ target_sources("acpi" PRIVATE
"acpi/common/table_header.cpp"
"acpi/data/madt.cpp"
"acpi/data/rsdt.cpp"
+ "acpi/data/xsdt.cpp"
"acpi/pointers.cpp"
)
@@ -44,6 +45,7 @@ if(NOT CMAKE_CROSSCOMPILING)
"basic_madt"
"basic_rsdt"
"basic_rsdp"
+ "basic_xsdt"
"table_header"
)
@@ -63,6 +65,7 @@ if(NOT CMAKE_CROSSCOMPILING)
"acpi/common/table_header.test.cpp"
"acpi/data/madt.test.cpp"
"acpi/data/rsdt.test.cpp"
+ "acpi/data/xsdt.test.cpp"
"acpi/pointers.test.cpp"
"test_data/tables.S"
diff --git a/libs/acpi/acpi/acpi.hpp b/libs/acpi/acpi/acpi.hpp
index 385ddc9..0da44a8 100644
--- a/libs/acpi/acpi/acpi.hpp
+++ b/libs/acpi/acpi/acpi.hpp
@@ -6,6 +6,7 @@
#include <acpi/common/table_type.hpp> // IWYU pragma: export
#include <acpi/data/madt.hpp> // IWYU pragma: export
#include <acpi/data/rsdt.hpp> // IWYU pragma: export
+#include <acpi/data/xsdt.hpp> // IWYU pragma: export
#include <acpi/pointers.hpp> // IWYU pragma: export
#endif
diff --git a/libs/acpi/acpi/data/rsdt.hpp b/libs/acpi/acpi/data/rsdt.hpp
index 88c5fd1..a661187 100644
--- a/libs/acpi/acpi/data/rsdt.hpp
+++ b/libs/acpi/acpi/data/rsdt.hpp
@@ -1,6 +1,7 @@
#ifndef ACPI_DATA_RSDT_HPP
#define ACPI_DATA_RSDT_HPP
+#include <acpi/common/table_header.hpp>
#include <acpi/common/table_signature.hpp>
#include <acpi/common/table_type.hpp>
#include <acpi/common/vla_table.hpp>
diff --git a/libs/acpi/acpi/data/xsdt.cpp b/libs/acpi/acpi/data/xsdt.cpp
new file mode 100644
index 0000000..b4202b8
--- /dev/null
+++ b/libs/acpi/acpi/data/xsdt.cpp
@@ -0,0 +1,38 @@
+#include <kstd/cstring>
+
+#include <acpi/common/table_header.hpp>
+#include <acpi/data/xsdt.hpp>
+
+#include <cstddef>
+#include <cstdint>
+#include <span>
+
+namespace acpi
+{
+
+ struct xsdt_entry_data
+ {
+ std::uint64_t address;
+ };
+
+ [[nodiscard]] auto xsdt_entry::address() const noexcept -> table_header *
+ {
+ using type = decltype(xsdt_entry_data::address);
+
+ constexpr auto size = sizeof(type);
+ constexpr auto offset = offsetof(xsdt_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 xsdt_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/xsdt.hpp b/libs/acpi/acpi/data/xsdt.hpp
new file mode 100644
index 0000000..965f23c
--- /dev/null
+++ b/libs/acpi/acpi/data/xsdt.hpp
@@ -0,0 +1,42 @@
+#ifndef ACPI_DATA_XSDT_HPP
+#define ACPI_DATA_XSDT_HPP
+
+#include <acpi/common/table_header.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 xsdt>
+ {
+ constexpr char static const value[] = "XSDT"; // NOLINT
+ };
+
+ template<>
+ struct table_type<table_signature_v<struct xsdt>>
+ {
+ using type = struct xsdt;
+ };
+
+ struct xsdt_entry
+ {
+ [[nodiscard]] auto address() const noexcept -> table_header *;
+ [[nodiscard]] auto length() const noexcept -> std::size_t;
+
+ private:
+ std::array<std::byte, 8> m_data{};
+ };
+
+ struct xsdt : vla_table<xsdt_entry, xsdt>
+ {
+ };
+
+} // namespace acpi
+
+#endif \ No newline at end of file
diff --git a/libs/acpi/acpi/data/xsdt.test.cpp b/libs/acpi/acpi/data/xsdt.test.cpp
new file mode 100644
index 0000000..7fb564c
--- /dev/null
+++ b/libs/acpi/acpi/data/xsdt.test.cpp
@@ -0,0 +1,46 @@
+#include <kstd/units>
+
+#include <acpi/acpi.hpp>
+#include <acpi/data/xsdt.hpp>
+#include <catch2/catch_test_macros.hpp>
+#include <test_data/tables.hpp>
+
+#include <iterator>
+
+SCENARIO("XSDT parsing", "[xsdt]")
+{
+ GIVEN("The basic compiled XSDT containing 8 table pointers")
+ {
+ auto data = acpi::test_data::tables::basic_xsdt();
+
+ WHEN("parsing the table")
+ {
+ auto xsdt = reinterpret_cast<acpi::xsdt const *>(data.data());
+
+ THEN("the signature is correct")
+ {
+ REQUIRE(xsdt->signature() == "XSDT");
+ }
+
+ THEN("validate returns true")
+ {
+ REQUIRE(xsdt->validate());
+ }
+
+ THEN("there are 8 entries in the table")
+ {
+ REQUIRE(std::distance(xsdt->begin(), xsdt->end()) == 8);
+ }
+
+ THEN("the first entry has address 0x10")
+ {
+ REQUIRE(xsdt->cbegin()->address() == reinterpret_cast<acpi::table_header *>(0x10));
+ }
+
+ THEN("the length is sizeof(xsdt) + 8 * sizeof(xsdt_entry)")
+ {
+ REQUIRE(xsdt->length().value == sizeof(acpi::xsdt) + 8 * sizeof(acpi::xsdt_entry));
+ }
+ }
+ }
+}
diff --git a/libs/acpi/test_data/basic_xsdt.asl b/libs/acpi/test_data/basic_xsdt.asl
new file mode 100644
index 0000000..d8589f9
--- /dev/null
+++ b/libs/acpi/test_data/basic_xsdt.asl
@@ -0,0 +1,26 @@
+/*
+ * Intel ACPI Component Architecture
+ * iASL Compiler/Disassembler version 20251212 (64-bit version)
+ * Copyright (c) 2000 - 2025 Intel Corporation
+ *
+ * Template for [XSDT] ACPI Table (static data table)
+ * Format: [ByteLength] FieldName : HexFieldValue
+ */
+[0004] Signature : "XSDT" [Extended System Description Table]
+[0004] Table Length : 00000064
+[0001] Revision : 01
+[0001] Checksum : 8B
+[0006] Oem ID : "INTEL "
+[0008] Oem Table ID : "TEMPLATE"
+[0004] Oem Revision : 00000001
+[0004] Asl Compiler ID : "INTL"
+[0004] Asl Compiler Revision : 20100528
+
+[0008] ACPI Table Address 0 : 0000000000000010
+[0008] ACPI Table Address 1 : 0000000000000020
+[0008] ACPI Table Address 2 : 0000000000000030
+[0008] ACPI Table Address 3 : 0000000000000040
+[0008] ACPI Table Address 4 : 0000000000000050
+[0008] ACPI Table Address 5 : 0000000000000060
+[0008] ACPI Table Address 6 : 0000000000000070
+[0008] ACPI Table Address 7 : 0000000000000080
diff --git a/libs/acpi/test_data/tables.S b/libs/acpi/test_data/tables.S
index da9a12f..641db6a 100644
--- a/libs/acpi/test_data/tables.S
+++ b/libs/acpi/test_data/tables.S
@@ -11,6 +11,7 @@
TABLE(basic_madt, "basic_madt.aml")
TABLE(basic_rsdt, "basic_rsdt.aml")
TABLE(basic_rsdp, "basic_rsdp.aml")
+TABLE(basic_xsdt, "basic_xsdt.aml")
TABLE(table_header, "table_header.aml")
#undef TABLE
diff --git a/libs/acpi/test_data/tables.hpp b/libs/acpi/test_data/tables.hpp
index dc39b37..e91f1a5 100644
--- a/libs/acpi/test_data/tables.hpp
+++ b/libs/acpi/test_data/tables.hpp
@@ -18,6 +18,7 @@ namespace acpi::test_data::tables
TABLE(basic_madt);
TABLE(basic_rsdt);
TABLE(basic_rsdp);
+ TABLE(basic_xsdt);
TABLE(table_header);
} // namespace acpi::test_data::tables