aboutsummaryrefslogtreecommitdiff
path: root/kapi
diff options
context:
space:
mode:
Diffstat (limited to 'kapi')
-rw-r--r--kapi/include/kapi/acpi.hpp134
-rw-r--r--kapi/include/kapi/devices/bus.hpp56
-rw-r--r--kapi/include/kapi/devices/device.hpp30
-rw-r--r--kapi/include/kapi/memory/layout.hpp12
-rw-r--r--kapi/include/kapi/platform.hpp34
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