diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2025-12-11 18:36:23 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2025-12-11 18:36:23 +0100 |
| commit | cf8d0d899ee17db734ce8ab7ee618333eb1767f2 (patch) | |
| tree | 8ff328c106d9f928423dfa860567fbf6dbf84f88 /kapi | |
| parent | 998a001fc621ca0e7560ca09a8acd29469ae3373 (diff) | |
| download | teachos-cf8d0d899ee17db734ce8ab7ee618333eb1767f2.tar.xz teachos-cf8d0d899ee17db734ce8ab7ee618333eb1767f2.zip | |
kapi: finish documentation
Diffstat (limited to 'kapi')
| -rw-r--r-- | kapi/include/kapi/boot.hpp | 6 | ||||
| -rw-r--r-- | kapi/include/kapi/cio.hpp | 61 | ||||
| -rw-r--r-- | kapi/include/kapi/cpu.hpp | 8 | ||||
| -rw-r--r-- | kapi/include/kapi/memory.hpp | 33 | ||||
| -rw-r--r-- | kapi/include/kapi/memory/address.hpp | 37 | ||||
| -rw-r--r-- | kapi/include/kapi/memory/page.hpp | 39 | ||||
| -rw-r--r-- | kapi/include/kapi/memory/page_mapper.hpp | 77 | ||||
| -rw-r--r-- | kapi/include/kapi/system.hpp | 8 | ||||
| -rw-r--r-- | kapi/src/cio.cpp | 21 |
9 files changed, 222 insertions, 68 deletions
diff --git a/kapi/include/kapi/boot.hpp b/kapi/include/kapi/boot.hpp index 013e180..9c344cf 100644 --- a/kapi/include/kapi/boot.hpp +++ b/kapi/include/kapi/boot.hpp @@ -3,8 +3,14 @@ namespace teachos::boot { + //! @qualifier platform-defined + //! Information passed from the early pre-main stage to the kernel executable. + //! + //! The specific structure of this type is defined on a platform level. struct information; + //! @qualifier platform-defined + //! An object passed from the early pre-main stage to the kernel executable. extern "C" information const bootstrap_information; } // namespace teachos::boot diff --git a/kapi/include/kapi/cio.hpp b/kapi/include/kapi/cio.hpp index a01af08..a2be97e 100644 --- a/kapi/include/kapi/cio.hpp +++ b/kapi/include/kapi/cio.hpp @@ -6,26 +6,77 @@ namespace teachos::cio { - // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions) + + //! The interface of a device able to perform character output on a platform. struct output_device { + output_device(output_device const &) = delete; + output_device(output_device &&) = delete; + auto operator=(output_device const &) -> output_device & = delete; + auto operator=(output_device &&) -> output_device & = delete; + virtual ~output_device() = default; - auto virtual write(std::string_view text [[maybe_unused]]) -> void {} - auto virtual writeln(std::string_view text [[maybe_unused]]) -> void {} + //! Write the given text to the output device. + //! + //! @param text The text to write. + auto virtual write(std::string_view text) -> void = 0; + + //! Write the given text to the output device, appending a newline + //! + //! @param text The text to write. + auto virtual writeln(std::string_view text) -> void = 0; + + //! Write the given error text to the output device. + //! + //! @param text The text to write. + auto virtual write_error(std::string_view text) -> void = 0; - auto virtual write_error(std::string_view text [[maybe_unused]]) -> void {} - auto virtual writeln_error(std::string_view text [[maybe_unused]]) -> void {} + //! Write the given error text to the output device, appending a newline + //! + //! @param text The text to write. + auto virtual writeln_error(std::string_view text) -> void = 0; + + protected: + output_device() = default; }; + //! @qualifier platform-defined + //! Initialize the character I/O subsystem. + //! + //! @note If a platform support character output, it shall ensure that when this function returns, basic character + //! output can be performed on the system. auto init() -> void; + //! @qualifier kernel-defined + //! Set the currently active output device. + //! + //! @param device A new output device. + //! @return The previously active output device. auto set_output_device(output_device & device) -> std::optional<output_device *>; + //! @qualifier kernel-defined + //! Print the given text to the currently active output device. + //! + //! @param text The text to print. auto print(std::string_view text) -> void; + + //! @qualifier kernel-defined + //! Print the given text, including a newline, to the currently active output device. + //! + //! @param text The text to print. auto println(std::string_view text) -> void; + //! @qualifier kernel-defined + //! Print the given error text, to the currently active output device. + //! + //! @param text The error text to print. auto print_error(std::string_view text) -> void; + + //! @qualifier kernel-defined + //! Print the given error text, including a newline, to the currently active output device. + //! + //! @param text The error text to print. auto println_error(std::string_view text) -> void; } // namespace teachos::cio diff --git a/kapi/include/kapi/cpu.hpp b/kapi/include/kapi/cpu.hpp index 673deab..0a26bcf 100644 --- a/kapi/include/kapi/cpu.hpp +++ b/kapi/include/kapi/cpu.hpp @@ -3,10 +3,10 @@ namespace teachos::cpu { - /** - * @brief Halt the CPU, effectively terminating kernel execution. - * - */ + //! @qualifier platform-defined + //! Halt the CPU. + //! + //! This function terminates execution of the kernel. [[noreturn]] auto halt() -> void; } // namespace teachos::cpu diff --git a/kapi/include/kapi/memory.hpp b/kapi/include/kapi/memory.hpp index 9ca1267..2f45611 100644 --- a/kapi/include/kapi/memory.hpp +++ b/kapi/include/kapi/memory.hpp @@ -9,9 +9,38 @@ namespace teachos::memory { - auto active_allocator() -> frame_allocator &; - auto active_mapper() -> page_mapper &; + + //! @qualifier platform-defined + //! Get the currently active frame allocator. + //! + //! @note This function must be implemented by the target platform. + //! + //! @warning If no allocator has been initialized yet, the behavior of this function is platform implementation + //! defined. Implementations are encouraged to terminate execution via a kernel panic. + //! + //! @return A reference to the currently active frame allocator. + auto active_frame_allocator() -> frame_allocator &; + + //! @qualifier platform-defined + //! Get the currently active page mapper. + //! + //! @note This function must be implemented by the target platform. + //! + //! @warning If no mapper has been initialized yet, the behavior of this function is platform implementation + //! defined. Implementations are encouraged to terminate execution via a kernel panic. + //! + //! @return A reference to the currently active page mapper. + auto active_page_mapper() -> page_mapper &; + + //! @qualifier platform-defined + //! Initialize the memory subsystem. + //! + //! @note This function must be implemented by the target platform. + //! + //! This function initializes the memory subsystem and activates the platform-specific frame allocator and page + //! mapper. When this function returns, a valid frame allocator and page mapper are expected to have been registered. auto init() -> void; + } // namespace teachos::memory #endif diff --git a/kapi/include/kapi/memory/address.hpp b/kapi/include/kapi/memory/address.hpp index b861ef5..d5496e4 100644 --- a/kapi/include/kapi/memory/address.hpp +++ b/kapi/include/kapi/memory/address.hpp @@ -11,54 +11,89 @@ namespace teachos::memory { + //! @qualifier kernel-defined + //! A tag for different address types. enum struct address_type : bool { linear, physical, }; + //! @qualifier kernel-defined + //! A physical or virtual address. + //! + //! This convenience wrapper type is used to ensure that no linear address is passed where a physical one is expected + //! and vice versa. + //! + //! @tparam Type The type of address. template<address_type Type> struct address { + //! Construct a null-address. constexpr explicit address() noexcept = default; + //! Construct an address representing the given value. + //! + //! @param value The raw value to initialize this address with. constexpr explicit address(std::uintptr_t value) noexcept : m_value{value} {} + //! Construct an address representing the given pointer value. + //! + //! @param pointer The pointer value to initialize this address with. explicit address(std::byte * pointer) noexcept : m_value{std::bit_cast<std::uintptr_t>(pointer)} {} + //! Convert this address into a C++ pointer. explicit operator std::byte *() const noexcept { return std::bit_cast<std::byte *>(m_value); } + //! Shift this address n bits to the right. + //! + //! @param n The width of the shift. + //! @return A new address representing the result of the shift operation. constexpr auto operator>>(std::size_t n) const noexcept -> address { return address{m_value >> n}; } + //! Apply the given mask to this address. + //! + //! @param mask The mask to apply + //! @return A new address representing the result of the masking operation. template<typename MaskType> constexpr auto operator&(MaskType mask) const noexcept -> MaskType { return static_cast<MaskType>(m_value & mask); } - constexpr auto operator<=>(address const &) const noexcept -> std::strong_ordering = default; + //! Check if this address is equal to another one. constexpr auto operator==(address const &) const noexcept -> bool = default; + //! Lexicographically compare this address with another one. + constexpr auto operator<=>(address const &) const noexcept -> std::strong_ordering = default; + + //! Extract the raw value from this address. + //! + //! @return The raw value of this address. [[nodiscard]] constexpr auto raw() const noexcept -> std::uintptr_t { return m_value; } private: + //! The raw address value. std::uintptr_t m_value{}; }; + //! A linear/virtual address. using linear_address = address<address_type::linear>; + + //! A physical address. using physical_address = address<address_type::physical>; } // namespace teachos::memory diff --git a/kapi/include/kapi/memory/page.hpp b/kapi/include/kapi/memory/page.hpp index 9bb22e9..66e8482 100644 --- a/kapi/include/kapi/memory/page.hpp +++ b/kapi/include/kapi/memory/page.hpp @@ -11,53 +11,58 @@ namespace teachos::memory { + //! @qualifier kernel-defined + //! A handle to a page of virtual memory. struct page { + //! The platform-dependent size of a single page of memory. constexpr auto static size = PLATFORM_FRAME_SIZE; + //! Construct a handle referencing the first page of virtual memory. constexpr page() = default; + //! Construct a handle referencing the page of virtual memory with the given page number. explicit constexpr page(std::size_t number) : m_number{number} {} - /** - * @brief Returns the virtual page the given address is contained in. - * - * @param address Linear address we want to get the corresponding virtual page for. - * @return Page the given address is contained in. - */ + //! Construct a new page handle for the page containing the given address. + //! + //! @param address A linear address contained by the desired page. + //! @return A handle to a page containing the given address. constexpr auto static containing(linear_address address) noexcept -> page { return page{address.raw() / size}; } - /** - * @brief Get the start address of this virtual page. - * - * @return Start address of the virtual page. - */ + //! Get the start address of the page referenced by this handle. + //! + //! @return The address of the first byte contained by the page referenced by this handle. [[nodiscard]] constexpr auto start_address() const noexcept -> linear_address { return linear_address{m_number * size}; } + //! Get the number of the page referenced by this handle. + //! + //! @return The zero-based number of the page referenced by this handle. [[nodiscard]] constexpr auto number() const noexcept -> std::size_t { return m_number; } - /** - * @brief Check if this page refers to the same page as @p other. - */ + //! Check if this page handle reference the same frame as another one. + //! + //! @param other Another page handle. constexpr auto operator==(page const & other) const noexcept -> bool = default; - /** - * @brief Lexicographically compare this page to @p other. - */ + //! Compare the number of the page referenced by this handle to the one reference by another one. + //! + //! @param other Another page handle. constexpr auto operator<=>(page const & other) const noexcept -> std::strong_ordering = default; private: + //! The number of the currently referenced page. std::size_t m_number{}; }; diff --git a/kapi/include/kapi/memory/page_mapper.hpp b/kapi/include/kapi/memory/page_mapper.hpp index aa5cf76..2396249 100644 --- a/kapi/include/kapi/memory/page_mapper.hpp +++ b/kapi/include/kapi/memory/page_mapper.hpp @@ -13,60 +13,65 @@ namespace teachos::memory { - // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions) + //! @qualifier platform-implemented + //! The interface of a type allowing the mapping, and unmapping, of pages onto frames. struct page_mapper { + page_mapper(page_mapper const &) = delete; + page_mapper(page_mapper &&) = delete; + auto operator=(page_mapper const &) -> page_mapper & = delete; + auto operator=(page_mapper &&) -> page_mapper & = delete; + + //! Platform independent page mapping flags enum struct flags : std::uint64_t { empty, - writable = 1 << 0, - executable = 1 << 1, - uncached = 1 << 2, - supervisor = 1 << 3, + writable = 1 << 0, //! The page is writable. + executable = 1 << 1, //! The page contains executable instructions. + uncached = 1 << 2, //! The page contents must not be cached. + supervisor_only = 1 << 3, //! The page is only accessible in supervisor mode. }; virtual ~page_mapper() = default; - /** - * Map a page into a given frame, applying the given flags. - * - * @param page The page to map. - * @param frame The frame to map the page into. - * @param flags The flags to map the page with. - * @return A pointer to the first byte of mapped page. - */ + //! Map a page into a given frame, applying the given flags. + //! + //! @param page The page to map. + //! @param frame The frame to map the page into. + //! @param flags The flags to map the page with. + //! @return A pointer to the first byte of mapped page. virtual auto map(page page, frame frame, flags flags) -> std::byte * = 0; - /** - * Unmap the given page. - * - * @warning If the provided page is not mapped, this function will panic. - * @param page The page to unmap. - */ + //! Unmap the given page. + //! + //! @warning If the provided page is not mapped, the behavior is undefined. Implementation are encourage to + //! terminate execution via a kernel panic. + //! + //! @param page The page to unmap. virtual auto unmap(page page) -> void = 0; - /** - * Try to unmap the given page. - * - * @param page The page to unmap - * @return true iff. the page was successfully unmapped, false otherwise. - */ - virtual auto try_unmap(page page) -> bool = 0; - - /** - * Map a page into a given frame, applyint the given flags. - * - * @tparam T The type of data contained in the page. - * @param page The page to map. - * @param frame The frame to map the page into. - * @param flags The flags to map the page with. - * @return A pointer to the first T in the page. - */ + //! Try to unmap the given page. + //! + //! @param page The page to unmap + //! @return true iff. the page was successfully unmapped, false otherwise. + virtual auto try_unmap(page page) noexcept -> bool = 0; + + //! @qualifier kernel-defined + //! Map a page into a given frame, applyint the given flags. + //! + //! @tparam T The type of data contained in the page. + //! @param page The page to map. + //! @param frame The frame to map the page into. + //! @param flags The flags to map the page with. + //! @return A pointer to the first T in the page. template<typename T> [[nodiscard]] auto map_as(page page, frame frame, flags flags) -> T * { return std::bit_cast<T *>(map(page, frame, flags)); } + + protected: + page_mapper() = default; }; } // namespace teachos::memory diff --git a/kapi/include/kapi/system.hpp b/kapi/include/kapi/system.hpp index b0b0e28..e6b9826 100644 --- a/kapi/include/kapi/system.hpp +++ b/kapi/include/kapi/system.hpp @@ -6,7 +6,15 @@ namespace teachos::system { + + //! @qualifier kernel-defined + //! Terminate kernel execution with the given error message. + //! + //! This function terminates the execution of the kernel and attempts to issue the given error message to the user. + //! + //! @param message The message associated with the panic [[noreturn]] auto panic(std::string_view message, std::source_location = std::source_location::current()) -> void; + } // namespace teachos::system #endif diff --git a/kapi/src/cio.cpp b/kapi/src/cio.cpp index 210e58e..66493b6 100644 --- a/kapi/src/cio.cpp +++ b/kapi/src/cio.cpp @@ -1,14 +1,29 @@ #include "kapi/cio.hpp" #include <optional> +#include <string_view> #include <utility> namespace teachos::cio { + namespace + { + struct null_device final : public output_device + { + null_device static instance; + + auto write(std::string_view) -> void override {} + auto writeln(std::string_view) -> void override {} + + auto write_error(std::string_view) -> void override {} + auto writeln_error(std::string_view) -> void override {} + }; + + constinit null_device null_device::instance; + } // namespace + // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) - auto constinit null_device = output_device{}; - // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) - auto constinit active_device = &null_device; + constinit auto active_device = static_cast<output_device *>(&null_device::instance); auto set_output_device(output_device & device) -> std::optional<output_device *> { |
