diff options
Diffstat (limited to 'kapi')
| -rw-r--r-- | kapi/include/kapi/acpi.hpp | 134 | ||||
| -rw-r--r-- | kapi/include/kapi/devices/bus.hpp | 56 | ||||
| -rw-r--r-- | kapi/include/kapi/devices/device.hpp | 30 | ||||
| -rw-r--r-- | kapi/include/kapi/memory/layout.hpp | 12 | ||||
| -rw-r--r-- | kapi/include/kapi/platform.hpp | 34 |
5 files changed, 196 insertions, 70 deletions
diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp new file mode 100644 index 0000000..75b6c48 --- /dev/null +++ b/kapi/include/kapi/acpi.hpp @@ -0,0 +1,134 @@ +#ifndef TEACHOS_KAPI_ACPI_HPP +#define TEACHOS_KAPI_ACPI_HPP + +#include "kapi/memory.hpp" + +#include <kstd/memory> +#include <kstd/units> + +#include <array> +#include <cstddef> +#include <cstdint> +#include <span> +#include <string_view> + +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. + 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; + + //! Get 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>; + + //! @} + + //! @addtogroup kapi-acpi-platform-defined + //! @{ + + auto get_root_pointer() -> kstd::observer_ptr<root_system_description_pointer const>; + + //! @} + +} // namespace kapi::acpi + +#endif diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index 052c062..7b2d41f 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -1,24 +1,22 @@ #ifndef TEACHOS_KAPI_DEVICES_BUS_HPP #define TEACHOS_KAPI_DEVICES_BUS_HPP +// IWYU pragma: private, include "kapi/devices.hpp" + #include "kapi/devices/device.hpp" -#include "kapi/devices/manager.hpp" -#include "kapi/system.hpp" #include <kstd/memory> #include <kstd/print> #include <kstd/string> #include <kstd/vector> -#include <algorithm> #include <atomic> #include <cstddef> -#include <utility> namespace kapi::devices { - //! @addtogroup kapi-devices + //! @addtogroup kapi-devices-kernel-defined //! @{ //! A bus device that represents a logical/physical tree of devices and busses. @@ -29,65 +27,27 @@ namespace kapi::devices //! @param major The major number of the bus. //! @param minor The minor number of the bus. //! @param name The name of the bus. - bus(std::size_t major, std::size_t minor, kstd::string const & name) - : device(major, minor, name) - {} + bus(std::size_t major, std::size_t minor, kstd::string const & name); //! Initialize the bus and all of its children. //! //! @return true iff. the bus and all of its children are healthy, false otherwise. - auto init() -> bool final - { - if (m_initialized.test_and_set()) - { - return true; - } - - if (!probe()) - { - return false; - } - - return std::ranges::fold_left(m_devices, true, [&](bool acc, auto & child) -> bool { - kstd::println("[kAPI:BUS] Initializing child device {}@{}", child->name(), name()); - return child->init() && acc; - }); - } + auto init() -> bool final; //! Attach a child device to this bus. //! //! Whenever a device is attached to a bus, the bus takes sole ownership of the device. //! //! @param child The child device to attach. - auto add_child(kstd::unique_ptr<device> child) -> void - { - auto observer = m_observers.emplace_back(child.get()); - m_devices.push_back(std::move(child)); - kapi::devices::register_device(*observer); - - if (m_initialized.test()) - { - kstd::println("[kAPI:BUS] Initializing child device {}@{}", observer->name(), name()); - if (!observer->init()) - { - kapi::system::panic("[kAPI:BUS] Failed to initialize child device"); - } - } - } + auto add_child(kstd::unique_ptr<device> child) -> void; - [[nodiscard]] auto children() const -> kstd::vector<kstd::observer_ptr<device>> const & - { - return m_observers; - } + [[nodiscard]] auto children() const -> kstd::vector<kstd::observer_ptr<device>> const &; protected: //! Probe the bus hardware state. //! //! @return true iff. the bus hardware is healthy, false otherwise. - auto virtual probe() -> bool - { - return true; - } + auto virtual probe() -> bool; private: kstd::vector<kstd::unique_ptr<device>> m_devices; diff --git a/kapi/include/kapi/devices/device.hpp b/kapi/include/kapi/devices/device.hpp index b7b6bba..b3647da 100644 --- a/kapi/include/kapi/devices/device.hpp +++ b/kapi/include/kapi/devices/device.hpp @@ -1,6 +1,8 @@ #ifndef TEACH_OS_KAPI_DEVICES_DEVICE_HPP #define TEACH_OS_KAPI_DEVICES_DEVICE_HPP +// IWYU pragma: private, include "kapi/devices.hpp" + #include <kstd/string> #include <cstddef> @@ -8,7 +10,7 @@ namespace kapi::devices { - //! @addtogroup kapi-devices + //! @addtogroup kapi-devices-kernel-defined //! @{ /** @@ -22,11 +24,7 @@ namespace kapi::devices * @param minor Device minor number. * @param name Device name. */ - device(size_t major, size_t minor, kstd::string const & name) - : m_major(major) - , m_minor(minor) - , m_name(name) - {} + device(size_t major, size_t minor, kstd::string const & name); /** * @brief Virtual destructor for device. @@ -43,37 +41,25 @@ namespace kapi::devices * @brief Returns the major number of the device. * @return Device major number. */ - [[nodiscard]] auto major() const -> size_t - { - return m_major; - } + [[nodiscard]] auto major() const -> size_t; /** * @brief Returns the minor number of the device. * @return Device minor number. */ - [[nodiscard]] auto minor() const -> size_t - { - return m_minor; - } + [[nodiscard]] auto minor() const -> size_t; /** * @brief Returns the name of the device. * @return Device name. */ - [[nodiscard]] auto name() const -> kstd::string const & - { - return m_name; - } + [[nodiscard]] auto name() const -> kstd::string const &; /** * @brief Check if the device is a block device. * @return true if this device is a block device, false otherwise. */ - [[nodiscard]] virtual auto is_block_device() const -> bool - { - return false; - } + [[nodiscard]] virtual auto is_block_device() const -> bool; private: size_t m_major; diff --git a/kapi/include/kapi/memory/layout.hpp b/kapi/include/kapi/memory/layout.hpp index 157f41e..26b48d8 100644 --- a/kapi/include/kapi/memory/layout.hpp +++ b/kapi/include/kapi/memory/layout.hpp @@ -37,6 +37,18 @@ namespace kapi::memory //! The linear base address of the loaded kernel image. constexpr auto kernel_base = linear_address{0xffff'ffff'8000'0000uz}; + //! Convert a physical address to a linear address using the higher-half direct map. + constexpr auto hhdm_to_linear(physical_address address) -> linear_address + { + return linear_address{address.raw() + higher_half_direct_map_base.raw()}; + } + + //! Convert a linear address in the higher-half direct map to a physical address. + constexpr auto hhdm_to_physical(linear_address address) -> physical_address + { + return physical_address{address.raw() - higher_half_direct_map_base.raw()}; + } + } // namespace kapi::memory #endif
\ No newline at end of file diff --git a/kapi/include/kapi/platform.hpp b/kapi/include/kapi/platform.hpp new file mode 100644 index 0000000..e1e267e --- /dev/null +++ b/kapi/include/kapi/platform.hpp @@ -0,0 +1,34 @@ +#ifndef TEACHOS_KAPI_PLATFORM_HPP +#define TEACHOS_KAPI_PLATFORM_HPP + +#include "kapi/devices.hpp" + +#include <kstd/memory> + +#include <cstddef> +#include <cstdint> + +namespace kapi::platform +{ + + //! @addtogroup kapi-platform-kernel-defined + //! @{ + + auto cpu_detected(kapi::devices::bus & bus, std::size_t major, std::size_t minor, std::uint64_t hardware_id, + bool is_bsp, kstd::unique_ptr<devices::device> core_interrupt_controller) -> bool; + //! @} + + //! @addtogroup kapi-platform-platform-defined + //! @{ + + //! Discover the CPU topology of the platform and attach it to the given CPU bus. + //! + //! @param bus The bus to attach the CPU topology to. + //! @return true iff. the CPU topology was discovered successfully, false otherwise. + auto discover_cpu_topology(kapi::devices::bus & bus) -> bool; + + //! @} + +} // namespace kapi::platform + +#endif
\ No newline at end of file |
