#include "kapi/acpi.hpp" #include "kapi/memory.hpp" #include "kapi/system.hpp" #include "kernel/acpi/manager.hpp" #include #include #include #include #include #include #include #include #include namespace kapi::acpi { namespace { auto constinit manager = std::optional{}; } // namespace 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(m_rsdt_address); return memory::physical_address{static_cast(raw)}; } auto root_system_description_pointer::validate() const noexcept -> bool { return validate_checksum({reinterpret_cast(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(m_xsdt_address)}; } auto extended_system_description_pointer::validate() const noexcept -> bool { return validate_checksum({reinterpret_cast(this), m_length}); } auto init(root_system_description_pointer const & sdp) -> bool { auto static constinit initialized = std::atomic_flag{}; if (initialized.test_and_set()) { system::panic("[OS::ACPI] The ACPI manager has already been initialized!"); } manager.emplace(sdp); return manager->load_tables(); } auto validate_checksum(std::span data) -> bool { auto sum = std::ranges::fold_left(data, std::uint8_t{}, [](auto acc, auto byte) { return static_cast(acc + static_cast(byte)); }); return sum == 0; } }; // namespace kapi::acpi