diff options
Diffstat (limited to 'kapi')
| -rw-r--r-- | kapi/CMakeLists.txt | 8 | ||||
| -rw-r--r-- | kapi/include/kapi/acpi.hpp | 64 | ||||
| -rw-r--r-- | kapi/src/acpi.cpp | 68 |
3 files changed, 137 insertions, 3 deletions
diff --git a/kapi/CMakeLists.txt b/kapi/CMakeLists.txt index c9aa23f..eeda158 100644 --- a/kapi/CMakeLists.txt +++ b/kapi/CMakeLists.txt @@ -1,4 +1,6 @@ -add_library("kapi" INTERFACE) +add_library("kapi" STATIC + "src/acpi.cpp" +) add_library("os::kapi" ALIAS "kapi") file(GLOB_RECURSE KAPI_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "include/**.hpp") @@ -10,11 +12,11 @@ target_sources("kapi" PUBLIC ${KAPI_HEADERS} ) -target_include_directories("kapi" INTERFACE +target_include_directories("kapi" PUBLIC "include" ) -target_link_libraries("kapi" INTERFACE +target_link_libraries("kapi" PUBLIC "libs::kstd" "gcc" diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp new file mode 100644 index 0000000..20e5e77 --- /dev/null +++ b/kapi/include/kapi/acpi.hpp @@ -0,0 +1,64 @@ +#ifndef TEACHOS_KAPI_ACPI_HPP +#define TEACHOS_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-api-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 + { + std::array<char, 4> signature; + std::uint32_t length; + std::uint8_t revision; + std::uint8_t checksum; + std::array<char, 6> oem_id; + std::array<char, 8> oem_table_id; + std::uint32_t oem_revision; + std::uint32_t creator_id; + std::uint32_t create_revision; + }; + +} // namespace kapi::acpi + +#endif diff --git a/kapi/src/acpi.cpp b/kapi/src/acpi.cpp new file mode 100644 index 0000000..aa0066d --- /dev/null +++ b/kapi/src/acpi.cpp @@ -0,0 +1,68 @@ +#include "kapi/acpi.hpp" + +#include "kapi/memory.hpp" + +#include <kstd/units> + +#include <algorithm> +#include <bit> +#include <cstddef> +#include <cstdint> +#include <span> +#include <string_view> + +namespace kapi::acpi +{ + + namespace + { + constexpr auto validate_checksum(std::span<std::byte const> data) -> bool + { + auto sum = std::ranges::fold_left( + data, std::uint8_t{}, [](std::uint8_t acc, auto byte) { return static_cast<std::uint8_t>(byte) + acc; }); + return sum == 0; + } + } // 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}); + } + +}; // namespace kapi::acpi |
