diff options
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(); + } + |
