diff options
| -rw-r--r-- | arch/x86_64/kapi/platform.cpp | 49 | ||||
| -rw-r--r-- | kapi/include/kapi/acpi.hpp | 107 | ||||
| -rw-r--r-- | kapi/include/kapi/acpi/multiple_apic_description_table.hpp | 104 | ||||
| -rw-r--r-- | kapi/include/kapi/acpi/pointers.hpp | 79 | ||||
| -rw-r--r-- | kapi/include/kapi/acpi/system_description_table_header.hpp | 76 | ||||
| -rw-r--r-- | kapi/include/kapi/acpi/table_iterator.hpp | 64 | ||||
| -rw-r--r-- | kapi/include/kapi/acpi/table_type.hpp | 22 | ||||
| -rw-r--r-- | kernel/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | kernel/kapi/acpi.cpp | 124 | ||||
| -rw-r--r-- | kernel/kapi/acpi/multiple_apic_description_table.cpp | 70 | ||||
| -rw-r--r-- | kernel/kapi/acpi/pointers.cpp | 55 | ||||
| -rw-r--r-- | kernel/kapi/acpi/system_description_table_header.cpp | 51 |
12 files changed, 565 insertions, 239 deletions
diff --git a/arch/x86_64/kapi/platform.cpp b/arch/x86_64/kapi/platform.cpp index 4ee35c7..fb27329 100644 --- a/arch/x86_64/kapi/platform.cpp +++ b/arch/x86_64/kapi/platform.cpp @@ -8,57 +8,54 @@ #include <kstd/memory> #include <kstd/print> -#include <cstddef> +#include <ranges> #include <utility> namespace kapi::platform { + namespace + { + constexpr auto candidate_flags = acpi::processor_local_apic::flags::processor_enabled // + | acpi::processor_local_apic::flags::online_capable; + } auto discover_cpu_topology(kapi::devices::bus & bus) -> bool { 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("APIC"); + auto madt = kapi::acpi::get_table<acpi::madt_table_signature>(); if (!madt) { kstd::println("[x86_64:PLT] Failed to find ACPI APIC table"); return false; } - auto real_madt = static_cast<acpi::madt_header const *>(madt.get()); - auto current = reinterpret_cast<std::byte const *>(madt.get()) + sizeof(kapi::acpi::madt_header); - auto end = reinterpret_cast<std::byte const *>(madt.get()) + madt->length(); - auto bsp_found = false; auto core_count = 0uz; + auto local_apic_address = madt->local_interrupt_controller_address(); - while (current < end) + auto lapic_entries = *madt | std::views::filter([](auto const & entry) { + return entry.type() == acpi::multiple_apic_description_table_entry::types::processor_local_apic; + }) | std::views::transform([](auto 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); + }); + + for (auto const & apic : lapic_entries) { - auto const * sub_table = reinterpret_cast<kapi::acpi::madt_subtable_header const *>(current); - if (sub_table->type() == 0) + auto is_bsp = !bsp_found; + bsp_found = true; + auto instance = kstd::make_unique<arch::devices::local_apic>(interrupt_controller_major, core_count, + apic.apic_id(), local_apic_address, is_bsp); + if (kapi::platform::cpu_detected(bus, core_major, core_count, apic.processor_id(), is_bsp, std::move(instance))) { - auto const * local_apic = reinterpret_cast<kapi::acpi::madt_local_apic const *>(sub_table); - if (local_apic->flags() & 0b11) - { - auto is_bsp = !bsp_found; - bsp_found = true; - auto lapic = kstd::make_unique<arch::devices::local_apic>( - interrupt_controller_major, core_count, local_apic->apic_id(), - real_madt->local_interrupt_controller_address(), is_bsp); - if (kapi::platform::cpu_detected(bus, core_major, core_count, local_apic->processor_id(), is_bsp, - std::move(lapic))) - { - ++core_count; - } - } + ++core_count; } - - current += sub_table->length(); } kstd::println("[x86_64:PLT] Found {} CPU cores", core_count); - return core_count > 0; } diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp index 75b6c48..5323fee 100644 --- a/kapi/include/kapi/acpi.hpp +++ b/kapi/include/kapi/acpi.hpp @@ -1,14 +1,15 @@ #ifndef TEACHOS_KAPI_ACPI_HPP #define TEACHOS_KAPI_ACPI_HPP -#include "kapi/memory.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 <array> #include <cstddef> -#include <cstdint> #include <span> #include <string_view> @@ -18,91 +19,6 @@ namespace kapi::acpi //! @addtogroup kapi-acpi-kernel-defined //! @{ - struct [[gnu::packed]] root_system_description_pointer - { - [[nodiscard]] auto oem_id() const noexcept -> std::string_view; - [[nodiscard]] auto revision() const noexcept -> std::uint8_t; - [[nodiscard]] auto signature() const noexcept -> std::string_view; - [[nodiscard]] auto table_address() const noexcept -> memory::physical_address; - [[nodiscard]] auto validate() const noexcept -> bool; - - private: - std::array<char, 8> m_signature; - [[maybe_unused]] std::uint8_t m_checksum; - std::array<char, 6> m_oem_id; - std::uint8_t m_revision; - std::array<std::byte, 4> m_rsdt_address; - }; - - struct [[gnu::packed]] extended_system_description_pointer : root_system_description_pointer - { - [[nodiscard]] auto length() const noexcept -> kstd::units::bytes; - [[nodiscard]] auto table_address() const noexcept -> memory::physical_address; - [[nodiscard]] auto validate() const noexcept -> bool; - - private: - std::uint32_t m_length; - std::array<std::byte, 8> m_xsdt_address; - [[maybe_unused]] std::uint8_t m_extended_checksum; - [[maybe_unused]] std::array<std::byte, 3> m_reserved; - }; - - struct [[gnu::packed]] system_description_table_header - { - [[nodiscard]] auto checksum() const noexcept -> std::uint8_t; - [[nodiscard]] auto creator_revision() const noexcept -> std::uint32_t; - [[nodiscard]] auto creator_id() const noexcept -> std::uint32_t; - [[nodiscard]] auto length() const noexcept -> kstd::units::bytes; - [[nodiscard]] auto oem_id() const noexcept -> std::string_view; - [[nodiscard]] auto oem_revision() const noexcept -> std::uint32_t; - [[nodiscard]] auto oem_table_id() const noexcept -> std::string_view; - [[nodiscard]] auto revision() const noexcept -> std::uint8_t; - [[nodiscard]] auto signature() const noexcept -> std::string_view; - - private: - std::array<char, 4> m_signature; - std::uint32_t m_length; - std::uint8_t m_revision; - std::uint8_t m_checksum; - std::array<char, 6> m_oem_id; - std::array<char, 8> m_oem_table_id; - std::uint32_t m_oem_revision; - std::uint32_t m_creator_id; - std::uint32_t m_creator_revision; - }; - - struct [[gnu::packed]] madt_header : system_description_table_header - { - [[nodiscard]] auto local_interrupt_controller_address() const noexcept -> memory::physical_address; - [[nodiscard]] auto flags() const noexcept -> std::uint32_t; - - private: - std::uint32_t m_local_interrupt_controller_address; - std::uint32_t m_flags; - }; - - struct [[gnu::packed]] madt_subtable_header - { - [[nodiscard]] auto type() const noexcept -> std::uint8_t; - [[nodiscard]] auto length() const noexcept -> std::size_t; - - private: - std::uint8_t m_type; - std::uint8_t m_length; - }; - - struct [[gnu::packed]] madt_local_apic : madt_subtable_header - { - [[nodiscard]] auto apic_id() const noexcept -> std::uint8_t; - [[nodiscard]] auto flags() const noexcept -> std::uint32_t; - [[nodiscard]] auto processor_id() const noexcept -> std::uint32_t; - - private: - std::uint8_t m_processor_id; - std::uint8_t m_apic_id; - std::uint32_t m_flags; - }; - //! Initialize the ACPI subsystem and discover the available tables. //! //! @return true iff. a valid system description tabled was found, false otherwise. @@ -114,17 +30,30 @@ namespace kapi::acpi //! @return true iff. the checksum is valid, false otherwise. auto validate_checksum(std::span<std::byte const> data) -> bool; - //! Get an ACPI table by its signature. + //! 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>; + //! 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> + { + return kstd::make_observer(static_cast<table_type_t<Signature> const *>(get_table(Signature).get())); + } + //! @} //! @addtogroup kapi-acpi-platform-defined //! @{ + //! 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>; //! @} diff --git a/kapi/include/kapi/acpi/multiple_apic_description_table.hpp b/kapi/include/kapi/acpi/multiple_apic_description_table.hpp new file mode 100644 index 0000000..33acac9 --- /dev/null +++ b/kapi/include/kapi/acpi/multiple_apic_description_table.hpp @@ -0,0 +1,104 @@ +#ifndef TEACHOS_KAPI_ACPI_MUTIPLE_APIC_DESCRIPTION_TABLE_HEADER_HPP +#define TEACHOS_KAPI_ACPI_MUTIPLE_APIC_DESCRIPTION_TABLE_HEADER_HPP + +// IWYU pragma: private, include "kapi/acpi.hpp" + +#include "kapi/acpi/system_description_table_header.hpp" +#include "kapi/acpi/table_iterator.hpp" +#include "kapi/acpi/table_type.hpp" +#include "kapi/memory.hpp" + +#include <kstd/ext/bitfield_enum> +#include <kstd/units> + +#include <cstddef> +#include <cstdint> +#include <type_traits> + +namespace kapi::acpi +{ + + //! @addtogroup kapi-acpi-kernel-defined + //! @{ + + struct [[gnu::packed]] multiple_apic_description_table_entry + { + enum struct types : std::uint8_t + { + processor_local_apic, + io_apic, + io_apic_interrupt_source_override, + io_apic_nmi_source, + local_apic_nmi_interrupts, + local_apic_address_override, + processor_local_x2_apic, + }; + + [[nodiscard]] auto type() const noexcept -> types; + [[nodiscard]] auto length() const noexcept -> std::size_t; + + private: + std::uint8_t m_type; + std::uint8_t m_length; + }; + + //! The common header for all + struct [[gnu::packed]] multiple_apic_description_table : system_description_table_header + { + using iterator = table_iterator<multiple_apic_description_table_entry const>; + using const_iterator = iterator; + + [[nodiscard]] auto local_interrupt_controller_address() const noexcept -> memory::physical_address; + [[nodiscard]] auto flags() const noexcept -> std::uint32_t; + + [[nodiscard]] auto begin() const noexcept -> iterator; + [[nodiscard]] auto cbegin() const noexcept -> iterator; + [[nodiscard]] auto end() const noexcept -> iterator; + [[nodiscard]] auto cend() const noexcept -> iterator; + + private: + std::uint32_t m_local_interrupt_controller_address; + std::uint32_t m_flags; + }; + + struct [[gnu::packed]] processor_local_apic : multiple_apic_description_table_entry + { + enum struct flags : std::uint32_t + { + processor_enabled = 1, + online_capable = 2, + }; + + [[nodiscard]] auto apic_id() const noexcept -> std::uint8_t; + [[nodiscard]] auto active_flags() const noexcept -> flags; + [[nodiscard]] auto processor_id() const noexcept -> std::uint32_t; + + private: + std::uint8_t m_processor_id; + std::uint8_t m_apic_id; + std::uint32_t m_flags; + }; + + //! @} + + //! @addtogroup kapi-acpi + //! @{ + + constexpr char const madt_table_signature[] = "APIC"; // NOLINT + + template<> + struct table_type<madt_table_signature> + { + using type = multiple_apic_description_table; + }; + + //! @} + +} // namespace kapi::acpi + +template<> +struct kstd::ext::is_bitfield_enum<kapi::acpi::processor_local_apic::flags> : std::true_type +{ +}; + +#endif diff --git a/kapi/include/kapi/acpi/pointers.hpp b/kapi/include/kapi/acpi/pointers.hpp new file mode 100644 index 0000000..2b88720 --- /dev/null +++ b/kapi/include/kapi/acpi/pointers.hpp @@ -0,0 +1,79 @@ +#ifndef TEACHOS_KAPI_ACPI_POINTERS_HPP +#define TEACHOS_KAPI_ACPI_POINTERS_HPP + +// IWYU pragma: private, include "kapi/acpi.hpp" + +#include "kapi/memory.hpp" + +#include <kstd/units> + +#include <array> +#include <cstddef> +#include <cstdint> +#include <string_view> + +namespace kapi::acpi +{ + + //! @addtogroup kapi-acpi-kernel-defined + //! @{ + + //! A pointer to the Root System Description Table. + struct [[gnu::packed]] root_system_description_pointer + { + //! Get the ID of the OEM, usually a vendor name. + [[nodiscard]] auto oem_id() const noexcept -> std::string_view; + + //! Get the revision of the ACPI Root System Description Table. + //! + //! @note Revisions greater or equal to two indicate that the system uses the Extended System Description Table, and + //! as such that table should be use to query information. + [[nodiscard]] auto revision() const noexcept -> std::uint8_t; + + //! Get the signature of this pointer. + //! + //! A valid RSDP must always carry the signature "RSD PTR ". + [[nodiscard]] auto signature() const noexcept -> std::string_view; + + //! Get the physical address of the pointed-to Root System Description Table. + [[nodiscard]] auto table_address() const noexcept -> memory::physical_address; + + //! Validate the checksum of this RSDP. + //! + //! @return @p true iff. the checksum of this RSDP is valid, @p false otherwise. + [[nodiscard]] auto validate() const noexcept -> bool; + + private: + std::array<char, 8> m_signature; + [[maybe_unused]] std::uint8_t m_checksum; + std::array<char, 6> m_oem_id; + std::uint8_t m_revision; + std::array<std::byte, 4> m_rsdt_address; + }; + + //! A pointer to the Extended System Description Table. + struct [[gnu::packed]] extended_system_description_pointer : root_system_description_pointer + { + //! Get the length of the data contained in this pointer. + [[nodiscard]] auto length() const noexcept -> kstd::units::bytes; + + //! Get the address of the pointed-to Extended System Description Table. + [[nodiscard]] auto table_address() const noexcept -> memory::physical_address; + + //! Validate the checksum of this XSDP. + //! + //! @return @p true iff. the checksum of this RSDP is valid, @p false otherwise. + [[nodiscard]] auto validate() const noexcept -> bool; + + private: + std::uint32_t m_length; + std::array<std::byte, 8> m_xsdt_address; + [[maybe_unused]] std::uint8_t m_extended_checksum; + [[maybe_unused]] std::array<std::byte, 3> m_reserved; + }; + + //! @} + +} // namespace kapi::acpi + +#endif diff --git a/kapi/include/kapi/acpi/system_description_table_header.hpp b/kapi/include/kapi/acpi/system_description_table_header.hpp new file mode 100644 index 0000000..b336ea1 --- /dev/null +++ b/kapi/include/kapi/acpi/system_description_table_header.hpp @@ -0,0 +1,76 @@ +#ifndef TEACHOS_KAPI_ACPI_SYSTEM_DESCRIPTION_TABLE_HEADER_HPP +#define TEACHOS_KAPI_ACPI_SYSTEM_DESCRIPTION_TABLE_HEADER_HPP + +// IWYU pragma: private, include "kapi/acpi.hpp" + +#include "kapi/acpi/table_type.hpp" + +#include <kstd/units> + +#include <array> +#include <cstdint> +#include <string_view> + +namespace kapi::acpi +{ + + //! @addtogroup kapi-acpi-kernel-defined + //! @{ + + //! The common header of all System Description Tables. + struct [[gnu::packed]] system_description_table_header + { + //! Get the revision of the utility used to create this table. + [[nodiscard]] auto creator_revision() const noexcept -> std::uint32_t; + + //! Get the vendor ID of the utility used to create this table. + [[nodiscard]] auto creator_id() const noexcept -> std::uint32_t; + + //! Get the length of the entire table, including this header. + [[nodiscard]] auto length() const noexcept -> kstd::units::bytes; + + //! Get the ID of the OEM. + [[nodiscard]] auto oem_id() const noexcept -> std::string_view; + + //! Get the OEMs revision number of this table. + [[nodiscard]] auto oem_revision() const noexcept -> std::uint32_t; + + //! Get the OEMs ID of this table. + [[nodiscard]] auto oem_table_id() const noexcept -> std::string_view; + + //! Get the revision number of the structure of this table. + [[nodiscard]] auto revision() const noexcept -> std::uint8_t; + + //! Get the signature of this table. + [[nodiscard]] auto signature() const noexcept -> std::string_view; + + private: + std::array<char, 4> m_signature; + std::uint32_t m_length; + std::uint8_t m_revision; + [[maybe_unused]] std::uint8_t m_checksum; + std::array<char, 6> m_oem_id; + std::array<char, 8> m_oem_table_id; + std::uint32_t m_oem_revision; + std::uint32_t m_creator_id; + std::uint32_t m_creator_revision; + }; + + //! @} + // + //! @addtogroup kapi-acpi + //! @{ + + constexpr char const rsdt_table_signature[] = "RSDT"; // NOLINT + + template<> + struct table_type<rsdt_table_signature> + { + using type = system_description_table_header; + }; + + //! @} + +} // namespace kapi::acpi + +#endif diff --git a/kapi/include/kapi/acpi/table_iterator.hpp b/kapi/include/kapi/acpi/table_iterator.hpp new file mode 100644 index 0000000..998d6d6 --- /dev/null +++ b/kapi/include/kapi/acpi/table_iterator.hpp @@ -0,0 +1,64 @@ +#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 new file mode 100644 index 0000000..e088a24 --- /dev/null +++ b/kapi/include/kapi/acpi/table_type.hpp @@ -0,0 +1,22 @@ +#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 67db0a8..8af6fe7 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,6 +1,9 @@ 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/kapi/acpi.cpp b/kernel/kapi/acpi.cpp index 1283d7e..e7c4921 100644 --- a/kernel/kapi/acpi.cpp +++ b/kernel/kapi/acpi.cpp @@ -1,16 +1,13 @@ #include "kapi/acpi.hpp" -#include "kapi/memory.hpp" #include "kapi/system.hpp" #include "kernel/acpi/manager.hpp" #include <kstd/memory> -#include <kstd/units> #include <algorithm> #include <atomic> -#include <bit> #include <cstddef> #include <cstdint> #include <optional> @@ -25,127 +22,6 @@ namespace kapi::acpi auto constinit manager = std::optional<kernel::acpi::manager>{}; } // 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<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}); - } - - [[nodiscard]] auto system_description_table_header::checksum() const noexcept -> std::uint8_t - { - return m_checksum; - } - - [[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()}; - } - - [[nodiscard]] auto madt_header::local_interrupt_controller_address() const noexcept -> memory::physical_address - { - return memory::physical_address{static_cast<std::uintptr_t>(m_local_interrupt_controller_address)}; - } - - [[nodiscard]] auto madt_header::flags() const noexcept -> std::uint32_t - { - return m_flags; - } - - [[nodiscard]] auto madt_subtable_header::type() const noexcept -> std::uint8_t - { - return m_type; - } - - [[nodiscard]] auto madt_subtable_header::length() const noexcept -> std::size_t - { - return m_length; - } - - [[nodiscard]] auto madt_local_apic::apic_id() const noexcept -> std::uint8_t - { - return m_apic_id; - } - - [[nodiscard]] auto madt_local_apic::flags() const noexcept -> std::uint32_t - { - return m_flags; - } - - [[nodiscard]] auto madt_local_apic::processor_id() const noexcept -> std::uint32_t - { - return m_processor_id; - } - auto init(root_system_description_pointer const & sdp) -> bool { auto static constinit initialized = std::atomic_flag{}; diff --git a/kernel/kapi/acpi/multiple_apic_description_table.cpp b/kernel/kapi/acpi/multiple_apic_description_table.cpp new file mode 100644 index 0000000..c0360a3 --- /dev/null +++ b/kernel/kapi/acpi/multiple_apic_description_table.cpp @@ -0,0 +1,70 @@ +#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 new file mode 100644 index 0000000..63831e9 --- /dev/null +++ b/kernel/kapi/acpi/pointers.cpp @@ -0,0 +1,55 @@ +#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 new file mode 100644 index 0000000..f688b4d --- /dev/null +++ b/kernel/kapi/acpi/system_description_table_header.cpp @@ -0,0 +1,51 @@ +#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 |
