From 035c8d6e38fd901e6769a81f67b8d9e1e3fcea20 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 26 Feb 2026 11:24:27 +0100 Subject: implemented boot_modules and boot_module_registry, init boot_modules in kernel main --- kapi/CMakeLists.txt | 3 + kapi/include/kapi/boot_module/boot_module.hpp | 21 ++++ .../kapi/boot_module/boot_module_registry.hpp | 108 +++++++++++++++++++++ kapi/include/kapi/boot_modules.hpp | 25 +++++ 4 files changed, 157 insertions(+) create mode 100644 kapi/include/kapi/boot_module/boot_module.hpp create mode 100644 kapi/include/kapi/boot_module/boot_module_registry.hpp create mode 100644 kapi/include/kapi/boot_modules.hpp (limited to 'kapi') diff --git a/kapi/CMakeLists.txt b/kapi/CMakeLists.txt index 5e914bb..028cdbb 100644 --- a/kapi/CMakeLists.txt +++ b/kapi/CMakeLists.txt @@ -5,8 +5,11 @@ target_sources("kapi" PUBLIC FILE_SET HEADERS BASE_DIRS "include" FILES + "include/kapi/boot_modules.hpp" "include/kapi/boot.hpp" "include/kapi/cio.hpp" + "include/kapi/boot_module/boot_module.hpp" + "include/kapi/boot_module/boot_module_registry.hpp" "include/kapi/memory.hpp" "include/kapi/memory/address.hpp" "include/kapi/memory/frame_allocator.hpp" diff --git a/kapi/include/kapi/boot_module/boot_module.hpp b/kapi/include/kapi/boot_module/boot_module.hpp new file mode 100644 index 0000000..f2d97ae --- /dev/null +++ b/kapi/include/kapi/boot_module/boot_module.hpp @@ -0,0 +1,21 @@ +#ifndef TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_HPP +#define TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_HPP + +#include +#include + +namespace kapi::boot_modules +{ + // ! The boot module struct + // ! + // ! The boot module struct represents a module loaded by the bootloader, and contains information about it, such as + // ! its name, virtual start address, and size. + struct boot_module + { + std::string_view name; + size_t start_address; + size_t size; + }; +} // namespace kapi::boot_modules + +#endif \ No newline at end of file diff --git a/kapi/include/kapi/boot_module/boot_module_registry.hpp b/kapi/include/kapi/boot_module/boot_module_registry.hpp new file mode 100644 index 0000000..3732a5f --- /dev/null +++ b/kapi/include/kapi/boot_module/boot_module_registry.hpp @@ -0,0 +1,108 @@ +#ifndef TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_REGISTRY_HPP +#define TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_REGISTRY_HPP + +#include "kapi/boot_module/boot_module.hpp" + +#include +#include + +namespace kapi::boot_modules +{ + + // ! The interface of the boot module registry + // ! + // ! The boot module registry is responsible for keeping track of the modules loaded by the bootloader, and + // ! providing access to them for the rest of the kernel. + struct boot_module_registry + { + using range_type = std::array; // TODO BA-FS26 use kstd::vector when available + + using value_type = range_type::value_type; + using const_reference = range_type::const_reference; + + using const_iterator = range_type::const_iterator; + using const_reverse_iterator = range_type::const_reverse_iterator; + using size_type = range_type::size_type; + using difference_type = range_type::difference_type; + + [[nodiscard]] auto begin() const noexcept -> const_iterator + { + return m_modules.begin(); + } + + [[nodiscard]] auto end() const noexcept -> const_iterator + { + return m_modules.end(); + } + + [[nodiscard]] auto cbegin() const noexcept -> const_iterator + { + return begin(); + } + + [[nodiscard]] auto cend() const noexcept -> const_iterator + { + return end(); + } + + [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator + { + return m_modules.rbegin(); + } + + [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator + { + return m_modules.rend(); + } + + [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator + { + return rbegin(); + } + + [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator + { + return rend(); + } + + [[nodiscard]] auto front() const noexcept -> const_reference + { + return m_modules.front(); + } + + [[nodiscard]] auto back() const noexcept -> const_reference + { + return m_modules.back(); + } + + [[nodiscard]] auto size() const noexcept -> std::size_t + { + return m_modules.size(); + } + + [[nodiscard]] auto empty() const noexcept -> bool + { + return m_modules.empty(); + } + + [[nodiscard]] auto at(std::size_t index) const -> const_reference + { + return m_modules.at(index); + } + + [[nodiscard]] auto operator[](std::size_t index) const noexcept -> const_reference + { + return m_modules[index]; + } + + auto add_boot_module(boot_module module) -> void + { + m_modules.at(0) = module; // TODO BA-FS26 push back when kstd::vector is available + } + + private: + range_type m_modules{}; + }; +} // namespace kapi::boot_modules + +#endif \ No newline at end of file diff --git a/kapi/include/kapi/boot_modules.hpp b/kapi/include/kapi/boot_modules.hpp new file mode 100644 index 0000000..752b070 --- /dev/null +++ b/kapi/include/kapi/boot_modules.hpp @@ -0,0 +1,25 @@ +#ifndef TEACHOS_KAPI_BOOT_MODULES_HPP +#define TEACHOS_KAPI_BOOT_MODULES_HPP + +#include "kapi/boot_module/boot_module_registry.hpp" // IWYU pragma: export + +namespace kapi::boot_modules +{ + + //! @qualifier platform-defined + //! Initialize the boot module registry. + //! + //! @note This function must be implemented by the target platform. + //! + //! This function initializes the boot module registry, which is responsible for keeping track of the modules loaded + //! by the bootloader, and providing access to them for the rest of the kernel. + auto init() -> void; + + //! @qualifier kernel-defined + //! Set the boot module registry + //! + //! @param registry A new boot module registry. + auto set_boot_module_registry(boot_module_registry & registry) -> void; + +} // namespace kapi::boot_modules +#endif \ No newline at end of file -- cgit v1.2.3 From e84c7fbf336847d3ff62aac10ed8f6d04a06cbe8 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 27 Feb 2026 19:27:41 +0100 Subject: use linear_address instead of size_t --- kapi/include/kapi/boot_module/boot_module.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'kapi') diff --git a/kapi/include/kapi/boot_module/boot_module.hpp b/kapi/include/kapi/boot_module/boot_module.hpp index f2d97ae..729efc9 100644 --- a/kapi/include/kapi/boot_module/boot_module.hpp +++ b/kapi/include/kapi/boot_module/boot_module.hpp @@ -1,6 +1,8 @@ #ifndef TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_HPP #define TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_HPP +#include "kapi/memory.hpp" + #include #include @@ -13,7 +15,7 @@ namespace kapi::boot_modules struct boot_module { std::string_view name; - size_t start_address; + memory::linear_address start_address{}; size_t size; }; } // namespace kapi::boot_modules -- cgit v1.2.3 From 296d58550e8e1202d83e66034c24e9454a1b67dc Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 27 Feb 2026 23:23:18 +0100 Subject: - add boot_module_registry getter --- kapi/include/kapi/boot_module/boot_module_registry.hpp | 2 +- kapi/include/kapi/boot_modules.hpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'kapi') diff --git a/kapi/include/kapi/boot_module/boot_module_registry.hpp b/kapi/include/kapi/boot_module/boot_module_registry.hpp index 3732a5f..eeb01ff 100644 --- a/kapi/include/kapi/boot_module/boot_module_registry.hpp +++ b/kapi/include/kapi/boot_module/boot_module_registry.hpp @@ -15,7 +15,7 @@ namespace kapi::boot_modules // ! providing access to them for the rest of the kernel. struct boot_module_registry { - using range_type = std::array; // TODO BA-FS26 use kstd::vector when available + using range_type = std::array; // TODO BA-FS26 use kstd::vector when available using value_type = range_type::value_type; using const_reference = range_type::const_reference; diff --git a/kapi/include/kapi/boot_modules.hpp b/kapi/include/kapi/boot_modules.hpp index 752b070..6eee169 100644 --- a/kapi/include/kapi/boot_modules.hpp +++ b/kapi/include/kapi/boot_modules.hpp @@ -21,5 +21,11 @@ namespace kapi::boot_modules //! @param registry A new boot module registry. auto set_boot_module_registry(boot_module_registry & registry) -> void; + //! @qualifier kernel-defined + //! Get the boot module registry. + //! + //! @returns The boot module registry. + auto get_boot_module_registry() -> boot_module_registry &; + } // namespace kapi::boot_modules #endif \ No newline at end of file -- cgit v1.2.3 From 5801be615a50bf465a9663b7f75cafbcf0870f5c Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 17 Mar 2026 11:49:13 +0100 Subject: use kstd::vector instead of std::array and replace plain-pointers with kstd::shared_ptr --- kapi/include/kapi/boot_module/boot_module_registry.hpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/boot_module/boot_module_registry.hpp b/kapi/include/kapi/boot_module/boot_module_registry.hpp index eeb01ff..70b5592 100644 --- a/kapi/include/kapi/boot_module/boot_module_registry.hpp +++ b/kapi/include/kapi/boot_module/boot_module_registry.hpp @@ -3,7 +3,8 @@ #include "kapi/boot_module/boot_module.hpp" -#include +#include + #include namespace kapi::boot_modules @@ -15,15 +16,13 @@ namespace kapi::boot_modules // ! providing access to them for the rest of the kernel. struct boot_module_registry { - using range_type = std::array; // TODO BA-FS26 use kstd::vector when available - + using range_type = kstd::vector; using value_type = range_type::value_type; using const_reference = range_type::const_reference; - using const_iterator = range_type::const_iterator; - using const_reverse_iterator = range_type::const_reverse_iterator; + using const_iterator = range_type::const_pointer; + using const_reverse_iterator = range_type::const_pointer; using size_type = range_type::size_type; - using difference_type = range_type::difference_type; [[nodiscard]] auto begin() const noexcept -> const_iterator { @@ -97,7 +96,7 @@ namespace kapi::boot_modules auto add_boot_module(boot_module module) -> void { - m_modules.at(0) = module; // TODO BA-FS26 push back when kstd::vector is available + m_modules.push_back(module); } private: -- cgit v1.2.3 From 483b7789c38e42b26fbdbf10601fe47567078a50 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 17 Mar 2026 22:32:06 +0100 Subject: kapi/memory: remove penalizing explicit --- kapi/include/kapi/memory/address.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kapi') diff --git a/kapi/include/kapi/memory/address.hpp b/kapi/include/kapi/memory/address.hpp index 3bef358..69fc7b9 100644 --- a/kapi/include/kapi/memory/address.hpp +++ b/kapi/include/kapi/memory/address.hpp @@ -33,7 +33,7 @@ namespace kapi::memory struct address { //! Construct a null-address. - constexpr explicit address() noexcept = default; + constexpr address() noexcept = default; //! Construct an address representing the given value. //! -- cgit v1.2.3 From d2e7a4e2fd5a2973b6c9071951eaf8b2d24d84a3 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 17 Mar 2026 22:32:52 +0100 Subject: kapi/bootm: initialize all members --- kapi/include/kapi/boot_module/boot_module.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/boot_module/boot_module.hpp b/kapi/include/kapi/boot_module/boot_module.hpp index 729efc9..85a1ac5 100644 --- a/kapi/include/kapi/boot_module/boot_module.hpp +++ b/kapi/include/kapi/boot_module/boot_module.hpp @@ -14,9 +14,9 @@ namespace kapi::boot_modules // ! its name, virtual start address, and size. struct boot_module { - std::string_view name; + std::string_view name{}; memory::linear_address start_address{}; - size_t size; + std::size_t size{}; }; } // namespace kapi::boot_modules -- cgit v1.2.3 From 12c0586ee15cadfa178e6982dc0f76b047cb2df9 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 18 Mar 2026 15:24:26 +0100 Subject: kapi/memory: remove page/frame size macros --- kapi/CMakeLists.txt | 6 ------ kapi/include/kapi/memory/layout.hpp | 20 +++++++++++++++++--- 2 files changed, 17 insertions(+), 9 deletions(-) (limited to 'kapi') diff --git a/kapi/CMakeLists.txt b/kapi/CMakeLists.txt index 028cdbb..b239adb 100644 --- a/kapi/CMakeLists.txt +++ b/kapi/CMakeLists.txt @@ -29,9 +29,3 @@ target_link_libraries("kapi" INTERFACE "gcc" "stdc++" ) - -target_compile_definitions("kapi" INTERFACE - "PLATFORM_PAGE_SIZE=${TEACHOS_PLATFORM_PAGE_SIZE}uz" - "PLATFORM_PAGING_LEVELS=${TEACHOS_PLATFORM_PAGING_LEVELS}uz" - "PLATFORM_FRAME_SIZE=${TEACHOS_PLATFORM_FRAME_SIZE}uz" -) diff --git a/kapi/include/kapi/memory/layout.hpp b/kapi/include/kapi/memory/layout.hpp index f5ba0f9..d4153d8 100644 --- a/kapi/include/kapi/memory/layout.hpp +++ b/kapi/include/kapi/memory/layout.hpp @@ -8,17 +8,31 @@ namespace kapi::memory { - constexpr auto page_size = PLATFORM_PAGE_SIZE; - constexpr auto frame_size = PLATFORM_FRAME_SIZE; - + //! The size of a single page of virtual memory. + //! + //! Platforms that use different sizes of pages are expected to emulate 4 KiB pages towards the kernel. + constexpr auto page_size = 4096uz; + + //! The size of a single frame of physical memory. + //! + //! Platforms that use different sizes of frames are expected to emulate 4 KiB pages towards the kernel. + constexpr auto frame_size = 4096uz; + + //! The linear base address of the higher-half direct map. + //! + //! Platforms are expected to provide a mapping of at least the first 512 GiB of available memory at this address. constexpr auto higher_half_direct_map_base = linear_address{0xffff'8000'0000'0000uz}; + //! The linear base address of the kernel heap. constexpr auto heap_base = linear_address{0xffff'c000'0000'0000uz}; + //! The linear base address of the memory region reserved for the metadata required by the PMM. constexpr auto pmm_metadata_base = linear_address{0xffff'd000'0000'0000uz}; + //! The linear base address of all Memory Mapped I/O mappings. constexpr auto mmio_base = linear_address{0xffff'e000'0000'0000uz}; + //! The linear base address of the loaded kernel image. constexpr auto kernel_base = linear_address{0xffff'ffff'8000'0000uz}; } // namespace kapi::memory -- cgit v1.2.3 From e7ccb96aecae7b231fb05818d7e45a767aebc31d Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 18 Mar 2026 17:18:37 +0100 Subject: kstd: introduce strong type for memory amounts --- kapi/include/kapi/memory/address.hpp | 11 +++++++++++ kapi/include/kapi/memory/chunk.hpp | 8 +++++--- kapi/include/kapi/memory/layout.hpp | 6 ++++-- 3 files changed, 20 insertions(+), 5 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/memory/address.hpp b/kapi/include/kapi/memory/address.hpp index 69fc7b9..587aeac 100644 --- a/kapi/include/kapi/memory/address.hpp +++ b/kapi/include/kapi/memory/address.hpp @@ -4,6 +4,7 @@ // IWYU pragma: private, include "kapi/memory.hpp" #include +#include #include #include @@ -183,6 +184,16 @@ namespace kapi::memory return static_cast(m_value & mask); } + constexpr auto operator+(kstd::units::bytes n) const noexcept -> address + { + return address{m_value + n.value}; + } + + constexpr auto operator+=(kstd::units::bytes n) noexcept -> address & + { + return *this = *this + n; + } + //! Check if this address is equal to another one. constexpr auto operator==(address const &) const noexcept -> bool = default; diff --git a/kapi/include/kapi/memory/chunk.hpp b/kapi/include/kapi/memory/chunk.hpp index 4529535..a046221 100644 --- a/kapi/include/kapi/memory/chunk.hpp +++ b/kapi/include/kapi/memory/chunk.hpp @@ -3,6 +3,8 @@ // IWYU pragma: private, include "kapi/memory.hpp" +#include + #include #include @@ -15,7 +17,7 @@ namespace kapi::memory //! @tparam ChunkType The CRTP type of the deriving class //! @tparam AddressType The type of addresses used to index this chunk //! @tparam Size The size of this chunk. - template + template struct chunk { //! The type of addresses used to index this chunk @@ -30,7 +32,7 @@ namespace kapi::memory //! @return A handle to a chunk containing the given address. constexpr auto static containing(address_type address) noexcept -> ChunkType { - return ChunkType{address / size}; + return ChunkType{address / size.value}; } //! Get the start address of the chunk referenced by this handle. @@ -38,7 +40,7 @@ namespace kapi::memory //! @return The address of the first byte contained by the chunk referenced by this handle. [[nodiscard]] constexpr auto start_address() const noexcept -> address_type { - return address_type{m_number * size}; + return address_type{(m_number * size).value}; } //! Get the number of the chunk referenced by this handle. diff --git a/kapi/include/kapi/memory/layout.hpp b/kapi/include/kapi/memory/layout.hpp index d4153d8..157f41e 100644 --- a/kapi/include/kapi/memory/layout.hpp +++ b/kapi/include/kapi/memory/layout.hpp @@ -5,18 +5,20 @@ #include "kapi/memory/address.hpp" +#include + namespace kapi::memory { //! The size of a single page of virtual memory. //! //! Platforms that use different sizes of pages are expected to emulate 4 KiB pages towards the kernel. - constexpr auto page_size = 4096uz; + constexpr auto page_size = kstd::units::KiB(4); //! The size of a single frame of physical memory. //! //! Platforms that use different sizes of frames are expected to emulate 4 KiB pages towards the kernel. - constexpr auto frame_size = 4096uz; + constexpr auto frame_size = kstd::units::KiB(4); //! The linear base address of the higher-half direct map. //! -- cgit v1.2.3 From ae2a264b117ecf556f742d8e9c357f906cb3fd83 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 19 Mar 2026 13:00:08 +0100 Subject: kstd: finish preliminary vector implementation --- kapi/include/kapi/boot_module/boot_module_registry.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/boot_module/boot_module_registry.hpp b/kapi/include/kapi/boot_module/boot_module_registry.hpp index 70b5592..0692d37 100644 --- a/kapi/include/kapi/boot_module/boot_module_registry.hpp +++ b/kapi/include/kapi/boot_module/boot_module_registry.hpp @@ -20,8 +20,8 @@ namespace kapi::boot_modules using value_type = range_type::value_type; using const_reference = range_type::const_reference; - using const_iterator = range_type::const_pointer; - using const_reverse_iterator = range_type::const_pointer; + using const_iterator = range_type::const_iterator; + using const_reverse_iterator = range_type::const_reverse_iterator; using size_type = range_type::size_type; [[nodiscard]] auto begin() const noexcept -> const_iterator -- cgit v1.2.3 From 4f942e014dab44ccb8850c5921b81d4bd777d831 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 20 Mar 2026 11:19:05 +0100 Subject: kstd: rework formatting to be closer to std --- kapi/include/kapi/memory/address.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/memory/address.hpp b/kapi/include/kapi/memory/address.hpp index 587aeac..13bdf4c 100644 --- a/kapi/include/kapi/memory/address.hpp +++ b/kapi/include/kapi/memory/address.hpp @@ -229,13 +229,13 @@ namespace kstd { constexpr auto static suffix = Type == kapi::memory::address_type::linear ? "%lin" : "%phy"; - constexpr auto parse(std::string_view context) -> std::string_view + constexpr auto parse(format_parse_context & context) -> format_parse_context::iterator { auto result = formatter::parse(context); - if (!this->specs.type) + if (!this->specifiers.type) { - this->specs.type = 'p'; - this->specs.alternative_form = true; + this->specifiers.type = 'p'; + this->specifiers.alternative_form = true; } return result; } -- cgit v1.2.3 From cb60cdebdc36dd2358fe1ce06eec197e213af491 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 24 Mar 2026 17:35:54 +0100 Subject: kapi/cpu: introduce CPU API --- kapi/include/kapi/cpu.hpp | 7 +++++ kapi/include/kapi/cpu/exception.hpp | 60 +++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 kapi/include/kapi/cpu/exception.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/cpu.hpp b/kapi/include/kapi/cpu.hpp index 05b84b7..1dd7cfe 100644 --- a/kapi/include/kapi/cpu.hpp +++ b/kapi/include/kapi/cpu.hpp @@ -1,6 +1,8 @@ #ifndef TEACHOS_KAPI_CPU_HPP #define TEACHOS_KAPI_CPU_HPP +#include "kapi/cpu/exception.hpp" + namespace kapi::cpu { //! @qualifier platform-defined @@ -8,6 +10,11 @@ namespace kapi::cpu //! //! This function terminates execution of the kernel. [[noreturn]] auto halt() -> void; + + //! @qualifier platform-defined + //! Perform early CPU initialization. + auto init() -> void; + } // namespace kapi::cpu #endif diff --git a/kapi/include/kapi/cpu/exception.hpp b/kapi/include/kapi/cpu/exception.hpp new file mode 100644 index 0000000..09e15a7 --- /dev/null +++ b/kapi/include/kapi/cpu/exception.hpp @@ -0,0 +1,60 @@ +#ifndef TEACHOS_KAPI_CPU_EXCEPTION_HPP +#define TEACHOS_KAPI_CPU_EXCEPTION_HPP + +// IWYU pragma: private, include "kapi/cpu.hpp" + +#include "kapi/memory.hpp" + +#include + +namespace kapi::cpu +{ + + struct exception + { + enum class type : std::uint8_t + { + unknown, + page_fault, + alignment_fault, + memory_access_fault, + illegal_instruction, + privilege_violation, + arithmetic_error, + breakpoint, + single_step, + }; + + //! The type of exception. + type type{}; + + //! The instruction pointer at the time of the exception. + kapi::memory::linear_address instruction_pointer{}; + + //! The memory address that caused the exception. + kapi::memory::linear_address access_address{}; + + //! Whether the page was present at the time of the exception. + bool is_present{}; + + //! Whether the exception was caused by a write access. + bool is_write_access{}; + + //! Whether the exception was caused by a user mode access. + bool is_user_mode{}; + }; + + struct exception_handler + { + virtual ~exception_handler() = default; + + virtual auto handle(exception const & context) -> bool = 0; + }; + + auto get_exception_handler() -> exception_handler &; + + auto set_exception_handler(exception_handler & handler) -> void; + +} // namespace kapi::cpu + +#endif \ No newline at end of file -- cgit v1.2.3 From 42895684b631380c8aca94f82209297ac0c0e5f2 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 24 Mar 2026 17:44:21 +0100 Subject: kapi: extract interrupt enablement --- kapi/include/kapi/cpu.hpp | 3 ++- kapi/include/kapi/cpu/interrupts.hpp | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 kapi/include/kapi/cpu/interrupts.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/cpu.hpp b/kapi/include/kapi/cpu.hpp index 1dd7cfe..ade954c 100644 --- a/kapi/include/kapi/cpu.hpp +++ b/kapi/include/kapi/cpu.hpp @@ -1,7 +1,8 @@ #ifndef TEACHOS_KAPI_CPU_HPP #define TEACHOS_KAPI_CPU_HPP -#include "kapi/cpu/exception.hpp" +#include "kapi/cpu/exception.hpp" // IWYU pragma: export +#include "kapi/cpu/interrupts.hpp" // IWYU pragma: export namespace kapi::cpu { diff --git a/kapi/include/kapi/cpu/interrupts.hpp b/kapi/include/kapi/cpu/interrupts.hpp new file mode 100644 index 0000000..26a215e --- /dev/null +++ b/kapi/include/kapi/cpu/interrupts.hpp @@ -0,0 +1,19 @@ +#ifndef TEACHOS_KAPI_CPU_INTERRUPTS_HPP +#define TEACHOS_KAPI_CPU_INTERRUPTS_HPP + +// IWYU pragma: private, include "kapi/cpu.hpp" + +namespace kapi::cpu +{ + + //! @qualifier platform-defined + //! Enable external interrupts. + auto enable_interrupts() -> void; + + //! @qualifier platform-defined + //! Disable external interrupts. + auto disable_interrupts() -> void; + +} // namespace kapi::cpu + +#endif \ No newline at end of file -- cgit v1.2.3 From 9b879b06e202a41cdecc25e08ed5e69c57814141 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 25 Mar 2026 07:44:57 +0100 Subject: kapi: add missing header to build --- kapi/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) (limited to 'kapi') diff --git a/kapi/CMakeLists.txt b/kapi/CMakeLists.txt index b239adb..4c94829 100644 --- a/kapi/CMakeLists.txt +++ b/kapi/CMakeLists.txt @@ -8,6 +8,9 @@ target_sources("kapi" PUBLIC "include/kapi/boot_modules.hpp" "include/kapi/boot.hpp" "include/kapi/cio.hpp" + "include/kapi/cpu.hpp" + "include/kapi/cpu/interrupts.hpp" + "include/kapi/cpu/exception.hpp" "include/kapi/boot_module/boot_module.hpp" "include/kapi/boot_module/boot_module_registry.hpp" "include/kapi/memory.hpp" -- cgit v1.2.3 From fd6ac1cbfbe90fa807dca60657bb80ed43c78aee Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 25 Mar 2026 07:45:08 +0100 Subject: kapi/cpu: improve documentation --- kapi/include/kapi/cpu/exception.hpp | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/cpu/exception.hpp b/kapi/include/kapi/cpu/exception.hpp index 09e15a7..6d39175 100644 --- a/kapi/include/kapi/cpu/exception.hpp +++ b/kapi/include/kapi/cpu/exception.hpp @@ -10,28 +10,40 @@ namespace kapi::cpu { + //! An exception originating from the CPU directly. + //! + //! Exception generally model interrupts that are synchronous to the instruction stream. This means that they do not + //! originate from external hardware, but rather are a product of program execution. struct exception { + //! The type of the exception, which identifies the reason for it being raised. enum class type : std::uint8_t { + //! The reason for the exception is unknown or platform-specific unknown, + //! A page fault occurred page_fault, + //! A memory access (either in the data or instruction stream) violated it's alignment constraints. alignment_fault, + //! A memory access (either in the data or instruction stream) violated it's permissions. memory_access_fault, - illegal_instruction, + //! The precoditions for the execution of an instruction were not met. privilege_violation, + //! An arithmetic error occurred. arithmetic_error, + //! A breakpoint was hit in the instruction stream. breakpoint, + //! The CPU is single-stepping through the instruction stream. single_step, }; - //! The type of exception. + //! The type of this exception. type type{}; - //! The instruction pointer at the time of the exception. + //! The value of the instruction pointer at the time this exception was raised. kapi::memory::linear_address instruction_pointer{}; - //! The memory address that caused the exception. + //! The memory address that caused this exception. kapi::memory::linear_address access_address{}; //! Whether the page was present at the time of the exception. @@ -44,15 +56,26 @@ namespace kapi::cpu bool is_user_mode{}; }; + //! The abstract interface for exception handlers. + //! + //! The kernel must define an exception handler to be used during execution. struct exception_handler { virtual ~exception_handler() = default; + //! Handle an exception. + //! + //! @param context The exception context. + //! @return Whether the exception was handled. virtual auto handle(exception const & context) -> bool = 0; }; + //! @qualifier kernel-defined + //! Get the currently active exception handler. auto get_exception_handler() -> exception_handler &; + //! @qualifier kernel-defined + //! Set the exception handler. auto set_exception_handler(exception_handler & handler) -> void; } // namespace kapi::cpu -- cgit v1.2.3 From 2f8c5ca6d5ab6131a148502e1d1be4ce2a65b339 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 25 Mar 2026 07:47:04 +0100 Subject: kapi/cpu: add missing exception type --- kapi/include/kapi/cpu/exception.hpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'kapi') diff --git a/kapi/include/kapi/cpu/exception.hpp b/kapi/include/kapi/cpu/exception.hpp index 6d39175..9fc697a 100644 --- a/kapi/include/kapi/cpu/exception.hpp +++ b/kapi/include/kapi/cpu/exception.hpp @@ -27,6 +27,8 @@ namespace kapi::cpu alignment_fault, //! A memory access (either in the data or instruction stream) violated it's permissions. memory_access_fault, + //! An invalid instruction was present in the instruction stream. + illegal_instruction, //! The precoditions for the execution of an instruction were not met. privilege_violation, //! An arithmetic error occurred. -- cgit v1.2.3 From fd1c5a50bb35f772b8e37125188640447d4b3b2a Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 25 Mar 2026 13:24:03 +0100 Subject: kapi/cpu: enable formatting of exception types --- kapi/include/kapi/cpu/exception.hpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'kapi') diff --git a/kapi/include/kapi/cpu/exception.hpp b/kapi/include/kapi/cpu/exception.hpp index 9fc697a..00b02e7 100644 --- a/kapi/include/kapi/cpu/exception.hpp +++ b/kapi/include/kapi/cpu/exception.hpp @@ -5,6 +5,8 @@ #include "kapi/memory.hpp" +#include + #include namespace kapi::cpu @@ -82,4 +84,38 @@ namespace kapi::cpu } // namespace kapi::cpu +template<> +struct kstd::formatter +{ + constexpr auto parse(kstd::format_parse_context & ctx) -> decltype(ctx.begin()) + { + return ctx.begin(); + } + + constexpr auto format(enum kapi::cpu::exception::type type, kstd::format_context & ctx) const -> void + { + switch (type) + { + case kapi::cpu::exception::type::unknown: + return ctx.push("unknown"); + case kapi::cpu::exception::type::page_fault: + return ctx.push("page fault"); + case kapi::cpu::exception::type::alignment_fault: + return ctx.push("alignment fault"); + case kapi::cpu::exception::type::memory_access_fault: + return ctx.push("memory access fault"); + case kapi::cpu::exception::type::illegal_instruction: + return ctx.push("illegal instruction"); + case kapi::cpu::exception::type::privilege_violation: + return ctx.push("privilege violation"); + case kapi::cpu::exception::type::arithmetic_error: + return ctx.push("arithmetic error"); + case kapi::cpu::exception::type::breakpoint: + return ctx.push("breakpoint"); + case kapi::cpu::exception::type::single_step: + return ctx.push("single step"); + } + } +}; + #endif \ No newline at end of file -- cgit v1.2.3 From a82416648d148152338dc612c25bf8dff428e773 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 25 Mar 2026 16:39:13 +0100 Subject: kapi: introduce cpu::interrupt_handler --- kapi/include/kapi/cpu/interrupts.hpp | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'kapi') diff --git a/kapi/include/kapi/cpu/interrupts.hpp b/kapi/include/kapi/cpu/interrupts.hpp index 26a215e..328e4a7 100644 --- a/kapi/include/kapi/cpu/interrupts.hpp +++ b/kapi/include/kapi/cpu/interrupts.hpp @@ -3,9 +3,32 @@ // IWYU pragma: private, include "kapi/cpu.hpp" +#include + namespace kapi::cpu { + enum class status : bool + { + unhandled, + handled, + }; + + //! The interface for all interrupt handlers. + struct interrupt_handler + { + virtual ~interrupt_handler() = default; + + //! Handle an interrupt with the given IRQ number. + // + //! This function will be called by the kernel in an interrupt context. As such, the function should complete its + //! task quickly and must take care when acquiring globally shared locks. + //! + //! @param irq_number The identifier of the interrupt request that triggered the handler. + //! @return status::handled if the handler successfully handled the interrupt, status::unhandled otherwise. + virtual auto handle_interrupt(std::uint32_t irq_number) -> status = 0; + }; + //! @qualifier platform-defined //! Enable external interrupts. auto enable_interrupts() -> void; @@ -14,6 +37,27 @@ namespace kapi::cpu //! Disable external interrupts. auto disable_interrupts() -> void; + //! @qualifier platform-defined + //! Register an interrupt handler for the given IRQ number. + //! + //! @param irq_number The IRQ number to register the handler for. + //! @param handler The interrupt handler to register. + auto register_interrupt_handler(std::uint32_t irq_number, interrupt_handler & handler) -> void; + + //! @qualifier platform-defined + //! Unregister a previously registered interrupt handler. + //! + //! @param irq_number The IRQ number to unregister the handler for. + //! @param handler The interrupt handler to unregister. + auto unregister_interrupt_handler(std::uint32_t irq_number, interrupt_handler & handler) -> void; + + //! @qualifier platform-defined + //! Dispatch an interrupt to all registered handlers. + //! + //! @param irq_number The IRQ number to dispatch. + //! @return status::handled if the interrupt was handled by at least one handler, status::unhandled otherwise. + auto dispatch_interrupt(std::uint32_t irq_number) -> status; + } // namespace kapi::cpu #endif \ No newline at end of file -- cgit v1.2.3 From 1cb599798a0b29302ab71d1ee0fb9febff8f6a75 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 15:24:10 +0100 Subject: kapi/cpu: update documentation of init() --- kapi/include/kapi/cpu.hpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'kapi') diff --git a/kapi/include/kapi/cpu.hpp b/kapi/include/kapi/cpu.hpp index ade954c..712de16 100644 --- a/kapi/include/kapi/cpu.hpp +++ b/kapi/include/kapi/cpu.hpp @@ -14,6 +14,9 @@ namespace kapi::cpu //! @qualifier platform-defined //! Perform early CPU initialization. + //! + //! When this function returns, the CPU is in a state where interrupt could be enabled. This function must not enable + //! interrupts itself. auto init() -> void; } // namespace kapi::cpu -- cgit v1.2.3 From 8d06763f47e7b7c93af2a55f6bd2dbc4aa9abfa2 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 16:10:50 +0100 Subject: kapi/cpu: simplify exception handling --- kapi/include/kapi/cpu/exception.hpp | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/cpu/exception.hpp b/kapi/include/kapi/cpu/exception.hpp index 00b02e7..d6e8511 100644 --- a/kapi/include/kapi/cpu/exception.hpp +++ b/kapi/include/kapi/cpu/exception.hpp @@ -31,7 +31,7 @@ namespace kapi::cpu memory_access_fault, //! An invalid instruction was present in the instruction stream. illegal_instruction, - //! The precoditions for the execution of an instruction were not met. + //! The preconditions for the execution of an instruction were not met. privilege_violation, //! An arithmetic error occurred. arithmetic_error, @@ -60,27 +60,12 @@ namespace kapi::cpu bool is_user_mode{}; }; - //! The abstract interface for exception handlers. - //! - //! The kernel must define an exception handler to be used during execution. - struct exception_handler - { - virtual ~exception_handler() = default; - - //! Handle an exception. - //! - //! @param context The exception context. - //! @return Whether the exception was handled. - virtual auto handle(exception const & context) -> bool = 0; - }; - - //! @qualifier kernel-defined - //! Get the currently active exception handler. - auto get_exception_handler() -> exception_handler &; - //! @qualifier kernel-defined - //! Set the exception handler. - auto set_exception_handler(exception_handler & handler) -> void; + //! Dispatch an exception to the appropriate handler. + //! + //! @param context The exception context. + //! @return Whether the exception was handled. + auto dispatch(exception const & context) -> bool; } // namespace kapi::cpu -- cgit v1.2.3 From 2521d58e7a5c16595e401e1af7becb572ad35f53 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 16:25:35 +0100 Subject: kapi: dissolve cpu/exception.hpp into cpu.hpp --- kapi/include/kapi/cpu.hpp | 96 +++++++++++++++++++++++++++++++- kapi/include/kapi/cpu/exception.hpp | 106 ------------------------------------ 2 files changed, 95 insertions(+), 107 deletions(-) delete mode 100644 kapi/include/kapi/cpu/exception.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/cpu.hpp b/kapi/include/kapi/cpu.hpp index 712de16..041a5db 100644 --- a/kapi/include/kapi/cpu.hpp +++ b/kapi/include/kapi/cpu.hpp @@ -1,11 +1,64 @@ #ifndef TEACHOS_KAPI_CPU_HPP #define TEACHOS_KAPI_CPU_HPP -#include "kapi/cpu/exception.hpp" // IWYU pragma: export #include "kapi/cpu/interrupts.hpp" // IWYU pragma: export +#include "kapi/memory.hpp" + +#include + +#include namespace kapi::cpu { + + //! An exception originating from the CPU directly. + //! + //! Exception generally model interrupts that are synchronous to the instruction stream. This means that they do not + //! originate from external hardware, but rather are a product of program execution. + struct exception + { + //! The type of the exception, which identifies the reason for it being raised. + enum class type : std::uint8_t + { + //! The reason for the exception is unknown or platform-specific + unknown, + //! A page fault occurred + page_fault, + //! A memory access (either in the data or instruction stream) violated it's alignment constraints. + alignment_fault, + //! A memory access (either in the data or instruction stream) violated it's permissions. + memory_access_fault, + //! An invalid instruction was present in the instruction stream. + illegal_instruction, + //! The preconditions for the execution of an instruction were not met. + privilege_violation, + //! An arithmetic error occurred. + arithmetic_error, + //! A breakpoint was hit in the instruction stream. + breakpoint, + //! The CPU is single-stepping through the instruction stream. + single_step, + }; + + //! The type of this exception. + type type{}; + + //! The value of the instruction pointer at the time this exception was raised. + kapi::memory::linear_address instruction_pointer{}; + + //! The memory address that caused this exception. + kapi::memory::linear_address access_address{}; + + //! Whether the page was present at the time of the exception. + bool is_present{}; + + //! Whether the exception was caused by a write access. + bool is_write_access{}; + + //! Whether the exception was caused by a user mode access. + bool is_user_mode{}; + }; + //! @qualifier platform-defined //! Halt the CPU. //! @@ -19,6 +72,47 @@ namespace kapi::cpu //! interrupts itself. auto init() -> void; + //! @qualifier kernel-defined + //! Dispatch an exception to the appropriate handler. + //! + //! @param context The exception context. + //! @return Whether the exception was handled. + [[nodiscard]] auto dispatch(exception const & context) -> bool; + } // namespace kapi::cpu +template<> +struct kstd::formatter +{ + constexpr auto parse(kstd::format_parse_context & ctx) -> decltype(ctx.begin()) + { + return ctx.begin(); + } + + constexpr auto format(enum kapi::cpu::exception::type type, kstd::format_context & ctx) const -> void + { + switch (type) + { + case kapi::cpu::exception::type::unknown: + return ctx.push("unknown"); + case kapi::cpu::exception::type::page_fault: + return ctx.push("page fault"); + case kapi::cpu::exception::type::alignment_fault: + return ctx.push("alignment fault"); + case kapi::cpu::exception::type::memory_access_fault: + return ctx.push("memory access fault"); + case kapi::cpu::exception::type::illegal_instruction: + return ctx.push("illegal instruction"); + case kapi::cpu::exception::type::privilege_violation: + return ctx.push("privilege violation"); + case kapi::cpu::exception::type::arithmetic_error: + return ctx.push("arithmetic error"); + case kapi::cpu::exception::type::breakpoint: + return ctx.push("breakpoint"); + case kapi::cpu::exception::type::single_step: + return ctx.push("single step"); + } + } +}; + #endif diff --git a/kapi/include/kapi/cpu/exception.hpp b/kapi/include/kapi/cpu/exception.hpp deleted file mode 100644 index d6e8511..0000000 --- a/kapi/include/kapi/cpu/exception.hpp +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef TEACHOS_KAPI_CPU_EXCEPTION_HPP -#define TEACHOS_KAPI_CPU_EXCEPTION_HPP - -// IWYU pragma: private, include "kapi/cpu.hpp" - -#include "kapi/memory.hpp" - -#include - -#include - -namespace kapi::cpu -{ - - //! An exception originating from the CPU directly. - //! - //! Exception generally model interrupts that are synchronous to the instruction stream. This means that they do not - //! originate from external hardware, but rather are a product of program execution. - struct exception - { - //! The type of the exception, which identifies the reason for it being raised. - enum class type : std::uint8_t - { - //! The reason for the exception is unknown or platform-specific - unknown, - //! A page fault occurred - page_fault, - //! A memory access (either in the data or instruction stream) violated it's alignment constraints. - alignment_fault, - //! A memory access (either in the data or instruction stream) violated it's permissions. - memory_access_fault, - //! An invalid instruction was present in the instruction stream. - illegal_instruction, - //! The preconditions for the execution of an instruction were not met. - privilege_violation, - //! An arithmetic error occurred. - arithmetic_error, - //! A breakpoint was hit in the instruction stream. - breakpoint, - //! The CPU is single-stepping through the instruction stream. - single_step, - }; - - //! The type of this exception. - type type{}; - - //! The value of the instruction pointer at the time this exception was raised. - kapi::memory::linear_address instruction_pointer{}; - - //! The memory address that caused this exception. - kapi::memory::linear_address access_address{}; - - //! Whether the page was present at the time of the exception. - bool is_present{}; - - //! Whether the exception was caused by a write access. - bool is_write_access{}; - - //! Whether the exception was caused by a user mode access. - bool is_user_mode{}; - }; - - //! @qualifier kernel-defined - //! Dispatch an exception to the appropriate handler. - //! - //! @param context The exception context. - //! @return Whether the exception was handled. - auto dispatch(exception const & context) -> bool; - -} // namespace kapi::cpu - -template<> -struct kstd::formatter -{ - constexpr auto parse(kstd::format_parse_context & ctx) -> decltype(ctx.begin()) - { - return ctx.begin(); - } - - constexpr auto format(enum kapi::cpu::exception::type type, kstd::format_context & ctx) const -> void - { - switch (type) - { - case kapi::cpu::exception::type::unknown: - return ctx.push("unknown"); - case kapi::cpu::exception::type::page_fault: - return ctx.push("page fault"); - case kapi::cpu::exception::type::alignment_fault: - return ctx.push("alignment fault"); - case kapi::cpu::exception::type::memory_access_fault: - return ctx.push("memory access fault"); - case kapi::cpu::exception::type::illegal_instruction: - return ctx.push("illegal instruction"); - case kapi::cpu::exception::type::privilege_violation: - return ctx.push("privilege violation"); - case kapi::cpu::exception::type::arithmetic_error: - return ctx.push("arithmetic error"); - case kapi::cpu::exception::type::breakpoint: - return ctx.push("breakpoint"); - case kapi::cpu::exception::type::single_step: - return ctx.push("single step"); - } - } -}; - -#endif \ No newline at end of file -- cgit v1.2.3 From 00a77644192642e06462c11479a5c0e9bd859e9a Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 16:35:32 +0100 Subject: kapi: extract interrupts API --- kapi/CMakeLists.txt | 3 +- kapi/include/kapi/cpu.hpp | 1 - kapi/include/kapi/cpu/interrupts.hpp | 63 ------------------------------------ kapi/include/kapi/interrupts.hpp | 61 ++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 66 deletions(-) delete mode 100644 kapi/include/kapi/cpu/interrupts.hpp create mode 100644 kapi/include/kapi/interrupts.hpp (limited to 'kapi') diff --git a/kapi/CMakeLists.txt b/kapi/CMakeLists.txt index 4c94829..99b737c 100644 --- a/kapi/CMakeLists.txt +++ b/kapi/CMakeLists.txt @@ -9,8 +9,7 @@ target_sources("kapi" PUBLIC "include/kapi/boot.hpp" "include/kapi/cio.hpp" "include/kapi/cpu.hpp" - "include/kapi/cpu/interrupts.hpp" - "include/kapi/cpu/exception.hpp" + "include/kapi/interrupts.hpp" "include/kapi/boot_module/boot_module.hpp" "include/kapi/boot_module/boot_module_registry.hpp" "include/kapi/memory.hpp" diff --git a/kapi/include/kapi/cpu.hpp b/kapi/include/kapi/cpu.hpp index 041a5db..c6aa6ff 100644 --- a/kapi/include/kapi/cpu.hpp +++ b/kapi/include/kapi/cpu.hpp @@ -1,7 +1,6 @@ #ifndef TEACHOS_KAPI_CPU_HPP #define TEACHOS_KAPI_CPU_HPP -#include "kapi/cpu/interrupts.hpp" // IWYU pragma: export #include "kapi/memory.hpp" #include diff --git a/kapi/include/kapi/cpu/interrupts.hpp b/kapi/include/kapi/cpu/interrupts.hpp deleted file mode 100644 index 328e4a7..0000000 --- a/kapi/include/kapi/cpu/interrupts.hpp +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef TEACHOS_KAPI_CPU_INTERRUPTS_HPP -#define TEACHOS_KAPI_CPU_INTERRUPTS_HPP - -// IWYU pragma: private, include "kapi/cpu.hpp" - -#include - -namespace kapi::cpu -{ - - enum class status : bool - { - unhandled, - handled, - }; - - //! The interface for all interrupt handlers. - struct interrupt_handler - { - virtual ~interrupt_handler() = default; - - //! Handle an interrupt with the given IRQ number. - // - //! This function will be called by the kernel in an interrupt context. As such, the function should complete its - //! task quickly and must take care when acquiring globally shared locks. - //! - //! @param irq_number The identifier of the interrupt request that triggered the handler. - //! @return status::handled if the handler successfully handled the interrupt, status::unhandled otherwise. - virtual auto handle_interrupt(std::uint32_t irq_number) -> status = 0; - }; - - //! @qualifier platform-defined - //! Enable external interrupts. - auto enable_interrupts() -> void; - - //! @qualifier platform-defined - //! Disable external interrupts. - auto disable_interrupts() -> void; - - //! @qualifier platform-defined - //! Register an interrupt handler for the given IRQ number. - //! - //! @param irq_number The IRQ number to register the handler for. - //! @param handler The interrupt handler to register. - auto register_interrupt_handler(std::uint32_t irq_number, interrupt_handler & handler) -> void; - - //! @qualifier platform-defined - //! Unregister a previously registered interrupt handler. - //! - //! @param irq_number The IRQ number to unregister the handler for. - //! @param handler The interrupt handler to unregister. - auto unregister_interrupt_handler(std::uint32_t irq_number, interrupt_handler & handler) -> void; - - //! @qualifier platform-defined - //! Dispatch an interrupt to all registered handlers. - //! - //! @param irq_number The IRQ number to dispatch. - //! @return status::handled if the interrupt was handled by at least one handler, status::unhandled otherwise. - auto dispatch_interrupt(std::uint32_t irq_number) -> status; - -} // namespace kapi::cpu - -#endif \ No newline at end of file diff --git a/kapi/include/kapi/interrupts.hpp b/kapi/include/kapi/interrupts.hpp new file mode 100644 index 0000000..fa4bc95 --- /dev/null +++ b/kapi/include/kapi/interrupts.hpp @@ -0,0 +1,61 @@ +#ifndef TEACHOS_KAPI_INTERRUPTS_HPP +#define TEACHOS_KAPI_INTERRUPTS_HPP + +#include + +namespace kapi::interrupts +{ + + enum class status : bool + { + unhandled, + handled, + }; + + //! The interface for all interrupt handlers. + struct handler + { + virtual ~handler() = default; + + //! Handle an interrupt with the given IRQ number. + // + //! This function will be called by the kernel in an interrupt context. As such, the function should complete its + //! task quickly and must take care when acquiring globally shared locks. + //! + //! @param irq_number The identifier of the interrupt request that triggered the handler. + //! @return status::handled if the handler successfully handled the interrupt, status::unhandled otherwise. + virtual auto handle_interrupt(std::uint32_t irq_number) -> status = 0; + }; + + //! @qualifier platform-defined + //! Enable external interrupts. + auto enable() -> void; + + //! @qualifier platform-defined + //! Disable external interrupts. + auto disable() -> void; + + //! @qualifier platform-defined + //! Register an interrupt handler for the given IRQ number. + //! + //! @param irq_number The IRQ number to register the handler for. + //! @param handler The interrupt handler to register. + auto register_handler(std::uint32_t irq_number, handler & handler) -> void; + + //! @qualifier platform-defined + //! Unregister a previously registered interrupt handler. + //! + //! @param irq_number The IRQ number to unregister the handler for. + //! @param handler The interrupt handler to unregister. + auto unregister_handler(std::uint32_t irq_number, handler & handler) -> void; + + //! @qualifier platform-defined + //! Dispatch an interrupt to all registered handlers. + //! + //! @param irq_number The IRQ number to dispatch. + //! @return status::handled if the interrupt was handled by at least one handler, status::unhandled otherwise. + auto dispatch(std::uint32_t irq_number) -> status; + +} // namespace kapi::interrupts + +#endif \ No newline at end of file -- cgit v1.2.3 From f4dc64976049761a6f56dd55d9d0b651f1e9475f Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 16:47:41 +0100 Subject: kapi: move interrupt handling to kernel --- kapi/include/kapi/interrupts.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/interrupts.hpp b/kapi/include/kapi/interrupts.hpp index fa4bc95..f72ef8c 100644 --- a/kapi/include/kapi/interrupts.hpp +++ b/kapi/include/kapi/interrupts.hpp @@ -35,21 +35,21 @@ namespace kapi::interrupts //! Disable external interrupts. auto disable() -> void; - //! @qualifier platform-defined + //! @qualifier kernel-defined //! Register an interrupt handler for the given IRQ number. //! //! @param irq_number The IRQ number to register the handler for. //! @param handler The interrupt handler to register. auto register_handler(std::uint32_t irq_number, handler & handler) -> void; - //! @qualifier platform-defined + //! @qualifier kernel-defined //! Unregister a previously registered interrupt handler. //! //! @param irq_number The IRQ number to unregister the handler for. //! @param handler The interrupt handler to unregister. auto unregister_handler(std::uint32_t irq_number, handler & handler) -> void; - //! @qualifier platform-defined + //! @qualifier kernel-defined //! Dispatch an interrupt to all registered handlers. //! //! @param irq_number The IRQ number to dispatch. -- cgit v1.2.3 From a2834cc22b096e848448bb681ab7b517ecbe70b9 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 16:54:07 +0100 Subject: build: simplify header scanning --- kapi/CMakeLists.txt | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'kapi') diff --git a/kapi/CMakeLists.txt b/kapi/CMakeLists.txt index 99b737c..c9aa23f 100644 --- a/kapi/CMakeLists.txt +++ b/kapi/CMakeLists.txt @@ -1,24 +1,13 @@ add_library("kapi" INTERFACE) add_library("os::kapi" ALIAS "kapi") +file(GLOB_RECURSE KAPI_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "include/**.hpp") + target_sources("kapi" PUBLIC FILE_SET HEADERS BASE_DIRS "include" FILES - "include/kapi/boot_modules.hpp" - "include/kapi/boot.hpp" - "include/kapi/cio.hpp" - "include/kapi/cpu.hpp" - "include/kapi/interrupts.hpp" - "include/kapi/boot_module/boot_module.hpp" - "include/kapi/boot_module/boot_module_registry.hpp" - "include/kapi/memory.hpp" - "include/kapi/memory/address.hpp" - "include/kapi/memory/frame_allocator.hpp" - "include/kapi/memory/frame.hpp" - "include/kapi/memory/page_mapper.hpp" - "include/kapi/memory/page.hpp" - "include/kapi/system.hpp" + ${KAPI_HEADERS} ) target_include_directories("kapi" INTERFACE -- cgit v1.2.3 From 9e85f9d1f34d08213a918d9c1b0845c179e323af Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 31 Mar 2026 08:56:17 +0200 Subject: move device into kapi --- kapi/include/kapi/devices/device.hpp | 81 ++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 kapi/include/kapi/devices/device.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/devices/device.hpp b/kapi/include/kapi/devices/device.hpp new file mode 100644 index 0000000..a049cf5 --- /dev/null +++ b/kapi/include/kapi/devices/device.hpp @@ -0,0 +1,81 @@ +#ifndef TEACH_OS_KAPI_DEVICES_DEVICE_HPP +#define TEACH_OS_KAPI_DEVICES_DEVICE_HPP + +#include + +#include + +namespace kapi::devices +{ + /** + * @brief Base device identified by a major, minor number and name. + */ + struct device + { + /** + * @brief Create a device identifier from @p major, @p minor and @p name. + * @param major Device major number. + * @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) + {} + + /** + * @brief Virtual destructor for device. + */ + virtual ~device() = default; + + /** + * @brief Initialize the device. + * @return true on success, false otherwise. + */ + virtual auto init() -> bool = 0; + + /** + * @brief Returns the major number of the device. + * @return Device major number. + */ + [[nodiscard]] auto major() const -> size_t + { + return m_major; + } + + /** + * @brief Returns the minor number of the device. + * @return Device minor number. + */ + [[nodiscard]] auto minor() const -> size_t + { + return m_minor; + } + + /** + * @brief Returns the name of the device. + * @return Device name. + */ + [[nodiscard]] auto name() const -> kstd::string const & + { + return m_name; + } + + /** + * @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; + } + + private: + size_t m_major; + size_t m_minor; + kstd::string m_name; + }; +} // namespace kapi::devices + +#endif \ No newline at end of file -- cgit v1.2.3 From fa1ea53e6f3dd6b9b5f5f8160776b230184a30bf Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 09:36:31 +0200 Subject: kernel/tests: implement platform CIO kapi --- kapi/include/kapi/cio.hpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'kapi') diff --git a/kapi/include/kapi/cio.hpp b/kapi/include/kapi/cio.hpp index 48f3000..71b5b02 100644 --- a/kapi/include/kapi/cio.hpp +++ b/kapi/include/kapi/cio.hpp @@ -25,6 +25,11 @@ namespace kapi::cio //! @return The previously active output device. auto set_output_device(output_device & device) -> std::optional; + //! @qualifier kernel-defined + //! Write a string to the given output stream. + //! + //! @param stream The output stream to write to. + //! @param text The text to write to the stream. auto write(output_stream stream, std::string_view text) -> void; } // namespace kapi::cio -- cgit v1.2.3 From e7abfb7bf87ac605b2168891973d7e04a84d627e Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 31 Mar 2026 21:56:37 +0200 Subject: kapi/devices: introduce basic bus abstraction --- kapi/include/kapi/devices/bus.hpp | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 kapi/include/kapi/devices/bus.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp new file mode 100644 index 0000000..cf8d090 --- /dev/null +++ b/kapi/include/kapi/devices/bus.hpp @@ -0,0 +1,40 @@ +#ifndef TEACHOS_KAPI_DEVICES_BUS_HPP +#define TEACHOS_KAPI_DEVICES_BUS_HPP + +#include "kapi/devices/device.hpp" + +#include +#include +#include + +#include + +namespace kapi::devices +{ + //! A bus device that represents a logical/physical tree of devices and busses. + struct bus : device + { + //! Construct a bus with the given major number, minor number, and name. + //! + //! @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) + {} + + //! 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. + virtual auto add_child(kstd::unique_ptr child) -> void = 0; + + //! Get a list of all child devices attached to this bus. + //! + //! @return A reference to list of child devices of this bus. + [[nodiscard]] virtual auto children() const -> kstd::vector const & = 0; + }; +} // namespace kapi::devices + +#endif \ No newline at end of file -- cgit v1.2.3 From 77473afe9d5acb9450443b07b56d3dbc2f0639a6 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 31 Mar 2026 22:22:25 +0200 Subject: kstd: introduce observer_ptr --- kapi/include/kapi/devices/bus.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'kapi') diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index cf8d090..0b25ac1 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -4,6 +4,7 @@ #include "kapi/devices/device.hpp" #include +#include #include #include @@ -33,7 +34,7 @@ namespace kapi::devices //! Get a list of all child devices attached to this bus. //! //! @return A reference to list of child devices of this bus. - [[nodiscard]] virtual auto children() const -> kstd::vector const & = 0; + [[nodiscard]] virtual auto children() const -> kstd::vector> const & = 0; }; } // namespace kapi::devices -- cgit v1.2.3 From a2ff4ace21699fe2be2e0401af78790c01f78d85 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 11:45:55 +0200 Subject: kstd: move observer_ptr to bits --- kapi/include/kapi/devices/bus.hpp | 1 - 1 file changed, 1 deletion(-) (limited to 'kapi') diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index 0b25ac1..a8d7df8 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -4,7 +4,6 @@ #include "kapi/devices/device.hpp" #include -#include #include #include -- cgit v1.2.3 From d0c532af74d8d486d734904fd330d5dae7f49754 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 13:36:01 +0200 Subject: kapi: add basic device subsystem --- kapi/include/kapi/devices.hpp | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 kapi/include/kapi/devices.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/devices.hpp b/kapi/include/kapi/devices.hpp new file mode 100644 index 0000000..60a39bd --- /dev/null +++ b/kapi/include/kapi/devices.hpp @@ -0,0 +1,46 @@ +#ifndef TEACHOS_KAPI_DEVICES_HPP +#define TEACHOS_KAPI_DEVICES_HPP + +#include "kapi/devices/bus.hpp" // IWYU pragma: export +#include "kapi/devices/device.hpp" // IWYU pragma: export + +#include + +namespace kapi::devices +{ + + //! @addtogroup kernel-defined + //! @{ + + //! Initialize the kernel's device management subsystem. + auto init() -> void; + + //! Get the virtual system root bus. + //! + //! @warning This function will panic if the root bus has not been initialized. + //! + //! @return a reference to the root bus. + auto get_root_bus() -> bus &; + + //! Ask the kernel to allocate a new major number. + //! + //! @return a new, unused major number. + auto allocate_major_number() -> std::size_t; + + //! Register a new device with the kernel's device manager. + //! + //! @param device The device to register. + //! @return true if the device was registered successfully, false otherwise. + auto register_device(device & device) -> bool; + + //! Unregister a device from the kernel's device manager. + //! + //! @param device The device to unregister. + //! @return true if the device was unregistered successfully, false otherwise. + auto unregister_device(device & device) -> bool; + + //! @} + +} // namespace kapi::devices + +#endif \ No newline at end of file -- cgit v1.2.3 From b84c4c9d8c90f3d3fd5a60de282278912fad2f04 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 13:59:27 +0200 Subject: x86_64/devices: implement ISA bus stub --- kapi/include/kapi/devices.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'kapi') diff --git a/kapi/include/kapi/devices.hpp b/kapi/include/kapi/devices.hpp index 60a39bd..2028a64 100644 --- a/kapi/include/kapi/devices.hpp +++ b/kapi/include/kapi/devices.hpp @@ -41,6 +41,14 @@ namespace kapi::devices //! @} + //! @addtogroup platform-defined + //! @{ + + //! Initialize the platform's device tree. + auto init_platform_devices() -> void; + + //! @} + } // namespace kapi::devices #endif \ No newline at end of file -- cgit v1.2.3 From 66ffd2ad8c793c4eea1527848fe4772e42595718 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 14:24:52 +0200 Subject: kapi: extract common bus code --- kapi/include/kapi/devices/bus.hpp | 61 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index a8d7df8..ccaf0f2 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -2,12 +2,17 @@ #define TEACHOS_KAPI_DEVICES_BUS_HPP #include "kapi/devices/device.hpp" +#include "kapi/system.hpp" #include +#include #include #include +#include +#include #include +#include namespace kapi::devices { @@ -23,17 +28,65 @@ namespace kapi::devices : device(major, minor, 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 acc && child->init(); + }); + } + //! 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. - virtual auto add_child(kstd::unique_ptr child) -> void = 0; + auto add_child(kstd::unique_ptr child) -> void + { + auto observer = m_observers.emplace_back(child.get()); + m_devices.push_back(std::move(child)); - //! Get a list of all child devices attached to this bus. + 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"); + } + } + } + + [[nodiscard]] auto children() const -> kstd::vector> const & + { + return m_observers; + } + + protected: + //! Probe the bus hardware state. //! - //! @return A reference to list of child devices of this bus. - [[nodiscard]] virtual auto children() const -> kstd::vector> const & = 0; + //! @return true iff. the bus hardware is healthy, false otherwise. + auto virtual probe() -> bool + { + return true; + } + + private: + kstd::vector> m_devices; + kstd::vector> m_observers; + std::atomic_flag m_initialized{}; }; } // namespace kapi::devices -- cgit v1.2.3 From ab4c59912c526d515e6e72188c08a7f92e5573e8 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 15:07:54 +0200 Subject: x86_64: implement legacy PIT driver --- kapi/include/kapi/devices.hpp | 24 +++-------------------- kapi/include/kapi/devices/bus.hpp | 2 ++ kapi/include/kapi/devices/manager.hpp | 37 +++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 kapi/include/kapi/devices/manager.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/devices.hpp b/kapi/include/kapi/devices.hpp index 2028a64..5c01b2f 100644 --- a/kapi/include/kapi/devices.hpp +++ b/kapi/include/kapi/devices.hpp @@ -1,10 +1,9 @@ #ifndef TEACHOS_KAPI_DEVICES_HPP #define TEACHOS_KAPI_DEVICES_HPP -#include "kapi/devices/bus.hpp" // IWYU pragma: export -#include "kapi/devices/device.hpp" // IWYU pragma: export - -#include +#include "kapi/devices/bus.hpp" // IWYU pragma: export +#include "kapi/devices/device.hpp" // IWYU pragma: export +#include "kapi/devices/manager.hpp" // IWYU pragma: export namespace kapi::devices { @@ -22,23 +21,6 @@ namespace kapi::devices //! @return a reference to the root bus. auto get_root_bus() -> bus &; - //! Ask the kernel to allocate a new major number. - //! - //! @return a new, unused major number. - auto allocate_major_number() -> std::size_t; - - //! Register a new device with the kernel's device manager. - //! - //! @param device The device to register. - //! @return true if the device was registered successfully, false otherwise. - auto register_device(device & device) -> bool; - - //! Unregister a device from the kernel's device manager. - //! - //! @param device The device to unregister. - //! @return true if the device was unregistered successfully, false otherwise. - auto unregister_device(device & device) -> bool; - //! @} //! @addtogroup platform-defined diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index ccaf0f2..a5457e1 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -2,6 +2,7 @@ #define TEACHOS_KAPI_DEVICES_BUS_HPP #include "kapi/devices/device.hpp" +#include "kapi/devices/manager.hpp" #include "kapi/system.hpp" #include @@ -58,6 +59,7 @@ namespace kapi::devices { auto observer = m_observers.emplace_back(child.get()); m_devices.push_back(std::move(child)); + kapi::devices::register_device(*observer); if (m_initialized.test()) { diff --git a/kapi/include/kapi/devices/manager.hpp b/kapi/include/kapi/devices/manager.hpp new file mode 100644 index 0000000..56cd678 --- /dev/null +++ b/kapi/include/kapi/devices/manager.hpp @@ -0,0 +1,37 @@ +#ifndef TEACHOS_KAPI_DEVICES_MANAGER_HPP +#define TEACHOS_KAPI_DEVICES_MANAGER_HPP + +// IWYU pragma: private, include "kapi/devices.hpp" + +#include "kapi/devices/device.hpp" + +#include + +namespace kapi::devices +{ + + //! @addtogroup kernel-defined + //! @{ + + //! Ask the kernel to allocate a new major number. + //! + //! @return a new, unused major number. + auto allocate_major_number() -> std::size_t; + + //! Register a new device with the kernel's device manager. + //! + //! @param device The device to register. + //! @return true if the device was registered successfully, false otherwise. + auto register_device(device & device) -> bool; + + //! Unregister a device from the kernel's device manager. + //! + //! @param device The device to unregister. + //! @return true if the device was unregistered successfully, false otherwise. + auto unregister_device(device & device) -> bool; + + //! @} + +} // namespace kapi::devices + +#endif \ No newline at end of file -- cgit v1.2.3 From 3e80b6baa8f9666a9dd3cd4531bc68a3de4fee92 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 15:18:05 +0200 Subject: kapi: allow for device searches --- kapi/include/kapi/devices/manager.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'kapi') diff --git a/kapi/include/kapi/devices/manager.hpp b/kapi/include/kapi/devices/manager.hpp index 56cd678..7817fbc 100644 --- a/kapi/include/kapi/devices/manager.hpp +++ b/kapi/include/kapi/devices/manager.hpp @@ -5,7 +5,10 @@ #include "kapi/devices/device.hpp" +#include + #include +#include namespace kapi::devices { @@ -30,6 +33,19 @@ namespace kapi::devices //! @return true if the device was unregistered successfully, false otherwise. auto unregister_device(device & device) -> bool; + //! Find a device by its major and minor numbers. + //! + //! @param major the major number of the device. + //! @param minor the minor number of the device. + //! @return a pointer to the device iff. the device was found, nullptr otherwise. + auto find_device(std::size_t major, std::size_t minor) -> kstd::observer_ptr; + + //! Find a device by its name. + //! + //! @param name the name of the device. + //! @return a pointer to the device iff. the device was found, nullptr otherwise. + auto find_device(std::string_view name) -> kstd::observer_ptr; + //! @} } // namespace kapi::devices -- cgit v1.2.3 From 33b43603936ed0108d67853727a17d6b3740b445 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 15:43:34 +0200 Subject: kapi/bus: ensure all devices get initialized --- kapi/include/kapi/devices/bus.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kapi') diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index a5457e1..ee774b7 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -46,7 +46,7 @@ namespace kapi::devices return std::ranges::fold_left(m_devices, true, [&](bool acc, auto & child) -> bool { kstd::println("[kAPI:BUS] Initializing child device {}@{}", child->name(), name()); - return acc && child->init(); + return child->init() && acc; }); } -- cgit v1.2.3 From 4cce84317474dd14da806d3ddc7f69ef11356b5f Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 20:04:07 +0200 Subject: docs: begin breathe documentation --- kapi/include/kapi/cio.hpp | 27 +++++++++++++++++++-------- kapi/include/kapi/cpu.hpp | 28 ++++++++++++++++++++-------- kapi/include/kapi/devices.hpp | 4 ++-- kapi/include/kapi/devices/bus.hpp | 7 +++++++ kapi/include/kapi/devices/device.hpp | 7 +++++++ kapi/include/kapi/devices/manager.hpp | 2 +- kapi/include/kapi/interrupts.hpp | 31 ++++++++++++++++++++++--------- kapi/include/kapi/memory.hpp | 33 +++++++++++++++++---------------- kapi/include/kapi/system.hpp | 12 ++++++++++-- kapi/kapi.dox | 8 ++++++++ 10 files changed, 113 insertions(+), 46 deletions(-) create mode 100644 kapi/kapi.dox (limited to 'kapi') diff --git a/kapi/include/kapi/cio.hpp b/kapi/include/kapi/cio.hpp index 71b5b02..8941a9f 100644 --- a/kapi/include/kapi/cio.hpp +++ b/kapi/include/kapi/cio.hpp @@ -11,27 +11,38 @@ namespace kapi::cio { - //! @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; + //! @addtogroup kapi-cio + //! @{ + //! @} + + //! @addtogroup kapi-cio-kernel-defined + //! @{ - //! @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; - //! @qualifier kernel-defined //! Write a string to the given output stream. //! //! @param stream The output stream to write to. //! @param text The text to write to the stream. auto write(output_stream stream, std::string_view text) -> void; + //! @} + + //! @addtogroup kapi-cio-platform-defined + //! @{ + + //! Initialize the character I/O subsystem. + //! + //! 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; + + //! @} + } // namespace kapi::cio #endif diff --git a/kapi/include/kapi/cpu.hpp b/kapi/include/kapi/cpu.hpp index c6aa6ff..d90365a 100644 --- a/kapi/include/kapi/cpu.hpp +++ b/kapi/include/kapi/cpu.hpp @@ -10,6 +10,9 @@ namespace kapi::cpu { + //! @addtogroup kapi-cpu + //! @{ + //! An exception originating from the CPU directly. //! //! Exception generally model interrupts that are synchronous to the instruction stream. This means that they do not @@ -58,25 +61,34 @@ namespace kapi::cpu bool is_user_mode{}; }; - //! @qualifier platform-defined + //! @} + + //! @addtogroup kapi-cpu-kernel-defined + //! @{ + + //! Dispatch an exception to the appropriate handler. + //! + //! @param context The exception context. + //! @return Whether the exception was handled. + [[nodiscard]] auto dispatch(exception const & context) -> bool; + + //! @} + + //! @addtogroup kapi-cpu-platform-defined + //! @{ + //! Halt the CPU. //! //! This function terminates execution of the kernel. [[noreturn]] auto halt() -> void; - //! @qualifier platform-defined //! Perform early CPU initialization. //! //! When this function returns, the CPU is in a state where interrupt could be enabled. This function must not enable //! interrupts itself. auto init() -> void; - //! @qualifier kernel-defined - //! Dispatch an exception to the appropriate handler. - //! - //! @param context The exception context. - //! @return Whether the exception was handled. - [[nodiscard]] auto dispatch(exception const & context) -> bool; + //! @} } // namespace kapi::cpu diff --git a/kapi/include/kapi/devices.hpp b/kapi/include/kapi/devices.hpp index 5c01b2f..c26efb9 100644 --- a/kapi/include/kapi/devices.hpp +++ b/kapi/include/kapi/devices.hpp @@ -8,7 +8,7 @@ namespace kapi::devices { - //! @addtogroup kernel-defined + //! @addtogroup kapi-devices-kernel-defined //! @{ //! Initialize the kernel's device management subsystem. @@ -23,7 +23,7 @@ namespace kapi::devices //! @} - //! @addtogroup platform-defined + //! @addtogroup kapi-devices-platform-defined //! @{ //! Initialize the platform's device tree. diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index ee774b7..052c062 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -17,6 +17,10 @@ namespace kapi::devices { + + //! @addtogroup kapi-devices + //! @{ + //! A bus device that represents a logical/physical tree of devices and busses. struct bus : device { @@ -90,6 +94,9 @@ namespace kapi::devices kstd::vector> m_observers; std::atomic_flag m_initialized{}; }; + + //! @} + } // namespace kapi::devices #endif \ No newline at end of file diff --git a/kapi/include/kapi/devices/device.hpp b/kapi/include/kapi/devices/device.hpp index a049cf5..b7b6bba 100644 --- a/kapi/include/kapi/devices/device.hpp +++ b/kapi/include/kapi/devices/device.hpp @@ -7,6 +7,10 @@ namespace kapi::devices { + + //! @addtogroup kapi-devices + //! @{ + /** * @brief Base device identified by a major, minor number and name. */ @@ -76,6 +80,9 @@ namespace kapi::devices size_t m_minor; kstd::string m_name; }; + + //! @} + } // namespace kapi::devices #endif \ No newline at end of file diff --git a/kapi/include/kapi/devices/manager.hpp b/kapi/include/kapi/devices/manager.hpp index 7817fbc..f19366e 100644 --- a/kapi/include/kapi/devices/manager.hpp +++ b/kapi/include/kapi/devices/manager.hpp @@ -13,7 +13,7 @@ namespace kapi::devices { - //! @addtogroup kernel-defined + //! @addtogroup kapi-devices-kernel-defined //! @{ //! Ask the kernel to allocate a new major number. diff --git a/kapi/include/kapi/interrupts.hpp b/kapi/include/kapi/interrupts.hpp index f72ef8c..4ba0684 100644 --- a/kapi/include/kapi/interrupts.hpp +++ b/kapi/include/kapi/interrupts.hpp @@ -6,9 +6,15 @@ namespace kapi::interrupts { + //! @addtogroup kapi-interrupts + //! @{ + + //! A status that indicates whether an interrupt was handled by a handler. enum class status : bool { + //! The interrupt was not handled by any handler. unhandled, + //! The interrupt was handled by at least one handler. handled, }; @@ -27,35 +33,42 @@ namespace kapi::interrupts virtual auto handle_interrupt(std::uint32_t irq_number) -> status = 0; }; - //! @qualifier platform-defined - //! Enable external interrupts. - auto enable() -> void; + //! @} - //! @qualifier platform-defined - //! Disable external interrupts. - auto disable() -> void; + //! @addtogroup kapi-interrupts-kernel-defined + //! @{ - //! @qualifier kernel-defined //! Register an interrupt handler for the given IRQ number. //! //! @param irq_number The IRQ number to register the handler for. //! @param handler The interrupt handler to register. auto register_handler(std::uint32_t irq_number, handler & handler) -> void; - //! @qualifier kernel-defined //! Unregister a previously registered interrupt handler. //! //! @param irq_number The IRQ number to unregister the handler for. //! @param handler The interrupt handler to unregister. auto unregister_handler(std::uint32_t irq_number, handler & handler) -> void; - //! @qualifier kernel-defined //! Dispatch an interrupt to all registered handlers. //! //! @param irq_number The IRQ number to dispatch. //! @return status::handled if the interrupt was handled by at least one handler, status::unhandled otherwise. auto dispatch(std::uint32_t irq_number) -> status; + //! @} + + //! @addtogroup kapi-interrupts-platform-defined + //! @{ + + //! Enable external interrupts. + auto enable() -> void; + + //! Disable external interrupts. + auto disable() -> void; + + //! @} + } // namespace kapi::interrupts #endif \ No newline at end of file diff --git a/kapi/include/kapi/memory.hpp b/kapi/include/kapi/memory.hpp index e31fa34..914ca61 100644 --- a/kapi/include/kapi/memory.hpp +++ b/kapi/include/kapi/memory.hpp @@ -16,16 +16,9 @@ namespace kapi::memory { - //! @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; + //! @addtogroup kapi-memory-kernel-defined + //! @{ - //! @qualifier kernel-defined //! Initialize the physical memory manager. //! //! This function initializes the kernel-wide physical memory manager. The function will invoke the handoff handler to @@ -39,25 +32,21 @@ namespace kapi::memory //! allocator to hand off to is passed to the handler. auto init_pmm(std::size_t frame_count, void (&handoff_handler)(frame_allocator &)) -> void; - //! @qualifier kernel-defined //! Get the currently active frame allocator. auto get_frame_allocator() -> frame_allocator &; - //! @qualifier kernel-defined //! Set the currently active frame allocator. //! //! @param allocator A new frame allocator. //! @return The previously active frame allocator. auto set_frame_allocator(frame_allocator & allocator) -> std::optional; - //! @qualifier kernel-defined //! Set the currently active page mapper. //! //! @param mapper A new page mapper. //! @return The previously active page mapper. auto set_page_mapper(page_mapper & mapper) -> std::optional; - //! @qualifier kernel-defined //! Allocate a new frame of physical memory //! //! @warning This function will panic if no frame allocator has been registered. @@ -65,7 +54,6 @@ namespace kapi::memory //! @return An engaged std::optional iff. a frame could be allocated, std::nullopt otherwise. auto allocate_frame() -> std::optional; - //! @qualifier kernel-defined //! Allocate multiple new frames of physical memory //! //! @warning This function will panic if no frame allocator has been registered. @@ -73,7 +61,6 @@ namespace kapi::memory //! @return An engaged std::optional iff. @p count frames could be allocated, std::nullopt otherwise. auto allocate_many_frames(std::size_t count) -> std::optional>; - //! @qualifier kernel-defined //! Map a page onto a frame. //! //! @warning This function will panic if no page mapper has been registered, or the page has already been mapped. @@ -85,7 +72,6 @@ namespace kapi::memory //! @return A pointer to the first byte of the mapped page. auto map(page page, frame frame, page_mapper::flags flags = page_mapper::flags::empty) -> std::byte *; - //! @qualifier kernel-defined //! Unmap a page. //! //! @warning This function will panic if no page mapper has been registered, or the page is not mapped. @@ -93,6 +79,21 @@ namespace kapi::memory //! @param page The page to unmap auto unmap(page page) -> void; + //! @} + + //! @addtogroup kapi-memory-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 kapi::memory #endif diff --git a/kapi/include/kapi/system.hpp b/kapi/include/kapi/system.hpp index e5c43c5..8a20af9 100644 --- a/kapi/include/kapi/system.hpp +++ b/kapi/include/kapi/system.hpp @@ -7,7 +7,9 @@ namespace kapi::system { - //! @qualifier kernel-defined + //! @addtogroup kapi-system-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. @@ -15,10 +17,16 @@ namespace kapi::system //! @param message The message associated with the panic [[noreturn]] auto panic(std::string_view message, std::source_location = std::source_location::current()) -> void; - //! @qualifier platform-defined + //! @} // end group kernel-defined + + //! @addtogroup kapi-system-platform-defined + //! @{ + //! A hook that runs once the memory subsystem has been initialized. auto memory_initialized() -> void; + //! @} // end group platform-defined + } // namespace kapi::system #endif diff --git a/kapi/kapi.dox b/kapi/kapi.dox new file mode 100644 index 0000000..929fc1f --- /dev/null +++ b/kapi/kapi.dox @@ -0,0 +1,8 @@ +//! @namespace kapi +//! The Kernel/Platform API +//! +//! This namespace defines the interface between the platform independent kernel and each supported platform. + +//! @defgroup kapi-kernel-defined Kernel-defined API + +//! @defgroup kapi-platform-defined Platform-defined API -- cgit v1.2.3 From bd585306e31889ee4fce60abb79bc3b3a58e2b84 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 13:11:15 +0200 Subject: kapi: add basic ACPI support --- kapi/CMakeLists.txt | 8 ++++-- kapi/include/kapi/acpi.hpp | 64 +++++++++++++++++++++++++++++++++++++++++++ kapi/src/acpi.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 kapi/include/kapi/acpi.hpp create mode 100644 kapi/src/acpi.cpp (limited to 'kapi') 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 + +#include +#include +#include +#include + +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 m_signature; + [[maybe_unused]] std::uint8_t m_checksum; + std::array m_oem_id; + std::uint8_t m_revision; + std::array 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 m_xsdt_address; + [[maybe_unused]] std::uint8_t m_extended_checksum; + [[maybe_unused]] std::array m_reserved; + }; + + //! @} + + struct [[gnu::packed]] system_description_table_header + { + std::array signature; + std::uint32_t length; + std::uint8_t revision; + std::uint8_t checksum; + std::array oem_id; + std::array 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 + +#include +#include +#include +#include +#include +#include + +namespace kapi::acpi +{ + + namespace + { + constexpr auto validate_checksum(std::span data) -> bool + { + auto sum = std::ranges::fold_left( + data, std::uint8_t{}, [](std::uint8_t acc, auto byte) { return static_cast(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(m_rsdt_address); + return memory::physical_address{static_cast(raw)}; + } + + auto root_system_description_pointer::validate() const noexcept -> bool + { + return validate_checksum({reinterpret_cast(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(m_xsdt_address)}; + } + + auto extended_system_description_pointer::validate() const noexcept -> bool + { + return validate_checksum({reinterpret_cast(this), m_length}); + } + +}; // namespace kapi::acpi -- cgit v1.2.3 From 6e54333bcc08ddd8dbcb6aa9c3404001c309ec74 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 13:27:22 +0200 Subject: kapi: move independent implementation to kernel --- kapi/CMakeLists.txt | 8 ++---- kapi/include/kapi/acpi.hpp | 2 +- kapi/src/acpi.cpp | 68 ---------------------------------------------- 3 files changed, 4 insertions(+), 74 deletions(-) delete mode 100644 kapi/src/acpi.cpp (limited to 'kapi') diff --git a/kapi/CMakeLists.txt b/kapi/CMakeLists.txt index eeda158..c9aa23f 100644 --- a/kapi/CMakeLists.txt +++ b/kapi/CMakeLists.txt @@ -1,6 +1,4 @@ -add_library("kapi" STATIC - "src/acpi.cpp" -) +add_library("kapi" INTERFACE) add_library("os::kapi" ALIAS "kapi") file(GLOB_RECURSE KAPI_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "include/**.hpp") @@ -12,11 +10,11 @@ target_sources("kapi" PUBLIC ${KAPI_HEADERS} ) -target_include_directories("kapi" PUBLIC +target_include_directories("kapi" INTERFACE "include" ) -target_link_libraries("kapi" PUBLIC +target_link_libraries("kapi" INTERFACE "libs::kstd" "gcc" diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp index 20e5e77..1068921 100644 --- a/kapi/include/kapi/acpi.hpp +++ b/kapi/include/kapi/acpi.hpp @@ -12,7 +12,7 @@ namespace kapi::acpi { - //! @addtogroup kapi-acpi-api-defined + //! @addtogroup kapi-acpi-kernel-defined //! @{ struct [[gnu::packed]] root_system_description_pointer diff --git a/kapi/src/acpi.cpp b/kapi/src/acpi.cpp deleted file mode 100644 index aa0066d..0000000 --- a/kapi/src/acpi.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "kapi/acpi.hpp" - -#include "kapi/memory.hpp" - -#include - -#include -#include -#include -#include -#include -#include - -namespace kapi::acpi -{ - - namespace - { - constexpr auto validate_checksum(std::span data) -> bool - { - auto sum = std::ranges::fold_left( - data, std::uint8_t{}, [](std::uint8_t acc, auto byte) { return static_cast(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(m_rsdt_address); - return memory::physical_address{static_cast(raw)}; - } - - auto root_system_description_pointer::validate() const noexcept -> bool - { - return validate_checksum({reinterpret_cast(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(m_xsdt_address)}; - } - - auto extended_system_description_pointer::validate() const noexcept -> bool - { - return validate_checksum({reinterpret_cast(this), m_length}); - } - -}; // namespace kapi::acpi -- cgit v1.2.3 From 3dcd14a0570fef3bcc68d7df42fe3ff4cd496f93 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 14:47:37 +0200 Subject: kapi: hook ACPI initialization up to boot process --- kapi/include/kapi/acpi.hpp | 44 ++++++++++++++++++++++++++----------- kapi/include/kapi/memory/layout.hpp | 12 ++++++++++ 2 files changed, 43 insertions(+), 13 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp index 1068921..d5e3c87 100644 --- a/kapi/include/kapi/acpi.hpp +++ b/kapi/include/kapi/acpi.hpp @@ -2,16 +2,36 @@ #define TEACHOS_KAPI_ACPI_HPP #include "kapi/memory.hpp" + #include #include #include #include +#include #include namespace kapi::acpi { + //! @addtogroup kapi-acpi + //! @{ + + struct [[gnu::packed]] system_description_table_header + { + std::array signature; + std::uint32_t length; + std::uint8_t revision; + std::uint8_t checksum; + std::array oem_id; + std::array oem_table_id; + std::uint32_t oem_revision; + std::uint32_t creator_id; + std::uint32_t create_revision; + }; + + //! @} + //! @addtogroup kapi-acpi-kernel-defined //! @{ @@ -44,20 +64,18 @@ namespace kapi::acpi [[maybe_unused]] std::array m_reserved; }; - //! @} + //! 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; - struct [[gnu::packed]] system_description_table_header - { - std::array signature; - std::uint32_t length; - std::uint8_t revision; - std::uint8_t checksum; - std::array oem_id; - std::array oem_table_id; - std::uint32_t oem_revision; - std::uint32_t creator_id; - std::uint32_t create_revision; - }; + //! 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 data) -> bool; + + //! @} } // namespace kapi::acpi 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 -- cgit v1.2.3 From 4d938cd31a35cd4322fe914edd568faa5391c9c2 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 15:10:04 +0200 Subject: kernel/acpi: implement basic table discovery --- kapi/include/kapi/acpi.hpp | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp index d5e3c87..11068d1 100644 --- a/kapi/include/kapi/acpi.hpp +++ b/kapi/include/kapi/acpi.hpp @@ -19,15 +19,26 @@ namespace kapi::acpi struct [[gnu::packed]] system_description_table_header { - std::array signature; - std::uint32_t length; - std::uint8_t revision; - std::uint8_t checksum; - std::array oem_id; - std::array oem_table_id; - std::uint32_t oem_revision; - std::uint32_t creator_id; - std::uint32_t create_revision; + [[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 m_signature; + std::uint32_t m_length; + std::uint8_t m_revision; + std::uint8_t m_checksum; + std::array m_oem_id; + std::array m_oem_table_id; + std::uint32_t m_oem_revision; + std::uint32_t m_creator_id; + std::uint32_t m_creator_revision; }; //! @} -- cgit v1.2.3 From f456f1674d48932846eb7b5ec1df630ad67e7e3d Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 17:24:36 +0200 Subject: kernel/acpi: discover local interrupt controllers --- kapi/include/kapi/acpi.hpp | 91 +++++++++++++++++++++++++++--------- kapi/include/kapi/devices/bus.hpp | 2 + kapi/include/kapi/devices/device.hpp | 2 + 3 files changed, 72 insertions(+), 23 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp index 11068d1..5d55d08 100644 --- a/kapi/include/kapi/acpi.hpp +++ b/kapi/include/kapi/acpi.hpp @@ -1,8 +1,10 @@ #ifndef TEACHOS_KAPI_ACPI_HPP #define TEACHOS_KAPI_ACPI_HPP +#include "kapi/devices.hpp" #include "kapi/memory.hpp" +#include #include #include @@ -14,9 +16,38 @@ namespace kapi::acpi { - //! @addtogroup 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 m_signature; + [[maybe_unused]] std::uint8_t m_checksum; + std::array m_oem_id; + std::uint8_t m_revision; + std::array 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 m_xsdt_address; + [[maybe_unused]] std::uint8_t m_extended_checksum; + [[maybe_unused]] std::array m_reserved; + }; + struct [[gnu::packed]] system_description_table_header { [[nodiscard]] auto checksum() const noexcept -> std::uint8_t; @@ -41,38 +72,36 @@ namespace kapi::acpi 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; - //! @addtogroup kapi-acpi-kernel-defined - //! @{ + private: + std::uint32_t m_local_interrupt_controller_address; + std::uint32_t m_flags; + }; - struct [[gnu::packed]] root_system_description_pointer + struct [[gnu::packed]] madt_subtable_header { - [[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; + [[nodiscard]] auto type() const noexcept -> std::uint8_t; + [[nodiscard]] auto length() const noexcept -> std::size_t; private: - std::array m_signature; - [[maybe_unused]] std::uint8_t m_checksum; - std::array m_oem_id; - std::uint8_t m_revision; - std::array m_rsdt_address; + std::uint8_t m_type; + std::uint8_t m_length; }; - struct [[gnu::packed]] extended_system_description_pointer : root_system_description_pointer + struct [[gnu::packed]] madt_local_apic : madt_subtable_header { - [[nodiscard]] auto length() const noexcept -> kstd::units::bytes; - [[nodiscard]] auto table_address() const noexcept -> memory::physical_address; - [[nodiscard]] auto validate() const noexcept -> bool; + [[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::uint32_t m_length; - std::array m_xsdt_address; - [[maybe_unused]] std::uint8_t m_extended_checksum; - [[maybe_unused]] std::array m_reserved; + 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. @@ -86,6 +115,22 @@ namespace kapi::acpi //! @return true iff. the checksum is valid, false otherwise. auto validate_checksum(std::span 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; + + //! @} + + //! @addtogroup kapi-acpi-platform-defined + //! @{ + + auto get_root_pointer() -> kstd::observer_ptr; + + auto create_local_interrupt_controller(std::size_t major, std::size_t minor, std::uint64_t hardware_id, + memory::physical_address address) -> kstd::unique_ptr; + //! @} } // namespace kapi::acpi diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index 052c062..a384291 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -1,6 +1,8 @@ #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" diff --git a/kapi/include/kapi/devices/device.hpp b/kapi/include/kapi/devices/device.hpp index b7b6bba..ca5033e 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 #include -- cgit v1.2.3 From 8d08b3b905d211e989848e1abf3a8ff2535836c8 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 18:13:21 +0200 Subject: kapi: extract more code to the kernel --- kapi/include/kapi/devices/bus.hpp | 54 ++++-------------------------------- kapi/include/kapi/devices/device.hpp | 28 ++++--------------- 2 files changed, 12 insertions(+), 70 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index a384291..7b2d41f 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -4,23 +4,19 @@ // IWYU pragma: private, include "kapi/devices.hpp" #include "kapi/devices/device.hpp" -#include "kapi/devices/manager.hpp" -#include "kapi/system.hpp" #include #include #include #include -#include #include #include -#include namespace kapi::devices { - //! @addtogroup kapi-devices + //! @addtogroup kapi-devices-kernel-defined //! @{ //! A bus device that represents a logical/physical tree of devices and busses. @@ -31,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 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 child) -> void; - [[nodiscard]] auto children() const -> kstd::vector> const & - { - return m_observers; - } + [[nodiscard]] auto children() const -> kstd::vector> 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> m_devices; diff --git a/kapi/include/kapi/devices/device.hpp b/kapi/include/kapi/devices/device.hpp index ca5033e..b3647da 100644 --- a/kapi/include/kapi/devices/device.hpp +++ b/kapi/include/kapi/devices/device.hpp @@ -10,7 +10,7 @@ namespace kapi::devices { - //! @addtogroup kapi-devices + //! @addtogroup kapi-devices-kernel-defined //! @{ /** @@ -24,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. @@ -45,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; -- cgit v1.2.3 From f50815110789a0f8f6e5ca66ffd49b26578791a9 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 18:43:28 +0200 Subject: kernel: generalize CPU discovery --- kapi/include/kapi/acpi.hpp | 4 ---- kapi/include/kapi/platform.hpp | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 kapi/include/kapi/platform.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp index 5d55d08..75b6c48 100644 --- a/kapi/include/kapi/acpi.hpp +++ b/kapi/include/kapi/acpi.hpp @@ -1,7 +1,6 @@ #ifndef TEACHOS_KAPI_ACPI_HPP #define TEACHOS_KAPI_ACPI_HPP -#include "kapi/devices.hpp" #include "kapi/memory.hpp" #include @@ -128,9 +127,6 @@ namespace kapi::acpi auto get_root_pointer() -> kstd::observer_ptr; - auto create_local_interrupt_controller(std::size_t major, std::size_t minor, std::uint64_t hardware_id, - memory::physical_address address) -> kstd::unique_ptr; - //! @} } // namespace kapi::acpi diff --git a/kapi/include/kapi/platform.hpp b/kapi/include/kapi/platform.hpp new file mode 100644 index 0000000..6aae795 --- /dev/null +++ b/kapi/include/kapi/platform.hpp @@ -0,0 +1,37 @@ +#ifndef TEACHOS_KAPI_PLATFORM_HPP +#define TEACHOS_KAPI_PLATFORM_HPP + +#include "kapi/devices.hpp" + +#include + +#include +#include + +namespace kapi::platform +{ + + //! @addtogroup kapi-platform-kernel-defined + //! @{ + + auto cpu_detected(kapi::devices::bus & bus, std::uint64_t hardware_id, bool is_bsp) -> 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; + + auto create_core_interrupt_controller(std::size_t major, std::size_t minor, std::uint64_t hardware_id) + -> kstd::unique_ptr; + + //! @} + +} // namespace kapi::platform + +#endif \ No newline at end of file -- cgit v1.2.3 From d5c2e101d62f6b4b69c45c127e7a729d246da566 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 19:04:16 +0200 Subject: kapi/platform: invert discovery dependencies --- kapi/include/kapi/platform.hpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/platform.hpp b/kapi/include/kapi/platform.hpp index 6aae795..e1e267e 100644 --- a/kapi/include/kapi/platform.hpp +++ b/kapi/include/kapi/platform.hpp @@ -14,8 +14,8 @@ namespace kapi::platform //! @addtogroup kapi-platform-kernel-defined //! @{ - auto cpu_detected(kapi::devices::bus & bus, std::uint64_t hardware_id, bool is_bsp) -> bool; - + 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 core_interrupt_controller) -> bool; //! @} //! @addtogroup kapi-platform-platform-defined @@ -27,9 +27,6 @@ namespace kapi::platform //! @return true iff. the CPU topology was discovered successfully, false otherwise. auto discover_cpu_topology(kapi::devices::bus & bus) -> bool; - auto create_core_interrupt_controller(std::size_t major, std::size_t minor, std::uint64_t hardware_id) - -> kstd::unique_ptr; - //! @} } // namespace kapi::platform -- cgit v1.2.3 From 878852c94c4d56f303366cec177b3edef9b3b9c5 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 8 Apr 2026 13:54:52 +0200 Subject: kapi: add basic support for MMIO mapping --- kapi/include/kapi/memory.hpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'kapi') diff --git a/kapi/include/kapi/memory.hpp b/kapi/include/kapi/memory.hpp index 914ca61..ae33904 100644 --- a/kapi/include/kapi/memory.hpp +++ b/kapi/include/kapi/memory.hpp @@ -79,6 +79,36 @@ namespace kapi::memory //! @param page The page to unmap auto unmap(page page) -> void; + //! Initialize the Memory-mapped I/O region system. + //! + //! @param base The base address for the MMIO region. + //! @param page_count The number of pages the MMIO region is spans. + auto init_mmio(linear_address base, std::size_t page_count) -> void; + + //! Allocate a Memory-mapped I/O region of the given size. + //! + //! @warning This function will panic if the MMIO system has not been initialized! + //! @param page_count The number of pages to allocate. + auto allocate_mmio_region(std::size_t page_count) -> linear_address; + + //! Map a region of Memory-mapped I/O address space to a given hardware address using the given flags. + //! + //! @warning This function will panic if no page mapper has been registered, or the page has already been mapped. + //! This function will not ensure that the frame is not already in use. + //! + //! This function will always set the @p uncached flag. + //! + //! @param base The base of the virtual region. + //! @param hw_base The base of the hardware region. + //! @param flags The flags to apply. + auto map_mmio_region(linear_address base, physical_address hw_base, page_mapper::flags flags = {}) -> std::byte *; + + //! Release a Memory-mapped I/O region. + //! + //! @warning This function will panic if the MMIO system has not been initialized! + //! @param base The start address of the region to release. + auto release_mmio_region(linear_address base) -> void; + //! @} //! @addtogroup kapi-memory-platform-defined -- cgit v1.2.3 From 0e92017837490d3ce806cf511977ada06d11a2a7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 8 Apr 2026 15:50:48 +0200 Subject: kapi/bus: fix eager initialization --- kapi/include/kapi/devices/bus.hpp | 1 + 1 file changed, 1 insertion(+) (limited to 'kapi') diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index 7b2d41f..60134ff 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -52,6 +52,7 @@ namespace kapi::devices private: kstd::vector> m_devices; kstd::vector> m_observers; + std::atomic_flag m_init_was_called{}; std::atomic_flag m_initialized{}; }; -- cgit v1.2.3 From aa208226f992523865328d4612ae4a7679f57a04 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 8 Apr 2026 17:17:11 +0200 Subject: kapi: return region pair for MMIO allocation --- kapi/include/kapi/memory.hpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/memory.hpp b/kapi/include/kapi/memory.hpp index ae33904..f5e126a 100644 --- a/kapi/include/kapi/memory.hpp +++ b/kapi/include/kapi/memory.hpp @@ -16,6 +16,8 @@ namespace kapi::memory { + using mmio_region = std::pair; + //! @addtogroup kapi-memory-kernel-defined //! @{ @@ -89,7 +91,7 @@ namespace kapi::memory //! //! @warning This function will panic if the MMIO system has not been initialized! //! @param page_count The number of pages to allocate. - auto allocate_mmio_region(std::size_t page_count) -> linear_address; + auto allocate_mmio_region(std::size_t page_count) -> mmio_region; //! Map a region of Memory-mapped I/O address space to a given hardware address using the given flags. //! @@ -98,16 +100,16 @@ namespace kapi::memory //! //! This function will always set the @p uncached flag. //! - //! @param base The base of the virtual region. + //! @param region The region to map. //! @param hw_base The base of the hardware region. //! @param flags The flags to apply. - auto map_mmio_region(linear_address base, physical_address hw_base, page_mapper::flags flags = {}) -> std::byte *; + auto map_mmio_region(mmio_region region, physical_address hw_base, page_mapper::flags flags = {}) -> std::byte *; //! Release a Memory-mapped I/O region. //! //! @warning This function will panic if the MMIO system has not been initialized! - //! @param base The start address of the region to release. - auto release_mmio_region(linear_address base) -> void; + //! @param region The region to release. + auto release_mmio_region(mmio_region region) -> void; //! @} -- cgit v1.2.3 From f6bea6a5f1939f3261392633f6caca186befd555 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 9 Apr 2026 15:54:04 +0200 Subject: kapi: restructure ACPI implementation --- kapi/include/kapi/acpi.hpp | 107 ++++----------------- .../kapi/acpi/multiple_apic_description_table.hpp | 104 ++++++++++++++++++++ kapi/include/kapi/acpi/pointers.hpp | 79 +++++++++++++++ .../kapi/acpi/system_description_table_header.hpp | 76 +++++++++++++++ kapi/include/kapi/acpi/table_iterator.hpp | 64 ++++++++++++ kapi/include/kapi/acpi/table_type.hpp | 22 +++++ 6 files changed, 363 insertions(+), 89 deletions(-) create mode 100644 kapi/include/kapi/acpi/multiple_apic_description_table.hpp create mode 100644 kapi/include/kapi/acpi/pointers.hpp create mode 100644 kapi/include/kapi/acpi/system_description_table_header.hpp create mode 100644 kapi/include/kapi/acpi/table_iterator.hpp create mode 100644 kapi/include/kapi/acpi/table_type.hpp (limited to 'kapi') 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 #include -#include #include -#include #include #include @@ -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 m_signature; - [[maybe_unused]] std::uint8_t m_checksum; - std::array m_oem_id; - std::uint8_t m_revision; - std::array 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 m_xsdt_address; - [[maybe_unused]] std::uint8_t m_extended_checksum; - [[maybe_unused]] std::array 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 m_signature; - std::uint32_t m_length; - std::uint8_t m_revision; - std::uint8_t m_checksum; - std::array m_oem_id; - std::array 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 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; + //! 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 + auto get_table() -> kstd::observer_ptr const> + { + return kstd::make_observer(static_cast 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; //! @} 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 +#include + +#include +#include +#include + +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; + 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 + { + using type = multiple_apic_description_table; + }; + + //! @} + +} // namespace kapi::acpi + +template<> +struct kstd::ext::is_bitfield_enum : 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 + +#include +#include +#include +#include + +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 m_signature; + [[maybe_unused]] std::uint8_t m_checksum; + std::array m_oem_id; + std::uint8_t m_revision; + std::array 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 m_xsdt_address; + [[maybe_unused]] std::uint8_t m_extended_checksum; + [[maybe_unused]] std::array 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 + +#include +#include +#include + +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 m_signature; + std::uint32_t m_length; + std::uint8_t m_revision; + [[maybe_unused]] std::uint8_t m_checksum; + std::array m_oem_id; + std::array 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 + { + 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 +#include +#include + +namespace kapi::acpi +{ + + template + 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(m_entry); + decayed += m_entry->length(); + m_entry = std::bit_cast(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 + struct table_type; + + template + using table_type_t = typename table_type::type; + + //! @} + +} // namespace kapi::acpi + +#endif -- cgit v1.2.3 From 3ad230fab8dc17758559aac3c20ba67a8c619878 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 10 Apr 2026 09:01:59 +0200 Subject: kapi: move platform functions to CPU --- kapi/include/kapi/cpu.hpp | 20 ++++++++++++++++++++ kapi/include/kapi/platform.hpp | 34 ---------------------------------- 2 files changed, 20 insertions(+), 34 deletions(-) delete mode 100644 kapi/include/kapi/platform.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/cpu.hpp b/kapi/include/kapi/cpu.hpp index d90365a..c643cd7 100644 --- a/kapi/include/kapi/cpu.hpp +++ b/kapi/include/kapi/cpu.hpp @@ -1,10 +1,13 @@ #ifndef TEACHOS_KAPI_CPU_HPP #define TEACHOS_KAPI_CPU_HPP +#include "kapi/devices.hpp" #include "kapi/memory.hpp" #include +#include +#include #include namespace kapi::cpu @@ -72,6 +75,17 @@ namespace kapi::cpu //! @return Whether the exception was handled. [[nodiscard]] auto dispatch(exception const & context) -> bool; + //! A hook that is called when the platform detects a CPU core during topology discovery. + //! + //! @param bus The bus the CPU was detected on. + //! @param major The major number of the CPU device. + //! @param minor The minor number of the CPU device. + //! @param hardware_id The hardware specific ID of the CPU core. + //! @param is_bsp Whether the reported CPU is the the bootstrap processor. + //! @param core_interrupt_controller The local interrupt controller of this CPU core. + auto core_detected(kapi::devices::bus & bus, std::size_t major, std::size_t minor, std::uint64_t hardware_id, + bool is_bsp, kstd::unique_ptr core_interrupt_controller) -> bool; + //! @} //! @addtogroup kapi-cpu-platform-defined @@ -88,6 +102,12 @@ namespace kapi::cpu //! interrupts itself. auto init() -> void; + //! 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_topology(kapi::devices::bus & bus) -> bool; + //! @} } // namespace kapi::cpu diff --git a/kapi/include/kapi/platform.hpp b/kapi/include/kapi/platform.hpp deleted file mode 100644 index e1e267e..0000000 --- a/kapi/include/kapi/platform.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef TEACHOS_KAPI_PLATFORM_HPP -#define TEACHOS_KAPI_PLATFORM_HPP - -#include "kapi/devices.hpp" - -#include - -#include -#include - -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 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 -- cgit v1.2.3 From dd8dfa3e674d05927e9ed4b7efcb634a634bfdcc Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 10 Apr 2026 10:30:32 +0200 Subject: kapi: move CPU to kapi --- kapi/include/kapi/cpu.hpp | 16 +--------------- kapi/include/kapi/devices.hpp | 1 + kapi/include/kapi/devices/cpu.hpp | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 kapi/include/kapi/devices/cpu.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/cpu.hpp b/kapi/include/kapi/cpu.hpp index c643cd7..e736be1 100644 --- a/kapi/include/kapi/cpu.hpp +++ b/kapi/include/kapi/cpu.hpp @@ -1,13 +1,11 @@ #ifndef TEACHOS_KAPI_CPU_HPP #define TEACHOS_KAPI_CPU_HPP -#include "kapi/devices.hpp" #include "kapi/memory.hpp" #include #include -#include #include namespace kapi::cpu @@ -75,17 +73,6 @@ namespace kapi::cpu //! @return Whether the exception was handled. [[nodiscard]] auto dispatch(exception const & context) -> bool; - //! A hook that is called when the platform detects a CPU core during topology discovery. - //! - //! @param bus The bus the CPU was detected on. - //! @param major The major number of the CPU device. - //! @param minor The minor number of the CPU device. - //! @param hardware_id The hardware specific ID of the CPU core. - //! @param is_bsp Whether the reported CPU is the the bootstrap processor. - //! @param core_interrupt_controller The local interrupt controller of this CPU core. - auto core_detected(kapi::devices::bus & bus, std::size_t major, std::size_t minor, std::uint64_t hardware_id, - bool is_bsp, kstd::unique_ptr core_interrupt_controller) -> bool; - //! @} //! @addtogroup kapi-cpu-platform-defined @@ -104,9 +91,8 @@ namespace kapi::cpu //! 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_topology(kapi::devices::bus & bus) -> bool; + auto discover_topology() -> bool; //! @} diff --git a/kapi/include/kapi/devices.hpp b/kapi/include/kapi/devices.hpp index c26efb9..ec154a5 100644 --- a/kapi/include/kapi/devices.hpp +++ b/kapi/include/kapi/devices.hpp @@ -2,6 +2,7 @@ #define TEACHOS_KAPI_DEVICES_HPP #include "kapi/devices/bus.hpp" // IWYU pragma: export +#include "kapi/devices/cpu.hpp" // IWYU pragma: export #include "kapi/devices/device.hpp" // IWYU pragma: export #include "kapi/devices/manager.hpp" // IWYU pragma: export diff --git a/kapi/include/kapi/devices/cpu.hpp b/kapi/include/kapi/devices/cpu.hpp new file mode 100644 index 0000000..00766b5 --- /dev/null +++ b/kapi/include/kapi/devices/cpu.hpp @@ -0,0 +1,37 @@ +#ifndef TEACHOS_KAPI_DEVICES_CPU_HPP +#define TEACHOS_KAPI_DEVICES_CPU_HPP + +#include "kapi/devices/bus.hpp" + +#include +#include + +namespace kapi::devices +{ + + //! A virtual CPU bus to host all CPUs in the system. + struct cpu final : kapi::devices::bus + { + //! A virtual CPU Core to host all core local devices. + struct core final : kapi::devices::bus + { + explicit core(std::size_t major_number, std::size_t minor_number, std::uint64_t hardware_id, bool is_bsp); + + [[nodiscard]] auto hardware_id() const -> std::uint64_t; + [[nodiscard]] auto is_bsp() const -> bool; + + private: + std::uint64_t m_hardware_id; + bool m_is_bsp; + }; + + //! Create a new CPU with the given major and minor numbers. + //! + //! @param major The major number of this CPU + //! @param minor The minor number of this CPU, identifying the physical CPU + cpu(std::size_t major, std::size_t minor); + }; + +} // namespace kapi::devices + +#endif \ No newline at end of file -- cgit v1.2.3 From 5a6b6ab376e67b173ef36f831445ccba7e86e038 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 10 Apr 2026 10:38:51 +0200 Subject: kapi/devices: add parent back-pointer to device --- kapi/include/kapi/devices/device.hpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'kapi') diff --git a/kapi/include/kapi/devices/device.hpp b/kapi/include/kapi/devices/device.hpp index b3647da..9939494 100644 --- a/kapi/include/kapi/devices/device.hpp +++ b/kapi/include/kapi/devices/device.hpp @@ -3,6 +3,7 @@ // IWYU pragma: private, include "kapi/devices.hpp" +#include #include #include @@ -62,9 +63,14 @@ namespace kapi::devices [[nodiscard]] virtual auto is_block_device() const -> bool; private: + friend struct bus; + + auto set_parent(kstd::observer_ptr parent) -> void; + size_t m_major; size_t m_minor; kstd::string m_name; + kstd::observer_ptr m_parent; }; //! @} -- cgit v1.2.3 From c3f7b747f02a79b34ed914c54ce74be973b17af1 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 10 Apr 2026 17:39:14 +0200 Subject: kapi: extract ACPI functionality to libs --- kapi/CMakeLists.txt | 1 + kapi/include/kapi/acpi.hpp | 25 ++--- .../kapi/acpi/multiple_apic_description_table.hpp | 104 --------------------- kapi/include/kapi/acpi/pointers.hpp | 79 ---------------- .../kapi/acpi/system_description_table_header.hpp | 76 --------------- kapi/include/kapi/acpi/table_iterator.hpp | 64 ------------- kapi/include/kapi/acpi/table_type.hpp | 22 ----- 7 files changed, 8 insertions(+), 363 deletions(-) delete mode 100644 kapi/include/kapi/acpi/multiple_apic_description_table.hpp delete mode 100644 kapi/include/kapi/acpi/pointers.hpp delete mode 100644 kapi/include/kapi/acpi/system_description_table_header.hpp delete mode 100644 kapi/include/kapi/acpi/table_iterator.hpp delete mode 100644 kapi/include/kapi/acpi/table_type.hpp (limited to 'kapi') diff --git a/kapi/CMakeLists.txt b/kapi/CMakeLists.txt index c9aa23f..99a8725 100644 --- a/kapi/CMakeLists.txt +++ b/kapi/CMakeLists.txt @@ -15,6 +15,7 @@ target_include_directories("kapi" INTERFACE ) target_link_libraries("kapi" INTERFACE + "libs::acpi" "libs::kstd" "gcc" diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp index 5323fee..01fd113 100644 --- a/kapi/include/kapi/acpi.hpp +++ b/kapi/include/kapi/acpi.hpp @@ -1,16 +1,11 @@ #ifndef TEACHOS_KAPI_ACPI_HPP #define TEACHOS_KAPI_ACPI_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 #include -#include -#include +#include + #include namespace kapi::acpi @@ -22,28 +17,22 @@ namespace kapi::acpi //! 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 data) -> bool; + auto init(::acpi::rsdp const & sdp) -> bool; //! 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; + auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt 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 - auto get_table() -> kstd::observer_ptr const> + auto get_table() -> kstd::observer_ptr<::acpi::table_type_t const> { - return kstd::make_observer(static_cast const *>(get_table(Signature).get())); + return kstd::make_observer(static_cast<::acpi::table_type_t const *>(get_table(Signature).get())); } //! @} @@ -54,7 +43,7 @@ namespace kapi::acpi //! 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; + auto get_root_pointer() -> kstd::observer_ptr<::acpi::rsdp const>; //! @} diff --git a/kapi/include/kapi/acpi/multiple_apic_description_table.hpp b/kapi/include/kapi/acpi/multiple_apic_description_table.hpp deleted file mode 100644 index 33acac9..0000000 --- a/kapi/include/kapi/acpi/multiple_apic_description_table.hpp +++ /dev/null @@ -1,104 +0,0 @@ -#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 -#include - -#include -#include -#include - -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; - 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 - { - using type = multiple_apic_description_table; - }; - - //! @} - -} // namespace kapi::acpi - -template<> -struct kstd::ext::is_bitfield_enum : std::true_type -{ -}; - -#endif diff --git a/kapi/include/kapi/acpi/pointers.hpp b/kapi/include/kapi/acpi/pointers.hpp deleted file mode 100644 index 2b88720..0000000 --- a/kapi/include/kapi/acpi/pointers.hpp +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef TEACHOS_KAPI_ACPI_POINTERS_HPP -#define TEACHOS_KAPI_ACPI_POINTERS_HPP - -// IWYU pragma: private, include "kapi/acpi.hpp" - -#include "kapi/memory.hpp" - -#include - -#include -#include -#include -#include - -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 m_signature; - [[maybe_unused]] std::uint8_t m_checksum; - std::array m_oem_id; - std::uint8_t m_revision; - std::array 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 m_xsdt_address; - [[maybe_unused]] std::uint8_t m_extended_checksum; - [[maybe_unused]] std::array 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 deleted file mode 100644 index b336ea1..0000000 --- a/kapi/include/kapi/acpi/system_description_table_header.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#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 - -#include -#include -#include - -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 m_signature; - std::uint32_t m_length; - std::uint8_t m_revision; - [[maybe_unused]] std::uint8_t m_checksum; - std::array m_oem_id; - std::array 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 - { - 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 deleted file mode 100644 index 998d6d6..0000000 --- a/kapi/include/kapi/acpi/table_iterator.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef TEACHOS_KAPI_ACPI_TABLE_ITERATOR_HPP -#define TEACHOS_KAPI_ACPI_TABLE_ITERATOR_HPP - -#include -#include -#include - -namespace kapi::acpi -{ - - template - 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(m_entry); - decayed += m_entry->length(); - m_entry = std::bit_cast(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 deleted file mode 100644 index e088a24..0000000 --- a/kapi/include/kapi/acpi/table_type.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#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 - struct table_type; - - template - using table_type_t = typename table_type::type; - - //! @} - -} // namespace kapi::acpi - -#endif -- cgit v1.2.3 From 21fd1281cf19572e202d583689b99c33ec68da50 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 10 Apr 2026 17:49:40 +0200 Subject: kernel: let arch initialize the ACPI manager --- kapi/include/kapi/acpi.hpp | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp index 01fd113..2835496 100644 --- a/kapi/include/kapi/acpi.hpp +++ b/kapi/include/kapi/acpi.hpp @@ -35,18 +35,6 @@ namespace kapi::acpi return kstd::make_observer(static_cast<::acpi::table_type_t 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<::acpi::rsdp const>; - - //! @} - } // namespace kapi::acpi #endif -- cgit v1.2.3 From bb01b9f2d29524974881e9a88ffb6c229836ddba Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Sun, 12 Apr 2026 20:45:23 +0200 Subject: Add fs syscall handler --- kapi/include/kapi/syscall_handler/filesystem.hpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 kapi/include/kapi/syscall_handler/filesystem.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/syscall_handler/filesystem.hpp b/kapi/include/kapi/syscall_handler/filesystem.hpp new file mode 100644 index 0000000..86ae4d2 --- /dev/null +++ b/kapi/include/kapi/syscall_handler/filesystem.hpp @@ -0,0 +1,19 @@ +#ifndef TEACHOS_KAPI_SYSCALL_HANDLER_FILESYSTEM_HPP +#define TEACHOS_KAPI_SYSCALL_HANDLER_FILESYSTEM_HPP + +#include +#include + +namespace kapi::syscall_handler::filesystem +{ + auto mount(char const * source, char const * target) -> int; + auto umount(char const * target) -> int; + + auto open(char const * path) -> int; + auto close(int fd) -> int; + + auto read(int fd, void * buffer, size_t size) -> ssize_t; + auto write(int fd, void const * buffer, size_t size) -> ssize_t; +} // namespace kapi::syscall_handler::filesystem + +#endif // TEACHOS_KAPI_SYSCALL_HANDLER_FILESYSTEM_HPP \ No newline at end of file -- cgit v1.2.3 From eb36544624c18a284debdf78b43fe627f40a8371 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 13 Apr 2026 18:49:21 +0200 Subject: Rename and refactor --- kapi/include/kapi/filesystem.hpp | 20 ++++++++++++++++++++ kapi/include/kapi/syscall_handler/filesystem.hpp | 19 ------------------- 2 files changed, 20 insertions(+), 19 deletions(-) create mode 100644 kapi/include/kapi/filesystem.hpp delete mode 100644 kapi/include/kapi/syscall_handler/filesystem.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/filesystem.hpp b/kapi/include/kapi/filesystem.hpp new file mode 100644 index 0000000..dba5d54 --- /dev/null +++ b/kapi/include/kapi/filesystem.hpp @@ -0,0 +1,20 @@ +#ifndef TEACHOS_KAPI_FILESYSTEM_HPP +#define TEACHOS_KAPI_FILESYSTEM_HPP + +#include +#include +#include + +namespace kapi::filesystem +{ + auto mount(std::string_view source, std::string_view target) -> int; + auto umount(std::string_view target) -> int; + + auto open(std::string_view path) -> int; + auto close(int fd) -> int; + + auto read(int fd, void * buffer, size_t size) -> ssize_t; + auto write(int fd, void const * buffer, size_t size) -> ssize_t; +} // namespace kapi::filesystem + +#endif // TEACHOS_KAPI_FILESYSTEM_HPP \ No newline at end of file diff --git a/kapi/include/kapi/syscall_handler/filesystem.hpp b/kapi/include/kapi/syscall_handler/filesystem.hpp deleted file mode 100644 index 86ae4d2..0000000 --- a/kapi/include/kapi/syscall_handler/filesystem.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef TEACHOS_KAPI_SYSCALL_HANDLER_FILESYSTEM_HPP -#define TEACHOS_KAPI_SYSCALL_HANDLER_FILESYSTEM_HPP - -#include -#include - -namespace kapi::syscall_handler::filesystem -{ - auto mount(char const * source, char const * target) -> int; - auto umount(char const * target) -> int; - - auto open(char const * path) -> int; - auto close(int fd) -> int; - - auto read(int fd, void * buffer, size_t size) -> ssize_t; - auto write(int fd, void const * buffer, size_t size) -> ssize_t; -} // namespace kapi::syscall_handler::filesystem - -#endif // TEACHOS_KAPI_SYSCALL_HANDLER_FILESYSTEM_HPP \ No newline at end of file -- cgit v1.2.3 From 252df23b061b2bf54206da73e41faca600541ccc Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 16 Apr 2026 09:26:52 +0200 Subject: acpi: introduce VLA table --- kapi/include/kapi/acpi.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kapi') diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp index 2835496..b607ee0 100644 --- a/kapi/include/kapi/acpi.hpp +++ b/kapi/include/kapi/acpi.hpp @@ -23,7 +23,7 @@ namespace kapi::acpi //! //! @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<::acpi::sdt const>; + auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::table_header const>; //! Get a type-cast pointer to an ACPI table by its signature. //! -- cgit v1.2.3 From 9b4cbc6ba3f8059278a20a4893780717851ce8e4 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 21 Apr 2026 13:06:35 +0200 Subject: build: clean up configuration --- kapi/CMakeLists.txt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'kapi') diff --git a/kapi/CMakeLists.txt b/kapi/CMakeLists.txt index 99a8725..d15b923 100644 --- a/kapi/CMakeLists.txt +++ b/kapi/CMakeLists.txt @@ -1,7 +1,11 @@ add_library("kapi" INTERFACE) -add_library("os::kapi" ALIAS "kapi") +add_library("kapi::lib" ALIAS "kapi") -file(GLOB_RECURSE KAPI_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "include/**.hpp") +file(GLOB_RECURSE KAPI_HEADERS + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + CONFIGURE_DEPENDS + "include/**.hpp" +) target_sources("kapi" PUBLIC FILE_SET HEADERS @@ -15,9 +19,13 @@ target_include_directories("kapi" INTERFACE ) target_link_libraries("kapi" INTERFACE - "libs::acpi" - "libs::kstd" + "acpi::lib" + "kstd::lib" "gcc" "stdc++" ) + +set_target_properties("kapi" PROPERTIES + VERIFY_INTERFACE_HEADER_SETS YES +) -- cgit v1.2.3 From 2d8fed40bd0d0f8144783b6b344dc79944291b72 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 23 Apr 2026 13:31:17 +0200 Subject: chore: organize includes --- kapi/include/kapi/acpi.hpp | 4 ++-- kapi/include/kapi/filesystem.hpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp index b607ee0..885fcde 100644 --- a/kapi/include/kapi/acpi.hpp +++ b/kapi/include/kapi/acpi.hpp @@ -1,11 +1,11 @@ #ifndef TEACHOS_KAPI_ACPI_HPP #define TEACHOS_KAPI_ACPI_HPP +#include + #include #include -#include - #include namespace kapi::acpi diff --git a/kapi/include/kapi/filesystem.hpp b/kapi/include/kapi/filesystem.hpp index dba5d54..db77bda 100644 --- a/kapi/include/kapi/filesystem.hpp +++ b/kapi/include/kapi/filesystem.hpp @@ -3,6 +3,7 @@ #include #include + #include namespace kapi::filesystem -- cgit v1.2.3 From f6f10575f75ac23d06e1d94f7861611503daa7af Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 23 Apr 2026 14:03:28 +0200 Subject: chore: banish relative includes --- kapi/include/kapi/boot_module/boot_module.hpp | 2 +- kapi/include/kapi/boot_module/boot_module_registry.hpp | 2 +- kapi/include/kapi/boot_modules.hpp | 2 +- kapi/include/kapi/cio.hpp | 2 +- kapi/include/kapi/cio/output_device.hpp | 2 +- kapi/include/kapi/cpu.hpp | 2 +- kapi/include/kapi/devices.hpp | 8 ++++---- kapi/include/kapi/devices/bus.hpp | 4 ++-- kapi/include/kapi/devices/cpu.hpp | 2 +- kapi/include/kapi/devices/device.hpp | 2 +- kapi/include/kapi/devices/manager.hpp | 4 ++-- kapi/include/kapi/memory.hpp | 14 +++++++------- kapi/include/kapi/memory/address.hpp | 2 +- kapi/include/kapi/memory/chunk.hpp | 2 +- kapi/include/kapi/memory/frame.hpp | 8 ++++---- kapi/include/kapi/memory/frame_allocator.hpp | 4 ++-- kapi/include/kapi/memory/layout.hpp | 4 ++-- kapi/include/kapi/memory/page.hpp | 8 ++++---- kapi/include/kapi/memory/page_mapper.hpp | 6 +++--- 19 files changed, 40 insertions(+), 40 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/boot_module/boot_module.hpp b/kapi/include/kapi/boot_module/boot_module.hpp index 85a1ac5..9b4b165 100644 --- a/kapi/include/kapi/boot_module/boot_module.hpp +++ b/kapi/include/kapi/boot_module/boot_module.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_HPP #define TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_HPP -#include "kapi/memory.hpp" +#include #include #include diff --git a/kapi/include/kapi/boot_module/boot_module_registry.hpp b/kapi/include/kapi/boot_module/boot_module_registry.hpp index 0692d37..fc3590f 100644 --- a/kapi/include/kapi/boot_module/boot_module_registry.hpp +++ b/kapi/include/kapi/boot_module/boot_module_registry.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_REGISTRY_HPP #define TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_REGISTRY_HPP -#include "kapi/boot_module/boot_module.hpp" +#include #include diff --git a/kapi/include/kapi/boot_modules.hpp b/kapi/include/kapi/boot_modules.hpp index 6eee169..026479d 100644 --- a/kapi/include/kapi/boot_modules.hpp +++ b/kapi/include/kapi/boot_modules.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KAPI_BOOT_MODULES_HPP #define TEACHOS_KAPI_BOOT_MODULES_HPP -#include "kapi/boot_module/boot_module_registry.hpp" // IWYU pragma: export +#include // IWYU pragma: export namespace kapi::boot_modules { diff --git a/kapi/include/kapi/cio.hpp b/kapi/include/kapi/cio.hpp index 8941a9f..9bbf7fa 100644 --- a/kapi/include/kapi/cio.hpp +++ b/kapi/include/kapi/cio.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KAPI_CIO_HPP #define TEACHOS_KAPI_CIO_HPP -#include "kapi/cio/output_device.hpp" // IWYU pragma: export +#include // IWYU pragma: export #include diff --git a/kapi/include/kapi/cio/output_device.hpp b/kapi/include/kapi/cio/output_device.hpp index f08d7ba..9fe2557 100644 --- a/kapi/include/kapi/cio/output_device.hpp +++ b/kapi/include/kapi/cio/output_device.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KAPI_CIO_OUTPUT_DEVICE_HPP #define TEACHOS_KAPI_CIO_OUTPUT_DEVICE_HPP -// IWYU pragma: private, include "kapi/cio.hpp" +// IWYU pragma: private, include #include diff --git a/kapi/include/kapi/cpu.hpp b/kapi/include/kapi/cpu.hpp index e736be1..deaf5cd 100644 --- a/kapi/include/kapi/cpu.hpp +++ b/kapi/include/kapi/cpu.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KAPI_CPU_HPP #define TEACHOS_KAPI_CPU_HPP -#include "kapi/memory.hpp" +#include #include #include diff --git a/kapi/include/kapi/devices.hpp b/kapi/include/kapi/devices.hpp index ec154a5..b597aa8 100644 --- a/kapi/include/kapi/devices.hpp +++ b/kapi/include/kapi/devices.hpp @@ -1,10 +1,10 @@ #ifndef TEACHOS_KAPI_DEVICES_HPP #define TEACHOS_KAPI_DEVICES_HPP -#include "kapi/devices/bus.hpp" // IWYU pragma: export -#include "kapi/devices/cpu.hpp" // IWYU pragma: export -#include "kapi/devices/device.hpp" // IWYU pragma: export -#include "kapi/devices/manager.hpp" // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export namespace kapi::devices { diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index 60134ff..59f49f7 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -1,9 +1,9 @@ #ifndef TEACHOS_KAPI_DEVICES_BUS_HPP #define TEACHOS_KAPI_DEVICES_BUS_HPP -// IWYU pragma: private, include "kapi/devices.hpp" +// IWYU pragma: private, include -#include "kapi/devices/device.hpp" +#include #include #include diff --git a/kapi/include/kapi/devices/cpu.hpp b/kapi/include/kapi/devices/cpu.hpp index 00766b5..f8ff60c 100644 --- a/kapi/include/kapi/devices/cpu.hpp +++ b/kapi/include/kapi/devices/cpu.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KAPI_DEVICES_CPU_HPP #define TEACHOS_KAPI_DEVICES_CPU_HPP -#include "kapi/devices/bus.hpp" +#include #include #include diff --git a/kapi/include/kapi/devices/device.hpp b/kapi/include/kapi/devices/device.hpp index 9939494..70cf01f 100644 --- a/kapi/include/kapi/devices/device.hpp +++ b/kapi/include/kapi/devices/device.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KAPI_DEVICES_DEVICE_HPP #define TEACH_OS_KAPI_DEVICES_DEVICE_HPP -// IWYU pragma: private, include "kapi/devices.hpp" +// IWYU pragma: private, include #include #include diff --git a/kapi/include/kapi/devices/manager.hpp b/kapi/include/kapi/devices/manager.hpp index f19366e..c9b90b4 100644 --- a/kapi/include/kapi/devices/manager.hpp +++ b/kapi/include/kapi/devices/manager.hpp @@ -1,9 +1,9 @@ #ifndef TEACHOS_KAPI_DEVICES_MANAGER_HPP #define TEACHOS_KAPI_DEVICES_MANAGER_HPP -// IWYU pragma: private, include "kapi/devices.hpp" +// IWYU pragma: private, include -#include "kapi/devices/device.hpp" +#include #include diff --git a/kapi/include/kapi/memory.hpp b/kapi/include/kapi/memory.hpp index f5e126a..8ad8d6e 100644 --- a/kapi/include/kapi/memory.hpp +++ b/kapi/include/kapi/memory.hpp @@ -1,13 +1,13 @@ #ifndef TEACHOS_KAPI_MEMORY_HPP #define TEACHOS_KAPI_MEMORY_HPP -#include "kapi/memory/address.hpp" // IWYU pragma: export -#include "kapi/memory/chunk.hpp" // IWYU pragma: export -#include "kapi/memory/frame.hpp" // IWYU pragma: export -#include "kapi/memory/frame_allocator.hpp" // IWYU pragma: export -#include "kapi/memory/layout.hpp" // IWYU pragma: export -#include "kapi/memory/page.hpp" // IWYU pragma: export -#include "kapi/memory/page_mapper.hpp" // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export #include #include diff --git a/kapi/include/kapi/memory/address.hpp b/kapi/include/kapi/memory/address.hpp index 13bdf4c..9231cfc 100644 --- a/kapi/include/kapi/memory/address.hpp +++ b/kapi/include/kapi/memory/address.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KAPI_MEMORY_ADDRESS_HPP #define TEACHOS_KAPI_MEMORY_ADDRESS_HPP -// IWYU pragma: private, include "kapi/memory.hpp" +// IWYU pragma: private, include #include #include diff --git a/kapi/include/kapi/memory/chunk.hpp b/kapi/include/kapi/memory/chunk.hpp index a046221..485a890 100644 --- a/kapi/include/kapi/memory/chunk.hpp +++ b/kapi/include/kapi/memory/chunk.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KAPI_MEMORY_CHUNK_HPP #define TEACHOS_KAPI_MEMORY_CHUNK_HPP -// IWYU pragma: private, include "kapi/memory.hpp" +// IWYU pragma: private, include #include diff --git a/kapi/include/kapi/memory/frame.hpp b/kapi/include/kapi/memory/frame.hpp index a55b6ff..e423fa4 100644 --- a/kapi/include/kapi/memory/frame.hpp +++ b/kapi/include/kapi/memory/frame.hpp @@ -1,11 +1,11 @@ #ifndef TEACHOS_KAPI_MEMORY_FRAME_HPP #define TEACHOS_KAPI_MEMORY_FRAME_HPP -// IWYU pragma: private, include "kapi/memory.hpp" +// IWYU pragma: private, include -#include "kapi/memory/address.hpp" -#include "kapi/memory/chunk.hpp" -#include "kapi/memory/layout.hpp" +#include +#include +#include #include diff --git a/kapi/include/kapi/memory/frame_allocator.hpp b/kapi/include/kapi/memory/frame_allocator.hpp index cfa8a1c..784ea93 100644 --- a/kapi/include/kapi/memory/frame_allocator.hpp +++ b/kapi/include/kapi/memory/frame_allocator.hpp @@ -1,9 +1,9 @@ #ifndef TEACHOS_KAPI_MEMORY_FRAME_ALLOCATOR_HPP #define TEACHOS_KAPI_MEMORY_FRAME_ALLOCATOR_HPP -// IWYU pragma: private, include "kapi/memory.hpp" +// IWYU pragma: private, include -#include "kapi/memory/frame.hpp" +#include #include #include diff --git a/kapi/include/kapi/memory/layout.hpp b/kapi/include/kapi/memory/layout.hpp index 26b48d8..733fa96 100644 --- a/kapi/include/kapi/memory/layout.hpp +++ b/kapi/include/kapi/memory/layout.hpp @@ -1,9 +1,9 @@ #ifndef TEACHOS_KAPI_MEMORY_LAYOUT_HPP #define TEACHOS_KAPI_MEMORY_LAYOUT_HPP -// IWYU pragma: private, include "kapi/memory.hpp" +// IWYU pragma: private, include -#include "kapi/memory/address.hpp" +#include #include diff --git a/kapi/include/kapi/memory/page.hpp b/kapi/include/kapi/memory/page.hpp index aa161ee..d987534 100644 --- a/kapi/include/kapi/memory/page.hpp +++ b/kapi/include/kapi/memory/page.hpp @@ -1,11 +1,11 @@ #ifndef TEACHOS_KAPI_MEMORY_PAGE_HPP #define TEACHOS_KAPI_MEMORY_PAGE_HPP -// IWYU pragma: private, include "kapi/memory.hpp" +// IWYU pragma: private, include -#include "kapi/memory/address.hpp" -#include "kapi/memory/chunk.hpp" -#include "kapi/memory/layout.hpp" +#include +#include +#include #include diff --git a/kapi/include/kapi/memory/page_mapper.hpp b/kapi/include/kapi/memory/page_mapper.hpp index c6052e9..fb600b2 100644 --- a/kapi/include/kapi/memory/page_mapper.hpp +++ b/kapi/include/kapi/memory/page_mapper.hpp @@ -1,10 +1,10 @@ #ifndef TEACHOS_KAPI_MEMORY_PAGE_MAPPER_HPP #define TEACHOS_KAPI_MEMORY_PAGE_MAPPER_HPP -// IWYU pragma: private, include "kapi/memory.hpp" +// IWYU pragma: private, include -#include "kapi/memory/frame.hpp" -#include "kapi/memory/page.hpp" +#include +#include #include -- cgit v1.2.3 From c002a6fe53375d8757d43c48c59ac7f327f412b5 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 25 Apr 2026 23:31:26 +0200 Subject: add documentation, refactoring --- kapi/include/kapi/filesystem.hpp | 58 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/filesystem.hpp b/kapi/include/kapi/filesystem.hpp index db77bda..94d42ce 100644 --- a/kapi/include/kapi/filesystem.hpp +++ b/kapi/include/kapi/filesystem.hpp @@ -8,14 +8,66 @@ namespace kapi::filesystem { + /** + @brief The kapi::filesystem namespace provides the interface for filesystem operations in the kernel. It includes + functions for mounting and unmounting filesystems, as well as basic file operations such as opening, closing, reading + from, and writing to files. The actual implementation of these functions is in the kernel's filesystem subsystem, + which will handle the specifics of different filesystem types and their interactions with the underlying storage + devices. + */ + + /** + @brief Mounts a filesystem from the specified @p source at the specified @p target path. + @param source The source device or filesystem to mount. + @param target The target mount point. + @return 0 on success, -1 on failure. + @qualifier kernel-defined + */ auto mount(std::string_view source, std::string_view target) -> int; + + /** + @brief Unmounts a filesystem from the specified @p target path. + @param target The target mount point to unmount. + @return 0 on success, -1 on failure. + @qualifier kernel-defined + */ auto umount(std::string_view target) -> int; + /** + @brief Opens a file at the specified @p path. + @param path The path to the file to open. + @return A file descriptor on success, -1 on failure. + @qualifier kernel-defined + */ auto open(std::string_view path) -> int; - auto close(int fd) -> int; - auto read(int fd, void * buffer, size_t size) -> ssize_t; - auto write(int fd, void const * buffer, size_t size) -> ssize_t; + /** + @brief Closes a @p file_descriptor. + @param file_descriptor The file descriptor to close. + @return 0 on success, -1 on failure. + @qualifier kernel-defined + */ + auto close(int file_descriptor) -> int; + + /** + @brief Reads @p size bytes into @p buffer from a @p file_descriptor. + @param file_descriptor The file descriptor to read from. + @param buffer The buffer to store the read data. + @param size The number of bytes to read. + @return The number of bytes read on success, -1 on failure. + @qualifier kernel-defined + */ + auto read(int file_descriptor, void * buffer, size_t size) -> ssize_t; + + /** + @brief Writes @p size bytes from @p buffer to a @p file_descriptor. + @param file_descriptor The file descriptor to write to. + @param buffer The buffer containing the data to write. + @param size The number of bytes to write. + @return The number of bytes written on success, -1 on failure. + @qualifier kernel-defined + */ + auto write(int file_descriptor, void const * buffer, size_t size) -> ssize_t; } // namespace kapi::filesystem #endif // TEACHOS_KAPI_FILESYSTEM_HPP \ No newline at end of file -- cgit v1.2.3 From 4b71a936183070e43a6ca73c2975eae70742e124 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 29 Apr 2026 09:25:53 +0200 Subject: chore: migrate 'kapi' to p1204 layout --- kapi/CMakeLists.txt | 2 +- kapi/include/kapi/acpi.hpp | 40 ---- kapi/include/kapi/boot.hpp | 17 -- kapi/include/kapi/boot_module/boot_module.hpp | 23 -- .../kapi/boot_module/boot_module_registry.hpp | 107 --------- kapi/include/kapi/boot_modules.hpp | 31 --- kapi/include/kapi/cio.hpp | 48 ---- kapi/include/kapi/cio/output_device.hpp | 39 ---- kapi/include/kapi/cpu.hpp | 135 ----------- kapi/include/kapi/devices.hpp | 37 --- kapi/include/kapi/devices/bus.hpp | 63 ------ kapi/include/kapi/devices/cpu.hpp | 37 --- kapi/include/kapi/devices/device.hpp | 80 ------- kapi/include/kapi/devices/manager.hpp | 53 ----- kapi/include/kapi/filesystem.hpp | 73 ------ kapi/include/kapi/interrupts.hpp | 74 ------ kapi/include/kapi/memory.hpp | 131 ----------- kapi/include/kapi/memory/address.hpp | 252 --------------------- kapi/include/kapi/memory/chunk.hpp | 109 --------- kapi/include/kapi/memory/frame.hpp | 48 ---- kapi/include/kapi/memory/frame_allocator.hpp | 66 ------ kapi/include/kapi/memory/layout.hpp | 54 ----- kapi/include/kapi/memory/page.hpp | 38 ---- kapi/include/kapi/memory/page_mapper.hpp | 90 -------- kapi/include/kapi/system.hpp | 32 --- kapi/kapi/acpi.hpp | 40 ++++ kapi/kapi/boot.hpp | 17 ++ kapi/kapi/boot_module/boot_module.hpp | 23 ++ kapi/kapi/boot_module/boot_module_registry.hpp | 107 +++++++++ kapi/kapi/boot_modules.hpp | 31 +++ kapi/kapi/cio.hpp | 48 ++++ kapi/kapi/cio/output_device.hpp | 39 ++++ kapi/kapi/cpu.hpp | 135 +++++++++++ kapi/kapi/devices.hpp | 37 +++ kapi/kapi/devices/bus.hpp | 63 ++++++ kapi/kapi/devices/cpu.hpp | 37 +++ kapi/kapi/devices/device.hpp | 80 +++++++ kapi/kapi/devices/manager.hpp | 53 +++++ kapi/kapi/filesystem.hpp | 73 ++++++ kapi/kapi/interrupts.hpp | 74 ++++++ kapi/kapi/memory.hpp | 131 +++++++++++ kapi/kapi/memory/address.hpp | 252 +++++++++++++++++++++ kapi/kapi/memory/chunk.hpp | 109 +++++++++ kapi/kapi/memory/frame.hpp | 48 ++++ kapi/kapi/memory/frame_allocator.hpp | 66 ++++++ kapi/kapi/memory/layout.hpp | 54 +++++ kapi/kapi/memory/page.hpp | 38 ++++ kapi/kapi/memory/page_mapper.hpp | 90 ++++++++ kapi/kapi/system.hpp | 32 +++ 49 files changed, 1678 insertions(+), 1678 deletions(-) delete mode 100644 kapi/include/kapi/acpi.hpp delete mode 100644 kapi/include/kapi/boot.hpp delete mode 100644 kapi/include/kapi/boot_module/boot_module.hpp delete mode 100644 kapi/include/kapi/boot_module/boot_module_registry.hpp delete mode 100644 kapi/include/kapi/boot_modules.hpp delete mode 100644 kapi/include/kapi/cio.hpp delete mode 100644 kapi/include/kapi/cio/output_device.hpp delete mode 100644 kapi/include/kapi/cpu.hpp delete mode 100644 kapi/include/kapi/devices.hpp delete mode 100644 kapi/include/kapi/devices/bus.hpp delete mode 100644 kapi/include/kapi/devices/cpu.hpp delete mode 100644 kapi/include/kapi/devices/device.hpp delete mode 100644 kapi/include/kapi/devices/manager.hpp delete mode 100644 kapi/include/kapi/filesystem.hpp delete mode 100644 kapi/include/kapi/interrupts.hpp delete mode 100644 kapi/include/kapi/memory.hpp delete mode 100644 kapi/include/kapi/memory/address.hpp delete mode 100644 kapi/include/kapi/memory/chunk.hpp delete mode 100644 kapi/include/kapi/memory/frame.hpp delete mode 100644 kapi/include/kapi/memory/frame_allocator.hpp delete mode 100644 kapi/include/kapi/memory/layout.hpp delete mode 100644 kapi/include/kapi/memory/page.hpp delete mode 100644 kapi/include/kapi/memory/page_mapper.hpp delete mode 100644 kapi/include/kapi/system.hpp create mode 100644 kapi/kapi/acpi.hpp create mode 100644 kapi/kapi/boot.hpp create mode 100644 kapi/kapi/boot_module/boot_module.hpp create mode 100644 kapi/kapi/boot_module/boot_module_registry.hpp create mode 100644 kapi/kapi/boot_modules.hpp create mode 100644 kapi/kapi/cio.hpp create mode 100644 kapi/kapi/cio/output_device.hpp create mode 100644 kapi/kapi/cpu.hpp create mode 100644 kapi/kapi/devices.hpp create mode 100644 kapi/kapi/devices/bus.hpp create mode 100644 kapi/kapi/devices/cpu.hpp create mode 100644 kapi/kapi/devices/device.hpp create mode 100644 kapi/kapi/devices/manager.hpp create mode 100644 kapi/kapi/filesystem.hpp create mode 100644 kapi/kapi/interrupts.hpp create mode 100644 kapi/kapi/memory.hpp create mode 100644 kapi/kapi/memory/address.hpp create mode 100644 kapi/kapi/memory/chunk.hpp create mode 100644 kapi/kapi/memory/frame.hpp create mode 100644 kapi/kapi/memory/frame_allocator.hpp create mode 100644 kapi/kapi/memory/layout.hpp create mode 100644 kapi/kapi/memory/page.hpp create mode 100644 kapi/kapi/memory/page_mapper.hpp create mode 100644 kapi/kapi/system.hpp (limited to 'kapi') diff --git a/kapi/CMakeLists.txt b/kapi/CMakeLists.txt index d15b923..f74cfb3 100644 --- a/kapi/CMakeLists.txt +++ b/kapi/CMakeLists.txt @@ -15,7 +15,7 @@ target_sources("kapi" PUBLIC ) target_include_directories("kapi" INTERFACE - "include" + "${CMAKE_CURRENT_SOURCE_DIR}" ) target_link_libraries("kapi" INTERFACE diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp deleted file mode 100644 index 885fcde..0000000 --- a/kapi/include/kapi/acpi.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef TEACHOS_KAPI_ACPI_HPP -#define TEACHOS_KAPI_ACPI_HPP - -#include - -#include -#include - -#include - -namespace kapi::acpi -{ - - //! @addtogroup kapi-acpi-kernel-defined - //! @{ - - //! Initialize the ACPI subsystem and discover the available tables. - //! - //! @return true iff. a valid system description tabled was found, false otherwise. - auto init(::acpi::rsdp const & sdp) -> bool; - - //! 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<::acpi::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 - auto get_table() -> kstd::observer_ptr<::acpi::table_type_t const> - { - return kstd::make_observer(static_cast<::acpi::table_type_t const *>(get_table(Signature).get())); - } - -} // namespace kapi::acpi - -#endif diff --git a/kapi/include/kapi/boot.hpp b/kapi/include/kapi/boot.hpp deleted file mode 100644 index 55ca941..0000000 --- a/kapi/include/kapi/boot.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef TEACHOS_KAPI_BOOT_HPP -#define TEACHOS_KAPI_BOOT_HPP - -namespace kapi::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 kapi::boot - -#endif diff --git a/kapi/include/kapi/boot_module/boot_module.hpp b/kapi/include/kapi/boot_module/boot_module.hpp deleted file mode 100644 index 9b4b165..0000000 --- a/kapi/include/kapi/boot_module/boot_module.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_HPP -#define TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_HPP - -#include - -#include -#include - -namespace kapi::boot_modules -{ - // ! The boot module struct - // ! - // ! The boot module struct represents a module loaded by the bootloader, and contains information about it, such as - // ! its name, virtual start address, and size. - struct boot_module - { - std::string_view name{}; - memory::linear_address start_address{}; - std::size_t size{}; - }; -} // namespace kapi::boot_modules - -#endif \ No newline at end of file diff --git a/kapi/include/kapi/boot_module/boot_module_registry.hpp b/kapi/include/kapi/boot_module/boot_module_registry.hpp deleted file mode 100644 index fc3590f..0000000 --- a/kapi/include/kapi/boot_module/boot_module_registry.hpp +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_REGISTRY_HPP -#define TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_REGISTRY_HPP - -#include - -#include - -#include - -namespace kapi::boot_modules -{ - - // ! The interface of the boot module registry - // ! - // ! The boot module registry is responsible for keeping track of the modules loaded by the bootloader, and - // ! providing access to them for the rest of the kernel. - struct boot_module_registry - { - using range_type = kstd::vector; - using value_type = range_type::value_type; - using const_reference = range_type::const_reference; - - using const_iterator = range_type::const_iterator; - using const_reverse_iterator = range_type::const_reverse_iterator; - using size_type = range_type::size_type; - - [[nodiscard]] auto begin() const noexcept -> const_iterator - { - return m_modules.begin(); - } - - [[nodiscard]] auto end() const noexcept -> const_iterator - { - return m_modules.end(); - } - - [[nodiscard]] auto cbegin() const noexcept -> const_iterator - { - return begin(); - } - - [[nodiscard]] auto cend() const noexcept -> const_iterator - { - return end(); - } - - [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator - { - return m_modules.rbegin(); - } - - [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator - { - return m_modules.rend(); - } - - [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator - { - return rbegin(); - } - - [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator - { - return rend(); - } - - [[nodiscard]] auto front() const noexcept -> const_reference - { - return m_modules.front(); - } - - [[nodiscard]] auto back() const noexcept -> const_reference - { - return m_modules.back(); - } - - [[nodiscard]] auto size() const noexcept -> std::size_t - { - return m_modules.size(); - } - - [[nodiscard]] auto empty() const noexcept -> bool - { - return m_modules.empty(); - } - - [[nodiscard]] auto at(std::size_t index) const -> const_reference - { - return m_modules.at(index); - } - - [[nodiscard]] auto operator[](std::size_t index) const noexcept -> const_reference - { - return m_modules[index]; - } - - auto add_boot_module(boot_module module) -> void - { - m_modules.push_back(module); - } - - private: - range_type m_modules{}; - }; -} // namespace kapi::boot_modules - -#endif \ No newline at end of file diff --git a/kapi/include/kapi/boot_modules.hpp b/kapi/include/kapi/boot_modules.hpp deleted file mode 100644 index 026479d..0000000 --- a/kapi/include/kapi/boot_modules.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef TEACHOS_KAPI_BOOT_MODULES_HPP -#define TEACHOS_KAPI_BOOT_MODULES_HPP - -#include // IWYU pragma: export - -namespace kapi::boot_modules -{ - - //! @qualifier platform-defined - //! Initialize the boot module registry. - //! - //! @note This function must be implemented by the target platform. - //! - //! This function initializes the boot module registry, which is responsible for keeping track of the modules loaded - //! by the bootloader, and providing access to them for the rest of the kernel. - auto init() -> void; - - //! @qualifier kernel-defined - //! Set the boot module registry - //! - //! @param registry A new boot module registry. - auto set_boot_module_registry(boot_module_registry & registry) -> void; - - //! @qualifier kernel-defined - //! Get the boot module registry. - //! - //! @returns The boot module registry. - auto get_boot_module_registry() -> boot_module_registry &; - -} // namespace kapi::boot_modules -#endif \ No newline at end of file diff --git a/kapi/include/kapi/cio.hpp b/kapi/include/kapi/cio.hpp deleted file mode 100644 index 9bbf7fa..0000000 --- a/kapi/include/kapi/cio.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef TEACHOS_KAPI_CIO_HPP -#define TEACHOS_KAPI_CIO_HPP - -#include // IWYU pragma: export - -#include - -#include -#include - -namespace kapi::cio -{ - - //! @addtogroup kapi-cio - //! @{ - //! @} - - //! @addtogroup kapi-cio-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; - - //! Write a string to the given output stream. - //! - //! @param stream The output stream to write to. - //! @param text The text to write to the stream. - auto write(output_stream stream, std::string_view text) -> void; - - //! @} - - //! @addtogroup kapi-cio-platform-defined - //! @{ - - //! Initialize the character I/O subsystem. - //! - //! 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; - - //! @} - -} // namespace kapi::cio - -#endif diff --git a/kapi/include/kapi/cio/output_device.hpp b/kapi/include/kapi/cio/output_device.hpp deleted file mode 100644 index 9fe2557..0000000 --- a/kapi/include/kapi/cio/output_device.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef TEACHOS_KAPI_CIO_OUTPUT_DEVICE_HPP -#define TEACHOS_KAPI_CIO_OUTPUT_DEVICE_HPP - -// IWYU pragma: private, include - -#include - -namespace kapi::cio -{ - - enum struct output_stream - { - stdout, - stderr, - }; - - //! 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; - - //! Write the given text to the output device. - //! - //! @param stream The stream to write to. - //! @param text The text to write. - auto virtual write(output_stream stream, std::string_view text) -> void = 0; - - protected: - output_device() = default; - }; - -} // namespace kapi::cio - -#endif diff --git a/kapi/include/kapi/cpu.hpp b/kapi/include/kapi/cpu.hpp deleted file mode 100644 index deaf5cd..0000000 --- a/kapi/include/kapi/cpu.hpp +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef TEACHOS_KAPI_CPU_HPP -#define TEACHOS_KAPI_CPU_HPP - -#include - -#include -#include - -#include - -namespace kapi::cpu -{ - - //! @addtogroup kapi-cpu - //! @{ - - //! An exception originating from the CPU directly. - //! - //! Exception generally model interrupts that are synchronous to the instruction stream. This means that they do not - //! originate from external hardware, but rather are a product of program execution. - struct exception - { - //! The type of the exception, which identifies the reason for it being raised. - enum class type : std::uint8_t - { - //! The reason for the exception is unknown or platform-specific - unknown, - //! A page fault occurred - page_fault, - //! A memory access (either in the data or instruction stream) violated it's alignment constraints. - alignment_fault, - //! A memory access (either in the data or instruction stream) violated it's permissions. - memory_access_fault, - //! An invalid instruction was present in the instruction stream. - illegal_instruction, - //! The preconditions for the execution of an instruction were not met. - privilege_violation, - //! An arithmetic error occurred. - arithmetic_error, - //! A breakpoint was hit in the instruction stream. - breakpoint, - //! The CPU is single-stepping through the instruction stream. - single_step, - }; - - //! The type of this exception. - type type{}; - - //! The value of the instruction pointer at the time this exception was raised. - kapi::memory::linear_address instruction_pointer{}; - - //! The memory address that caused this exception. - kapi::memory::linear_address access_address{}; - - //! Whether the page was present at the time of the exception. - bool is_present{}; - - //! Whether the exception was caused by a write access. - bool is_write_access{}; - - //! Whether the exception was caused by a user mode access. - bool is_user_mode{}; - }; - - //! @} - - //! @addtogroup kapi-cpu-kernel-defined - //! @{ - - //! Dispatch an exception to the appropriate handler. - //! - //! @param context The exception context. - //! @return Whether the exception was handled. - [[nodiscard]] auto dispatch(exception const & context) -> bool; - - //! @} - - //! @addtogroup kapi-cpu-platform-defined - //! @{ - - //! Halt the CPU. - //! - //! This function terminates execution of the kernel. - [[noreturn]] auto halt() -> void; - - //! Perform early CPU initialization. - //! - //! When this function returns, the CPU is in a state where interrupt could be enabled. This function must not enable - //! interrupts itself. - auto init() -> void; - - //! Discover the CPU topology of the platform and attach it to the given CPU bus. - //! - //! @return true iff. the CPU topology was discovered successfully, false otherwise. - auto discover_topology() -> bool; - - //! @} - -} // namespace kapi::cpu - -template<> -struct kstd::formatter -{ - constexpr auto parse(kstd::format_parse_context & ctx) -> decltype(ctx.begin()) - { - return ctx.begin(); - } - - constexpr auto format(enum kapi::cpu::exception::type type, kstd::format_context & ctx) const -> void - { - switch (type) - { - case kapi::cpu::exception::type::unknown: - return ctx.push("unknown"); - case kapi::cpu::exception::type::page_fault: - return ctx.push("page fault"); - case kapi::cpu::exception::type::alignment_fault: - return ctx.push("alignment fault"); - case kapi::cpu::exception::type::memory_access_fault: - return ctx.push("memory access fault"); - case kapi::cpu::exception::type::illegal_instruction: - return ctx.push("illegal instruction"); - case kapi::cpu::exception::type::privilege_violation: - return ctx.push("privilege violation"); - case kapi::cpu::exception::type::arithmetic_error: - return ctx.push("arithmetic error"); - case kapi::cpu::exception::type::breakpoint: - return ctx.push("breakpoint"); - case kapi::cpu::exception::type::single_step: - return ctx.push("single step"); - } - } -}; - -#endif diff --git a/kapi/include/kapi/devices.hpp b/kapi/include/kapi/devices.hpp deleted file mode 100644 index b597aa8..0000000 --- a/kapi/include/kapi/devices.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef TEACHOS_KAPI_DEVICES_HPP -#define TEACHOS_KAPI_DEVICES_HPP - -#include // IWYU pragma: export -#include // IWYU pragma: export -#include // IWYU pragma: export -#include // IWYU pragma: export - -namespace kapi::devices -{ - - //! @addtogroup kapi-devices-kernel-defined - //! @{ - - //! Initialize the kernel's device management subsystem. - auto init() -> void; - - //! Get the virtual system root bus. - //! - //! @warning This function will panic if the root bus has not been initialized. - //! - //! @return a reference to the root bus. - auto get_root_bus() -> bus &; - - //! @} - - //! @addtogroup kapi-devices-platform-defined - //! @{ - - //! Initialize the platform's device tree. - auto init_platform_devices() -> void; - - //! @} - -} // namespace kapi::devices - -#endif \ No newline at end of file diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp deleted file mode 100644 index 59f49f7..0000000 --- a/kapi/include/kapi/devices/bus.hpp +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef TEACHOS_KAPI_DEVICES_BUS_HPP -#define TEACHOS_KAPI_DEVICES_BUS_HPP - -// IWYU pragma: private, include - -#include - -#include -#include -#include -#include - -#include -#include - -namespace kapi::devices -{ - - //! @addtogroup kapi-devices-kernel-defined - //! @{ - - //! A bus device that represents a logical/physical tree of devices and busses. - struct bus : device - { - //! Construct a bus with the given major number, minor number, and name. - //! - //! @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); - - //! 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; - - //! 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 child) -> void; - - [[nodiscard]] auto children() const -> kstd::vector> const &; - - protected: - //! Probe the bus hardware state. - //! - //! @return true iff. the bus hardware is healthy, false otherwise. - auto virtual probe() -> bool; - - private: - kstd::vector> m_devices; - kstd::vector> m_observers; - std::atomic_flag m_init_was_called{}; - std::atomic_flag m_initialized{}; - }; - - //! @} - -} // namespace kapi::devices - -#endif \ No newline at end of file diff --git a/kapi/include/kapi/devices/cpu.hpp b/kapi/include/kapi/devices/cpu.hpp deleted file mode 100644 index f8ff60c..0000000 --- a/kapi/include/kapi/devices/cpu.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef TEACHOS_KAPI_DEVICES_CPU_HPP -#define TEACHOS_KAPI_DEVICES_CPU_HPP - -#include - -#include -#include - -namespace kapi::devices -{ - - //! A virtual CPU bus to host all CPUs in the system. - struct cpu final : kapi::devices::bus - { - //! A virtual CPU Core to host all core local devices. - struct core final : kapi::devices::bus - { - explicit core(std::size_t major_number, std::size_t minor_number, std::uint64_t hardware_id, bool is_bsp); - - [[nodiscard]] auto hardware_id() const -> std::uint64_t; - [[nodiscard]] auto is_bsp() const -> bool; - - private: - std::uint64_t m_hardware_id; - bool m_is_bsp; - }; - - //! Create a new CPU with the given major and minor numbers. - //! - //! @param major The major number of this CPU - //! @param minor The minor number of this CPU, identifying the physical CPU - cpu(std::size_t major, std::size_t minor); - }; - -} // namespace kapi::devices - -#endif \ No newline at end of file diff --git a/kapi/include/kapi/devices/device.hpp b/kapi/include/kapi/devices/device.hpp deleted file mode 100644 index 70cf01f..0000000 --- a/kapi/include/kapi/devices/device.hpp +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef TEACH_OS_KAPI_DEVICES_DEVICE_HPP -#define TEACH_OS_KAPI_DEVICES_DEVICE_HPP - -// IWYU pragma: private, include - -#include -#include - -#include - -namespace kapi::devices -{ - - //! @addtogroup kapi-devices-kernel-defined - //! @{ - - /** - * @brief Base device identified by a major, minor number and name. - */ - struct device - { - /** - * @brief Create a device identifier from @p major, @p minor and @p name. - * @param major Device major number. - * @param minor Device minor number. - * @param name Device name. - */ - device(size_t major, size_t minor, kstd::string const & name); - - /** - * @brief Virtual destructor for device. - */ - virtual ~device() = default; - - /** - * @brief Initialize the device. - * @return true on success, false otherwise. - */ - virtual auto init() -> bool = 0; - - /** - * @brief Returns the major number of the device. - * @return Device major number. - */ - [[nodiscard]] auto major() const -> size_t; - - /** - * @brief Returns the minor number of the device. - * @return Device minor number. - */ - [[nodiscard]] auto minor() const -> size_t; - - /** - * @brief Returns the name of the device. - * @return Device 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; - - private: - friend struct bus; - - auto set_parent(kstd::observer_ptr parent) -> void; - - size_t m_major; - size_t m_minor; - kstd::string m_name; - kstd::observer_ptr m_parent; - }; - - //! @} - -} // namespace kapi::devices - -#endif \ No newline at end of file diff --git a/kapi/include/kapi/devices/manager.hpp b/kapi/include/kapi/devices/manager.hpp deleted file mode 100644 index c9b90b4..0000000 --- a/kapi/include/kapi/devices/manager.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef TEACHOS_KAPI_DEVICES_MANAGER_HPP -#define TEACHOS_KAPI_DEVICES_MANAGER_HPP - -// IWYU pragma: private, include - -#include - -#include - -#include -#include - -namespace kapi::devices -{ - - //! @addtogroup kapi-devices-kernel-defined - //! @{ - - //! Ask the kernel to allocate a new major number. - //! - //! @return a new, unused major number. - auto allocate_major_number() -> std::size_t; - - //! Register a new device with the kernel's device manager. - //! - //! @param device The device to register. - //! @return true if the device was registered successfully, false otherwise. - auto register_device(device & device) -> bool; - - //! Unregister a device from the kernel's device manager. - //! - //! @param device The device to unregister. - //! @return true if the device was unregistered successfully, false otherwise. - auto unregister_device(device & device) -> bool; - - //! Find a device by its major and minor numbers. - //! - //! @param major the major number of the device. - //! @param minor the minor number of the device. - //! @return a pointer to the device iff. the device was found, nullptr otherwise. - auto find_device(std::size_t major, std::size_t minor) -> kstd::observer_ptr; - - //! Find a device by its name. - //! - //! @param name the name of the device. - //! @return a pointer to the device iff. the device was found, nullptr otherwise. - auto find_device(std::string_view name) -> kstd::observer_ptr; - - //! @} - -} // namespace kapi::devices - -#endif \ No newline at end of file diff --git a/kapi/include/kapi/filesystem.hpp b/kapi/include/kapi/filesystem.hpp deleted file mode 100644 index 94d42ce..0000000 --- a/kapi/include/kapi/filesystem.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef TEACHOS_KAPI_FILESYSTEM_HPP -#define TEACHOS_KAPI_FILESYSTEM_HPP - -#include -#include - -#include - -namespace kapi::filesystem -{ - /** - @brief The kapi::filesystem namespace provides the interface for filesystem operations in the kernel. It includes - functions for mounting and unmounting filesystems, as well as basic file operations such as opening, closing, reading - from, and writing to files. The actual implementation of these functions is in the kernel's filesystem subsystem, - which will handle the specifics of different filesystem types and their interactions with the underlying storage - devices. - */ - - /** - @brief Mounts a filesystem from the specified @p source at the specified @p target path. - @param source The source device or filesystem to mount. - @param target The target mount point. - @return 0 on success, -1 on failure. - @qualifier kernel-defined - */ - auto mount(std::string_view source, std::string_view target) -> int; - - /** - @brief Unmounts a filesystem from the specified @p target path. - @param target The target mount point to unmount. - @return 0 on success, -1 on failure. - @qualifier kernel-defined - */ - auto umount(std::string_view target) -> int; - - /** - @brief Opens a file at the specified @p path. - @param path The path to the file to open. - @return A file descriptor on success, -1 on failure. - @qualifier kernel-defined - */ - auto open(std::string_view path) -> int; - - /** - @brief Closes a @p file_descriptor. - @param file_descriptor The file descriptor to close. - @return 0 on success, -1 on failure. - @qualifier kernel-defined - */ - auto close(int file_descriptor) -> int; - - /** - @brief Reads @p size bytes into @p buffer from a @p file_descriptor. - @param file_descriptor The file descriptor to read from. - @param buffer The buffer to store the read data. - @param size The number of bytes to read. - @return The number of bytes read on success, -1 on failure. - @qualifier kernel-defined - */ - auto read(int file_descriptor, void * buffer, size_t size) -> ssize_t; - - /** - @brief Writes @p size bytes from @p buffer to a @p file_descriptor. - @param file_descriptor The file descriptor to write to. - @param buffer The buffer containing the data to write. - @param size The number of bytes to write. - @return The number of bytes written on success, -1 on failure. - @qualifier kernel-defined - */ - auto write(int file_descriptor, void const * buffer, size_t size) -> ssize_t; -} // namespace kapi::filesystem - -#endif // TEACHOS_KAPI_FILESYSTEM_HPP \ No newline at end of file diff --git a/kapi/include/kapi/interrupts.hpp b/kapi/include/kapi/interrupts.hpp deleted file mode 100644 index 4ba0684..0000000 --- a/kapi/include/kapi/interrupts.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef TEACHOS_KAPI_INTERRUPTS_HPP -#define TEACHOS_KAPI_INTERRUPTS_HPP - -#include - -namespace kapi::interrupts -{ - - //! @addtogroup kapi-interrupts - //! @{ - - //! A status that indicates whether an interrupt was handled by a handler. - enum class status : bool - { - //! The interrupt was not handled by any handler. - unhandled, - //! The interrupt was handled by at least one handler. - handled, - }; - - //! The interface for all interrupt handlers. - struct handler - { - virtual ~handler() = default; - - //! Handle an interrupt with the given IRQ number. - // - //! This function will be called by the kernel in an interrupt context. As such, the function should complete its - //! task quickly and must take care when acquiring globally shared locks. - //! - //! @param irq_number The identifier of the interrupt request that triggered the handler. - //! @return status::handled if the handler successfully handled the interrupt, status::unhandled otherwise. - virtual auto handle_interrupt(std::uint32_t irq_number) -> status = 0; - }; - - //! @} - - //! @addtogroup kapi-interrupts-kernel-defined - //! @{ - - //! Register an interrupt handler for the given IRQ number. - //! - //! @param irq_number The IRQ number to register the handler for. - //! @param handler The interrupt handler to register. - auto register_handler(std::uint32_t irq_number, handler & handler) -> void; - - //! Unregister a previously registered interrupt handler. - //! - //! @param irq_number The IRQ number to unregister the handler for. - //! @param handler The interrupt handler to unregister. - auto unregister_handler(std::uint32_t irq_number, handler & handler) -> void; - - //! Dispatch an interrupt to all registered handlers. - //! - //! @param irq_number The IRQ number to dispatch. - //! @return status::handled if the interrupt was handled by at least one handler, status::unhandled otherwise. - auto dispatch(std::uint32_t irq_number) -> status; - - //! @} - - //! @addtogroup kapi-interrupts-platform-defined - //! @{ - - //! Enable external interrupts. - auto enable() -> void; - - //! Disable external interrupts. - auto disable() -> void; - - //! @} - -} // namespace kapi::interrupts - -#endif \ No newline at end of file diff --git a/kapi/include/kapi/memory.hpp b/kapi/include/kapi/memory.hpp deleted file mode 100644 index 8ad8d6e..0000000 --- a/kapi/include/kapi/memory.hpp +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef TEACHOS_KAPI_MEMORY_HPP -#define TEACHOS_KAPI_MEMORY_HPP - -#include // IWYU pragma: export -#include // IWYU pragma: export -#include // IWYU pragma: export -#include // IWYU pragma: export -#include // IWYU pragma: export -#include // IWYU pragma: export -#include // IWYU pragma: export - -#include -#include -#include - -namespace kapi::memory -{ - - using mmio_region = std::pair; - - //! @addtogroup kapi-memory-kernel-defined - //! @{ - - //! Initialize the physical memory manager. - //! - //! This function initializes the kernel-wide physical memory manager. The function will invoke the handoff handler to - //! transfer the platform-specific frame allocation state to the physical memory manager. - //! - //! @note Once this function returns, the global allocator has been replaced by the platform-agnostic, kernel-defined - //! allocator. Any state of the platform specific allocator may be released. - //! - //! @param frame_count The number of frames present in the system. - //! @param handoff_handler A function to be invoked to transfer the platform-specific frame allocation state. The - //! allocator to hand off to is passed to the handler. - auto init_pmm(std::size_t frame_count, void (&handoff_handler)(frame_allocator &)) -> void; - - //! Get the currently active frame allocator. - auto get_frame_allocator() -> frame_allocator &; - - //! Set the currently active frame allocator. - //! - //! @param allocator A new frame allocator. - //! @return The previously active frame allocator. - auto set_frame_allocator(frame_allocator & allocator) -> std::optional; - - //! Set the currently active page mapper. - //! - //! @param mapper A new page mapper. - //! @return The previously active page mapper. - auto set_page_mapper(page_mapper & mapper) -> std::optional; - - //! Allocate a new frame of physical memory - //! - //! @warning This function will panic if no frame allocator has been registered. - //! - //! @return An engaged std::optional iff. a frame could be allocated, std::nullopt otherwise. - auto allocate_frame() -> std::optional; - - //! Allocate multiple new frames of physical memory - //! - //! @warning This function will panic if no frame allocator has been registered. - //! - //! @return An engaged std::optional iff. @p count frames could be allocated, std::nullopt otherwise. - auto allocate_many_frames(std::size_t count) -> std::optional>; - - //! Map a page onto a frame. - //! - //! @warning This function will panic if no page mapper has been registered, or the page has already been mapped. - //! This function will not ensure that the frame is not already in use. - //! - //! @param page The page to map. - //! @param frame The frame to map the page into. - //! @param flags The flags to apply to this mapping. - //! @return A pointer to the first byte of the mapped page. - auto map(page page, frame frame, page_mapper::flags flags = page_mapper::flags::empty) -> std::byte *; - - //! Unmap a page. - //! - //! @warning This function will panic if no page mapper has been registered, or the page is not mapped. - //! - //! @param page The page to unmap - auto unmap(page page) -> void; - - //! Initialize the Memory-mapped I/O region system. - //! - //! @param base The base address for the MMIO region. - //! @param page_count The number of pages the MMIO region is spans. - auto init_mmio(linear_address base, std::size_t page_count) -> void; - - //! Allocate a Memory-mapped I/O region of the given size. - //! - //! @warning This function will panic if the MMIO system has not been initialized! - //! @param page_count The number of pages to allocate. - auto allocate_mmio_region(std::size_t page_count) -> mmio_region; - - //! Map a region of Memory-mapped I/O address space to a given hardware address using the given flags. - //! - //! @warning This function will panic if no page mapper has been registered, or the page has already been mapped. - //! This function will not ensure that the frame is not already in use. - //! - //! This function will always set the @p uncached flag. - //! - //! @param region The region to map. - //! @param hw_base The base of the hardware region. - //! @param flags The flags to apply. - auto map_mmio_region(mmio_region region, physical_address hw_base, page_mapper::flags flags = {}) -> std::byte *; - - //! Release a Memory-mapped I/O region. - //! - //! @warning This function will panic if the MMIO system has not been initialized! - //! @param region The region to release. - auto release_mmio_region(mmio_region region) -> void; - - //! @} - - //! @addtogroup kapi-memory-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 kapi::memory - -#endif diff --git a/kapi/include/kapi/memory/address.hpp b/kapi/include/kapi/memory/address.hpp deleted file mode 100644 index 9231cfc..0000000 --- a/kapi/include/kapi/memory/address.hpp +++ /dev/null @@ -1,252 +0,0 @@ -#ifndef TEACHOS_KAPI_MEMORY_ADDRESS_HPP -#define TEACHOS_KAPI_MEMORY_ADDRESS_HPP - -// IWYU pragma: private, include - -#include -#include - -#include -#include -#include -#include -#include - -namespace kapi::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 - struct address - { - //! Construct a null-address. - constexpr 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(pointer)} - {} - - //! Convert this address into a C++ pointer. - //! - //! @tparam T The type of the object this address should refer to. - //! @return This address as a typed pointer to the given type. - template - explicit operator ObjectType *() const noexcept - { - return std::bit_cast(m_value); - } - - //! Create a new address n beyond this one. - //! - //! @param n The amount to add to this address. - //! @return A new address, n further than this one. - [[nodiscard]] constexpr auto operator+(std::ptrdiff_t n) const noexcept -> address - { - return address{m_value + n}; - } - - //! Increment this address by a given amount. - //! - //! @param n The amount to Increment the address by. - //! @return A reference to this address. - constexpr auto operator+=(std::ptrdiff_t n) noexcept -> address & - { - m_value += n; - return *this; - } - - //! Increment this address by one. - //! - //! @return A reference to this address. - constexpr auto operator++() noexcept -> address & - { - return (*this += 1); - } - - //! Increment this address by one. - //! - //! @return A copy of this address before the increment. - constexpr auto operator++(int) noexcept -> address - { - auto copy = *this; - ++*this; - return copy; - } - - //! Create a new address n bytes before this one - //! - //! @param n The amount to subtract from this address - //! @return A nre address, @p n ahead of this one - [[nodiscard]] constexpr auto operator-(std::ptrdiff_t n) noexcept -> address - { - return address{m_value - n}; - } - - //! Decrement this address by a given amount. - //! - //! @param n The amount to Decrement the address by. - //! @return A reference to this address. - constexpr auto operator-=(std::ptrdiff_t n) noexcept -> address & - { - m_value -= n; - return *this; - } - - //! Decrement this address by one. - //! - //! @return A reference to this address. - constexpr auto operator--() noexcept -> address & - { - return (*this -= 1); - } - - //! Decrement this address by one. - //! - //! @return A copy of this address before the decrement. - constexpr auto operator--(int) noexcept -> address - { - auto copy = *this; - --*this; - return copy; - } - - //! Calculate the distance between this address and another one - //! - //! @param other The address to calculate the distance to. - //! @return The distance between this address and the given one. - [[nodiscard]] constexpr auto operator-(address const & other) noexcept -> std::ptrdiff_t - { - return m_value - other.m_value; - } - - //! Extract the lower bits of the address - //! - //! @note The only meaningful values for @p n are powers of two. - //! - //! @param n The divisor to use for extraction. - //! @return The lower bits of the address as defined by the divisor. - constexpr auto operator%(std::size_t n) const noexcept -> std::uintptr_t - { - return m_value % n; - } - - //! Extract the upper bits of the address - //! - //! @note The only meaningful values for @p n are powers of two. - //! - //! @param n The divisor to use for extraction. - //! @return The upper bits of the address as defined by the divisor. - constexpr auto operator/(std::size_t n) const noexcept -> std::uintptr_t - { - return m_value / n; - } - - //! 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 - constexpr auto operator&(MaskType mask) const noexcept -> MaskType - { - return static_cast(m_value & mask); - } - - constexpr auto operator+(kstd::units::bytes n) const noexcept -> address - { - return address{m_value + n.value}; - } - - constexpr auto operator+=(kstd::units::bytes n) noexcept -> address & - { - return *this = *this + n; - } - - //! 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; - - //! A physical address. - using physical_address = address; - -} // namespace kapi::memory - -namespace kstd -{ - - template - struct formatter> : kstd::formatter - { - constexpr auto static suffix = Type == kapi::memory::address_type::linear ? "%lin" : "%phy"; - - constexpr auto parse(format_parse_context & context) -> format_parse_context::iterator - { - auto result = formatter::parse(context); - if (!this->specifiers.type) - { - this->specifiers.type = 'p'; - this->specifiers.alternative_form = true; - } - return result; - } - - auto format(kapi::memory::address const & address, format_context & context) const -> void - { - formatter::format(address.raw(), context); - context.push(suffix); - } - }; - -} // namespace kstd - -#endif \ No newline at end of file diff --git a/kapi/include/kapi/memory/chunk.hpp b/kapi/include/kapi/memory/chunk.hpp deleted file mode 100644 index 485a890..0000000 --- a/kapi/include/kapi/memory/chunk.hpp +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef TEACHOS_KAPI_MEMORY_CHUNK_HPP -#define TEACHOS_KAPI_MEMORY_CHUNK_HPP - -// IWYU pragma: private, include - -#include - -#include -#include - -namespace kapi::memory -{ - - //! @qualifier kernel-defined - //! A fixed-size unit of memory, indexed by a number. - //! - //! @tparam ChunkType The CRTP type of the deriving class - //! @tparam AddressType The type of addresses used to index this chunk - //! @tparam Size The size of this chunk. - template - struct chunk - { - //! The type of addresses used to index this chunk - using address_type = AddressType; - - //! The size of this chunk - constexpr auto static size = Size; - - //! Construct a new chunk handle for the chunk containing the given address. - //! - //! @param address An address contained by the desired chunk. - //! @return A handle to a chunk containing the given address. - constexpr auto static containing(address_type address) noexcept -> ChunkType - { - return ChunkType{address / size.value}; - } - - //! Get the start address of the chunk referenced by this handle. - //! - //! @return The address of the first byte contained by the chunk referenced by this handle. - [[nodiscard]] constexpr auto start_address() const noexcept -> address_type - { - return address_type{(m_number * size).value}; - } - - //! Get the number of the chunk referenced by this handle. - //! - //! @return The zero-based number of the chunk referenced by this handle. - [[nodiscard]] constexpr auto number() const noexcept -> std::size_t - { - return m_number; - } - - //! Get a handle n chunks after the one referenced by this handle. - //! - //! @param n The positive offset to this chunk. - //! @return A handle referencing the chunk n chunks after the one referenced by this handle. - constexpr auto operator+(std::size_t n) const noexcept -> ChunkType - { - return ChunkType{m_number + n}; - } - - //! Let this handle reference the next chunk after the currently reference one. - //! - //! @return A handle referencing the same chunk as this handle did before the operation. - constexpr auto operator++(int) noexcept -> ChunkType - { - auto copy = static_cast(*this); - ++*this; - return copy; - } - - //! Let this handle reference the next chunk after the currently reference one. - //! - //! @return A reference to this handle. - constexpr auto operator++() noexcept -> ChunkType & - { - ++m_number; - return static_cast(*this); - } - - //! Check if this chunk handle reference the same chunk as another one. - //! - //! @param other Another chunk handle. - constexpr auto operator==(chunk const & other) const noexcept -> bool = default; - - //! Compare the number of the chunk referenced by this handle to the one reference by another one. - //! - //! @param other Another chunk handle. - constexpr auto operator<=>(chunk const & other) const noexcept -> std::strong_ordering = default; - - private: - friend ChunkType; - - //! Construct a handle referencing the first chunk of the respective address space. - constexpr chunk() noexcept = default; - - //! Construct a handle referencing the chunk of memory with the given number. - explicit constexpr chunk(std::size_t number) noexcept - : m_number{number} - {} - - //! The number of the currently referenced chunk. - std::size_t m_number{}; - }; - -} // namespace kapi::memory - -#endif \ No newline at end of file diff --git a/kapi/include/kapi/memory/frame.hpp b/kapi/include/kapi/memory/frame.hpp deleted file mode 100644 index e423fa4..0000000 --- a/kapi/include/kapi/memory/frame.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef TEACHOS_KAPI_MEMORY_FRAME_HPP -#define TEACHOS_KAPI_MEMORY_FRAME_HPP - -// IWYU pragma: private, include - -#include -#include -#include - -#include - -namespace kapi::memory -{ - - //! @qualifier kernel-defined - //! A handle to a frame of physical memory. - //! - //! @note Contrary to the address types, this type is modeled using inheritance to support future extensions. - struct frame : chunk - { - frame() = default; - - frame(std::size_t number) - : chunk{number} - {} - - using difference_type = std::ptrdiff_t; - - //! @copydoc chunk::containing - //! - //! @note This factory shadows the base factory to aid in type deduction. - constexpr auto static containing(physical_address address) noexcept -> frame - { - return frame{chunk::containing(address)}; - } - - //! Convert a base chunk into a page. - //! - //! This constructor allows for conversion from chunk to a frame for - //! convenience. It is deliberately not explicit. - constexpr frame(chunk other) - : chunk{other} - {} - }; - -} // namespace kapi::memory - -#endif \ No newline at end of file diff --git a/kapi/include/kapi/memory/frame_allocator.hpp b/kapi/include/kapi/memory/frame_allocator.hpp deleted file mode 100644 index 784ea93..0000000 --- a/kapi/include/kapi/memory/frame_allocator.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef TEACHOS_KAPI_MEMORY_FRAME_ALLOCATOR_HPP -#define TEACHOS_KAPI_MEMORY_FRAME_ALLOCATOR_HPP - -// IWYU pragma: private, include - -#include - -#include -#include -#include - -namespace kapi::memory -{ - - //! The interface of all frame allocators. - //! - //! A frame allocator is responsible for the allocation, and deallocation, of frames of physical memory. Frames - //! obtained from an allocator shall only be deallocated, or released, via the same allocator. When a frame allocated - //! from one allocator is release via a different one (instance or type), the behavior is undefined. - struct frame_allocator - { - frame_allocator(frame_allocator const &) = delete; - frame_allocator(frame_allocator &&) = delete; - auto operator=(frame_allocator const &) -> frame_allocator & = delete; - auto operator=(frame_allocator &&) -> frame_allocator & = delete; - - virtual ~frame_allocator() = default; - - //! Allocate a frame of physical memory. - //! - //! @return An engaged std::optional iff. a new frame could be allocated, std::nullopt otherwise. - virtual auto allocate() noexcept -> std::optional - { - return allocate_many(1).transform([](auto result) { return result.first; }); - } - - //! Mark the given frame as used - virtual auto mark_used(frame frame) -> void = 0; - - //! Allocate multiple consecutive frames of physical memory. - //! - //! @param count The number of frames to allocate - //! @return an engaged optional iff. a block of consecutive frames could be allocated, std::nullopt otherwise. - virtual auto allocate_many(std::size_t count) noexcept -> std::optional> = 0; - - //! Release a frame of physical memory. - //! - //! @param frame A frame of physical memory, previously acquired by a call to the #allocate function. - virtual auto release(frame frame) -> void - { - return release_many({frame, 1}); - } - - //! Release a frame of physical memory. - //! - //! @param frame_set A set of frames of physical memory, previously acquired by a call to the #allocate_many - //! function. - virtual auto release_many(std::pair frame_set) -> void = 0; - - protected: - frame_allocator() = default; - }; - -} // namespace kapi::memory - -#endif // TEACHOS_KAPI_MEMORY_FRAME_ALLOCATOR_HPP \ No newline at end of file diff --git a/kapi/include/kapi/memory/layout.hpp b/kapi/include/kapi/memory/layout.hpp deleted file mode 100644 index 733fa96..0000000 --- a/kapi/include/kapi/memory/layout.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef TEACHOS_KAPI_MEMORY_LAYOUT_HPP -#define TEACHOS_KAPI_MEMORY_LAYOUT_HPP - -// IWYU pragma: private, include - -#include - -#include - -namespace kapi::memory -{ - - //! The size of a single page of virtual memory. - //! - //! Platforms that use different sizes of pages are expected to emulate 4 KiB pages towards the kernel. - constexpr auto page_size = kstd::units::KiB(4); - - //! The size of a single frame of physical memory. - //! - //! Platforms that use different sizes of frames are expected to emulate 4 KiB pages towards the kernel. - constexpr auto frame_size = kstd::units::KiB(4); - - //! The linear base address of the higher-half direct map. - //! - //! Platforms are expected to provide a mapping of at least the first 512 GiB of available memory at this address. - constexpr auto higher_half_direct_map_base = linear_address{0xffff'8000'0000'0000uz}; - - //! The linear base address of the kernel heap. - constexpr auto heap_base = linear_address{0xffff'c000'0000'0000uz}; - - //! The linear base address of the memory region reserved for the metadata required by the PMM. - constexpr auto pmm_metadata_base = linear_address{0xffff'd000'0000'0000uz}; - - //! The linear base address of all Memory Mapped I/O mappings. - constexpr auto mmio_base = linear_address{0xffff'e000'0000'0000uz}; - - //! 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/memory/page.hpp b/kapi/include/kapi/memory/page.hpp deleted file mode 100644 index d987534..0000000 --- a/kapi/include/kapi/memory/page.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef TEACHOS_KAPI_MEMORY_PAGE_HPP -#define TEACHOS_KAPI_MEMORY_PAGE_HPP - -// IWYU pragma: private, include - -#include -#include -#include - -#include - -namespace kapi::memory -{ - - //! @qualifier kernel-defined - //! A handle to a page of virtual memory. - //! - //! @note Contrary to the address types, this type is modeled using inheritance to support future extensions. - struct page : chunk - { - page() = default; - - page(std::size_t number) - : chunk{number} - {} - - //! Convert a base chunk into a page. - //! - //! This constructor allows for conversion from chunk to a page for convenience. - //! It is deliberately not explicit. - constexpr page(chunk other) - : chunk{other} - {} - }; - -} // namespace kapi::memory - -#endif \ No newline at end of file diff --git a/kapi/include/kapi/memory/page_mapper.hpp b/kapi/include/kapi/memory/page_mapper.hpp deleted file mode 100644 index fb600b2..0000000 --- a/kapi/include/kapi/memory/page_mapper.hpp +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef TEACHOS_KAPI_MEMORY_PAGE_MAPPER_HPP -#define TEACHOS_KAPI_MEMORY_PAGE_MAPPER_HPP - -// IWYU pragma: private, include - -#include -#include - -#include - -#include -#include -#include - -namespace kapi::memory -{ - - //! @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, //! 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. - global = 1 << 4, //! The page translation persists across context switches. - }; - - 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. - virtual auto map(page page, frame frame, flags flags) -> std::byte * = 0; - - //! 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) 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 - [[nodiscard]] auto map_as(page page, frame frame, flags flags) -> T * - { - return std::bit_cast(map(page, frame, flags)); - } - - protected: - page_mapper() = default; - }; - -} // namespace kapi::memory - -namespace kstd::ext -{ - template<> - struct is_bitfield_enum : std::true_type - { - }; -} // namespace kstd::ext - -#endif \ No newline at end of file diff --git a/kapi/include/kapi/system.hpp b/kapi/include/kapi/system.hpp deleted file mode 100644 index 8a20af9..0000000 --- a/kapi/include/kapi/system.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef TEACHOS_KAPI_SYSTEM_HPP -#define TEACHOS_KAPI_SYSTEM_HPP - -#include -#include - -namespace kapi::system -{ - - //! @addtogroup kapi-system-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; - - //! @} // end group kernel-defined - - //! @addtogroup kapi-system-platform-defined - //! @{ - - //! A hook that runs once the memory subsystem has been initialized. - auto memory_initialized() -> void; - - //! @} // end group platform-defined - -} // namespace kapi::system - -#endif diff --git a/kapi/kapi/acpi.hpp b/kapi/kapi/acpi.hpp new file mode 100644 index 0000000..885fcde --- /dev/null +++ b/kapi/kapi/acpi.hpp @@ -0,0 +1,40 @@ +#ifndef TEACHOS_KAPI_ACPI_HPP +#define TEACHOS_KAPI_ACPI_HPP + +#include + +#include +#include + +#include + +namespace kapi::acpi +{ + + //! @addtogroup kapi-acpi-kernel-defined + //! @{ + + //! Initialize the ACPI subsystem and discover the available tables. + //! + //! @return true iff. a valid system description tabled was found, false otherwise. + auto init(::acpi::rsdp const & sdp) -> bool; + + //! 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<::acpi::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 + auto get_table() -> kstd::observer_ptr<::acpi::table_type_t const> + { + return kstd::make_observer(static_cast<::acpi::table_type_t const *>(get_table(Signature).get())); + } + +} // namespace kapi::acpi + +#endif diff --git a/kapi/kapi/boot.hpp b/kapi/kapi/boot.hpp new file mode 100644 index 0000000..55ca941 --- /dev/null +++ b/kapi/kapi/boot.hpp @@ -0,0 +1,17 @@ +#ifndef TEACHOS_KAPI_BOOT_HPP +#define TEACHOS_KAPI_BOOT_HPP + +namespace kapi::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 kapi::boot + +#endif diff --git a/kapi/kapi/boot_module/boot_module.hpp b/kapi/kapi/boot_module/boot_module.hpp new file mode 100644 index 0000000..9b4b165 --- /dev/null +++ b/kapi/kapi/boot_module/boot_module.hpp @@ -0,0 +1,23 @@ +#ifndef TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_HPP +#define TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_HPP + +#include + +#include +#include + +namespace kapi::boot_modules +{ + // ! The boot module struct + // ! + // ! The boot module struct represents a module loaded by the bootloader, and contains information about it, such as + // ! its name, virtual start address, and size. + struct boot_module + { + std::string_view name{}; + memory::linear_address start_address{}; + std::size_t size{}; + }; +} // namespace kapi::boot_modules + +#endif \ No newline at end of file diff --git a/kapi/kapi/boot_module/boot_module_registry.hpp b/kapi/kapi/boot_module/boot_module_registry.hpp new file mode 100644 index 0000000..fc3590f --- /dev/null +++ b/kapi/kapi/boot_module/boot_module_registry.hpp @@ -0,0 +1,107 @@ +#ifndef TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_REGISTRY_HPP +#define TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_REGISTRY_HPP + +#include + +#include + +#include + +namespace kapi::boot_modules +{ + + // ! The interface of the boot module registry + // ! + // ! The boot module registry is responsible for keeping track of the modules loaded by the bootloader, and + // ! providing access to them for the rest of the kernel. + struct boot_module_registry + { + using range_type = kstd::vector; + using value_type = range_type::value_type; + using const_reference = range_type::const_reference; + + using const_iterator = range_type::const_iterator; + using const_reverse_iterator = range_type::const_reverse_iterator; + using size_type = range_type::size_type; + + [[nodiscard]] auto begin() const noexcept -> const_iterator + { + return m_modules.begin(); + } + + [[nodiscard]] auto end() const noexcept -> const_iterator + { + return m_modules.end(); + } + + [[nodiscard]] auto cbegin() const noexcept -> const_iterator + { + return begin(); + } + + [[nodiscard]] auto cend() const noexcept -> const_iterator + { + return end(); + } + + [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator + { + return m_modules.rbegin(); + } + + [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator + { + return m_modules.rend(); + } + + [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator + { + return rbegin(); + } + + [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator + { + return rend(); + } + + [[nodiscard]] auto front() const noexcept -> const_reference + { + return m_modules.front(); + } + + [[nodiscard]] auto back() const noexcept -> const_reference + { + return m_modules.back(); + } + + [[nodiscard]] auto size() const noexcept -> std::size_t + { + return m_modules.size(); + } + + [[nodiscard]] auto empty() const noexcept -> bool + { + return m_modules.empty(); + } + + [[nodiscard]] auto at(std::size_t index) const -> const_reference + { + return m_modules.at(index); + } + + [[nodiscard]] auto operator[](std::size_t index) const noexcept -> const_reference + { + return m_modules[index]; + } + + auto add_boot_module(boot_module module) -> void + { + m_modules.push_back(module); + } + + private: + range_type m_modules{}; + }; +} // namespace kapi::boot_modules + +#endif \ No newline at end of file diff --git a/kapi/kapi/boot_modules.hpp b/kapi/kapi/boot_modules.hpp new file mode 100644 index 0000000..026479d --- /dev/null +++ b/kapi/kapi/boot_modules.hpp @@ -0,0 +1,31 @@ +#ifndef TEACHOS_KAPI_BOOT_MODULES_HPP +#define TEACHOS_KAPI_BOOT_MODULES_HPP + +#include // IWYU pragma: export + +namespace kapi::boot_modules +{ + + //! @qualifier platform-defined + //! Initialize the boot module registry. + //! + //! @note This function must be implemented by the target platform. + //! + //! This function initializes the boot module registry, which is responsible for keeping track of the modules loaded + //! by the bootloader, and providing access to them for the rest of the kernel. + auto init() -> void; + + //! @qualifier kernel-defined + //! Set the boot module registry + //! + //! @param registry A new boot module registry. + auto set_boot_module_registry(boot_module_registry & registry) -> void; + + //! @qualifier kernel-defined + //! Get the boot module registry. + //! + //! @returns The boot module registry. + auto get_boot_module_registry() -> boot_module_registry &; + +} // namespace kapi::boot_modules +#endif \ No newline at end of file diff --git a/kapi/kapi/cio.hpp b/kapi/kapi/cio.hpp new file mode 100644 index 0000000..9bbf7fa --- /dev/null +++ b/kapi/kapi/cio.hpp @@ -0,0 +1,48 @@ +#ifndef TEACHOS_KAPI_CIO_HPP +#define TEACHOS_KAPI_CIO_HPP + +#include // IWYU pragma: export + +#include + +#include +#include + +namespace kapi::cio +{ + + //! @addtogroup kapi-cio + //! @{ + //! @} + + //! @addtogroup kapi-cio-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; + + //! Write a string to the given output stream. + //! + //! @param stream The output stream to write to. + //! @param text The text to write to the stream. + auto write(output_stream stream, std::string_view text) -> void; + + //! @} + + //! @addtogroup kapi-cio-platform-defined + //! @{ + + //! Initialize the character I/O subsystem. + //! + //! 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; + + //! @} + +} // namespace kapi::cio + +#endif diff --git a/kapi/kapi/cio/output_device.hpp b/kapi/kapi/cio/output_device.hpp new file mode 100644 index 0000000..9fe2557 --- /dev/null +++ b/kapi/kapi/cio/output_device.hpp @@ -0,0 +1,39 @@ +#ifndef TEACHOS_KAPI_CIO_OUTPUT_DEVICE_HPP +#define TEACHOS_KAPI_CIO_OUTPUT_DEVICE_HPP + +// IWYU pragma: private, include + +#include + +namespace kapi::cio +{ + + enum struct output_stream + { + stdout, + stderr, + }; + + //! 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; + + //! Write the given text to the output device. + //! + //! @param stream The stream to write to. + //! @param text The text to write. + auto virtual write(output_stream stream, std::string_view text) -> void = 0; + + protected: + output_device() = default; + }; + +} // namespace kapi::cio + +#endif diff --git a/kapi/kapi/cpu.hpp b/kapi/kapi/cpu.hpp new file mode 100644 index 0000000..deaf5cd --- /dev/null +++ b/kapi/kapi/cpu.hpp @@ -0,0 +1,135 @@ +#ifndef TEACHOS_KAPI_CPU_HPP +#define TEACHOS_KAPI_CPU_HPP + +#include + +#include +#include + +#include + +namespace kapi::cpu +{ + + //! @addtogroup kapi-cpu + //! @{ + + //! An exception originating from the CPU directly. + //! + //! Exception generally model interrupts that are synchronous to the instruction stream. This means that they do not + //! originate from external hardware, but rather are a product of program execution. + struct exception + { + //! The type of the exception, which identifies the reason for it being raised. + enum class type : std::uint8_t + { + //! The reason for the exception is unknown or platform-specific + unknown, + //! A page fault occurred + page_fault, + //! A memory access (either in the data or instruction stream) violated it's alignment constraints. + alignment_fault, + //! A memory access (either in the data or instruction stream) violated it's permissions. + memory_access_fault, + //! An invalid instruction was present in the instruction stream. + illegal_instruction, + //! The preconditions for the execution of an instruction were not met. + privilege_violation, + //! An arithmetic error occurred. + arithmetic_error, + //! A breakpoint was hit in the instruction stream. + breakpoint, + //! The CPU is single-stepping through the instruction stream. + single_step, + }; + + //! The type of this exception. + type type{}; + + //! The value of the instruction pointer at the time this exception was raised. + kapi::memory::linear_address instruction_pointer{}; + + //! The memory address that caused this exception. + kapi::memory::linear_address access_address{}; + + //! Whether the page was present at the time of the exception. + bool is_present{}; + + //! Whether the exception was caused by a write access. + bool is_write_access{}; + + //! Whether the exception was caused by a user mode access. + bool is_user_mode{}; + }; + + //! @} + + //! @addtogroup kapi-cpu-kernel-defined + //! @{ + + //! Dispatch an exception to the appropriate handler. + //! + //! @param context The exception context. + //! @return Whether the exception was handled. + [[nodiscard]] auto dispatch(exception const & context) -> bool; + + //! @} + + //! @addtogroup kapi-cpu-platform-defined + //! @{ + + //! Halt the CPU. + //! + //! This function terminates execution of the kernel. + [[noreturn]] auto halt() -> void; + + //! Perform early CPU initialization. + //! + //! When this function returns, the CPU is in a state where interrupt could be enabled. This function must not enable + //! interrupts itself. + auto init() -> void; + + //! Discover the CPU topology of the platform and attach it to the given CPU bus. + //! + //! @return true iff. the CPU topology was discovered successfully, false otherwise. + auto discover_topology() -> bool; + + //! @} + +} // namespace kapi::cpu + +template<> +struct kstd::formatter +{ + constexpr auto parse(kstd::format_parse_context & ctx) -> decltype(ctx.begin()) + { + return ctx.begin(); + } + + constexpr auto format(enum kapi::cpu::exception::type type, kstd::format_context & ctx) const -> void + { + switch (type) + { + case kapi::cpu::exception::type::unknown: + return ctx.push("unknown"); + case kapi::cpu::exception::type::page_fault: + return ctx.push("page fault"); + case kapi::cpu::exception::type::alignment_fault: + return ctx.push("alignment fault"); + case kapi::cpu::exception::type::memory_access_fault: + return ctx.push("memory access fault"); + case kapi::cpu::exception::type::illegal_instruction: + return ctx.push("illegal instruction"); + case kapi::cpu::exception::type::privilege_violation: + return ctx.push("privilege violation"); + case kapi::cpu::exception::type::arithmetic_error: + return ctx.push("arithmetic error"); + case kapi::cpu::exception::type::breakpoint: + return ctx.push("breakpoint"); + case kapi::cpu::exception::type::single_step: + return ctx.push("single step"); + } + } +}; + +#endif diff --git a/kapi/kapi/devices.hpp b/kapi/kapi/devices.hpp new file mode 100644 index 0000000..b597aa8 --- /dev/null +++ b/kapi/kapi/devices.hpp @@ -0,0 +1,37 @@ +#ifndef TEACHOS_KAPI_DEVICES_HPP +#define TEACHOS_KAPI_DEVICES_HPP + +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export + +namespace kapi::devices +{ + + //! @addtogroup kapi-devices-kernel-defined + //! @{ + + //! Initialize the kernel's device management subsystem. + auto init() -> void; + + //! Get the virtual system root bus. + //! + //! @warning This function will panic if the root bus has not been initialized. + //! + //! @return a reference to the root bus. + auto get_root_bus() -> bus &; + + //! @} + + //! @addtogroup kapi-devices-platform-defined + //! @{ + + //! Initialize the platform's device tree. + auto init_platform_devices() -> void; + + //! @} + +} // namespace kapi::devices + +#endif \ No newline at end of file diff --git a/kapi/kapi/devices/bus.hpp b/kapi/kapi/devices/bus.hpp new file mode 100644 index 0000000..59f49f7 --- /dev/null +++ b/kapi/kapi/devices/bus.hpp @@ -0,0 +1,63 @@ +#ifndef TEACHOS_KAPI_DEVICES_BUS_HPP +#define TEACHOS_KAPI_DEVICES_BUS_HPP + +// IWYU pragma: private, include + +#include + +#include +#include +#include +#include + +#include +#include + +namespace kapi::devices +{ + + //! @addtogroup kapi-devices-kernel-defined + //! @{ + + //! A bus device that represents a logical/physical tree of devices and busses. + struct bus : device + { + //! Construct a bus with the given major number, minor number, and name. + //! + //! @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); + + //! 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; + + //! 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 child) -> void; + + [[nodiscard]] auto children() const -> kstd::vector> const &; + + protected: + //! Probe the bus hardware state. + //! + //! @return true iff. the bus hardware is healthy, false otherwise. + auto virtual probe() -> bool; + + private: + kstd::vector> m_devices; + kstd::vector> m_observers; + std::atomic_flag m_init_was_called{}; + std::atomic_flag m_initialized{}; + }; + + //! @} + +} // namespace kapi::devices + +#endif \ No newline at end of file diff --git a/kapi/kapi/devices/cpu.hpp b/kapi/kapi/devices/cpu.hpp new file mode 100644 index 0000000..f8ff60c --- /dev/null +++ b/kapi/kapi/devices/cpu.hpp @@ -0,0 +1,37 @@ +#ifndef TEACHOS_KAPI_DEVICES_CPU_HPP +#define TEACHOS_KAPI_DEVICES_CPU_HPP + +#include + +#include +#include + +namespace kapi::devices +{ + + //! A virtual CPU bus to host all CPUs in the system. + struct cpu final : kapi::devices::bus + { + //! A virtual CPU Core to host all core local devices. + struct core final : kapi::devices::bus + { + explicit core(std::size_t major_number, std::size_t minor_number, std::uint64_t hardware_id, bool is_bsp); + + [[nodiscard]] auto hardware_id() const -> std::uint64_t; + [[nodiscard]] auto is_bsp() const -> bool; + + private: + std::uint64_t m_hardware_id; + bool m_is_bsp; + }; + + //! Create a new CPU with the given major and minor numbers. + //! + //! @param major The major number of this CPU + //! @param minor The minor number of this CPU, identifying the physical CPU + cpu(std::size_t major, std::size_t minor); + }; + +} // namespace kapi::devices + +#endif \ No newline at end of file diff --git a/kapi/kapi/devices/device.hpp b/kapi/kapi/devices/device.hpp new file mode 100644 index 0000000..70cf01f --- /dev/null +++ b/kapi/kapi/devices/device.hpp @@ -0,0 +1,80 @@ +#ifndef TEACH_OS_KAPI_DEVICES_DEVICE_HPP +#define TEACH_OS_KAPI_DEVICES_DEVICE_HPP + +// IWYU pragma: private, include + +#include +#include + +#include + +namespace kapi::devices +{ + + //! @addtogroup kapi-devices-kernel-defined + //! @{ + + /** + * @brief Base device identified by a major, minor number and name. + */ + struct device + { + /** + * @brief Create a device identifier from @p major, @p minor and @p name. + * @param major Device major number. + * @param minor Device minor number. + * @param name Device name. + */ + device(size_t major, size_t minor, kstd::string const & name); + + /** + * @brief Virtual destructor for device. + */ + virtual ~device() = default; + + /** + * @brief Initialize the device. + * @return true on success, false otherwise. + */ + virtual auto init() -> bool = 0; + + /** + * @brief Returns the major number of the device. + * @return Device major number. + */ + [[nodiscard]] auto major() const -> size_t; + + /** + * @brief Returns the minor number of the device. + * @return Device minor number. + */ + [[nodiscard]] auto minor() const -> size_t; + + /** + * @brief Returns the name of the device. + * @return Device 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; + + private: + friend struct bus; + + auto set_parent(kstd::observer_ptr parent) -> void; + + size_t m_major; + size_t m_minor; + kstd::string m_name; + kstd::observer_ptr m_parent; + }; + + //! @} + +} // namespace kapi::devices + +#endif \ No newline at end of file diff --git a/kapi/kapi/devices/manager.hpp b/kapi/kapi/devices/manager.hpp new file mode 100644 index 0000000..c9b90b4 --- /dev/null +++ b/kapi/kapi/devices/manager.hpp @@ -0,0 +1,53 @@ +#ifndef TEACHOS_KAPI_DEVICES_MANAGER_HPP +#define TEACHOS_KAPI_DEVICES_MANAGER_HPP + +// IWYU pragma: private, include + +#include + +#include + +#include +#include + +namespace kapi::devices +{ + + //! @addtogroup kapi-devices-kernel-defined + //! @{ + + //! Ask the kernel to allocate a new major number. + //! + //! @return a new, unused major number. + auto allocate_major_number() -> std::size_t; + + //! Register a new device with the kernel's device manager. + //! + //! @param device The device to register. + //! @return true if the device was registered successfully, false otherwise. + auto register_device(device & device) -> bool; + + //! Unregister a device from the kernel's device manager. + //! + //! @param device The device to unregister. + //! @return true if the device was unregistered successfully, false otherwise. + auto unregister_device(device & device) -> bool; + + //! Find a device by its major and minor numbers. + //! + //! @param major the major number of the device. + //! @param minor the minor number of the device. + //! @return a pointer to the device iff. the device was found, nullptr otherwise. + auto find_device(std::size_t major, std::size_t minor) -> kstd::observer_ptr; + + //! Find a device by its name. + //! + //! @param name the name of the device. + //! @return a pointer to the device iff. the device was found, nullptr otherwise. + auto find_device(std::string_view name) -> kstd::observer_ptr; + + //! @} + +} // namespace kapi::devices + +#endif \ No newline at end of file diff --git a/kapi/kapi/filesystem.hpp b/kapi/kapi/filesystem.hpp new file mode 100644 index 0000000..94d42ce --- /dev/null +++ b/kapi/kapi/filesystem.hpp @@ -0,0 +1,73 @@ +#ifndef TEACHOS_KAPI_FILESYSTEM_HPP +#define TEACHOS_KAPI_FILESYSTEM_HPP + +#include +#include + +#include + +namespace kapi::filesystem +{ + /** + @brief The kapi::filesystem namespace provides the interface for filesystem operations in the kernel. It includes + functions for mounting and unmounting filesystems, as well as basic file operations such as opening, closing, reading + from, and writing to files. The actual implementation of these functions is in the kernel's filesystem subsystem, + which will handle the specifics of different filesystem types and their interactions with the underlying storage + devices. + */ + + /** + @brief Mounts a filesystem from the specified @p source at the specified @p target path. + @param source The source device or filesystem to mount. + @param target The target mount point. + @return 0 on success, -1 on failure. + @qualifier kernel-defined + */ + auto mount(std::string_view source, std::string_view target) -> int; + + /** + @brief Unmounts a filesystem from the specified @p target path. + @param target The target mount point to unmount. + @return 0 on success, -1 on failure. + @qualifier kernel-defined + */ + auto umount(std::string_view target) -> int; + + /** + @brief Opens a file at the specified @p path. + @param path The path to the file to open. + @return A file descriptor on success, -1 on failure. + @qualifier kernel-defined + */ + auto open(std::string_view path) -> int; + + /** + @brief Closes a @p file_descriptor. + @param file_descriptor The file descriptor to close. + @return 0 on success, -1 on failure. + @qualifier kernel-defined + */ + auto close(int file_descriptor) -> int; + + /** + @brief Reads @p size bytes into @p buffer from a @p file_descriptor. + @param file_descriptor The file descriptor to read from. + @param buffer The buffer to store the read data. + @param size The number of bytes to read. + @return The number of bytes read on success, -1 on failure. + @qualifier kernel-defined + */ + auto read(int file_descriptor, void * buffer, size_t size) -> ssize_t; + + /** + @brief Writes @p size bytes from @p buffer to a @p file_descriptor. + @param file_descriptor The file descriptor to write to. + @param buffer The buffer containing the data to write. + @param size The number of bytes to write. + @return The number of bytes written on success, -1 on failure. + @qualifier kernel-defined + */ + auto write(int file_descriptor, void const * buffer, size_t size) -> ssize_t; +} // namespace kapi::filesystem + +#endif // TEACHOS_KAPI_FILESYSTEM_HPP \ No newline at end of file diff --git a/kapi/kapi/interrupts.hpp b/kapi/kapi/interrupts.hpp new file mode 100644 index 0000000..4ba0684 --- /dev/null +++ b/kapi/kapi/interrupts.hpp @@ -0,0 +1,74 @@ +#ifndef TEACHOS_KAPI_INTERRUPTS_HPP +#define TEACHOS_KAPI_INTERRUPTS_HPP + +#include + +namespace kapi::interrupts +{ + + //! @addtogroup kapi-interrupts + //! @{ + + //! A status that indicates whether an interrupt was handled by a handler. + enum class status : bool + { + //! The interrupt was not handled by any handler. + unhandled, + //! The interrupt was handled by at least one handler. + handled, + }; + + //! The interface for all interrupt handlers. + struct handler + { + virtual ~handler() = default; + + //! Handle an interrupt with the given IRQ number. + // + //! This function will be called by the kernel in an interrupt context. As such, the function should complete its + //! task quickly and must take care when acquiring globally shared locks. + //! + //! @param irq_number The identifier of the interrupt request that triggered the handler. + //! @return status::handled if the handler successfully handled the interrupt, status::unhandled otherwise. + virtual auto handle_interrupt(std::uint32_t irq_number) -> status = 0; + }; + + //! @} + + //! @addtogroup kapi-interrupts-kernel-defined + //! @{ + + //! Register an interrupt handler for the given IRQ number. + //! + //! @param irq_number The IRQ number to register the handler for. + //! @param handler The interrupt handler to register. + auto register_handler(std::uint32_t irq_number, handler & handler) -> void; + + //! Unregister a previously registered interrupt handler. + //! + //! @param irq_number The IRQ number to unregister the handler for. + //! @param handler The interrupt handler to unregister. + auto unregister_handler(std::uint32_t irq_number, handler & handler) -> void; + + //! Dispatch an interrupt to all registered handlers. + //! + //! @param irq_number The IRQ number to dispatch. + //! @return status::handled if the interrupt was handled by at least one handler, status::unhandled otherwise. + auto dispatch(std::uint32_t irq_number) -> status; + + //! @} + + //! @addtogroup kapi-interrupts-platform-defined + //! @{ + + //! Enable external interrupts. + auto enable() -> void; + + //! Disable external interrupts. + auto disable() -> void; + + //! @} + +} // namespace kapi::interrupts + +#endif \ No newline at end of file diff --git a/kapi/kapi/memory.hpp b/kapi/kapi/memory.hpp new file mode 100644 index 0000000..8ad8d6e --- /dev/null +++ b/kapi/kapi/memory.hpp @@ -0,0 +1,131 @@ +#ifndef TEACHOS_KAPI_MEMORY_HPP +#define TEACHOS_KAPI_MEMORY_HPP + +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export + +#include +#include +#include + +namespace kapi::memory +{ + + using mmio_region = std::pair; + + //! @addtogroup kapi-memory-kernel-defined + //! @{ + + //! Initialize the physical memory manager. + //! + //! This function initializes the kernel-wide physical memory manager. The function will invoke the handoff handler to + //! transfer the platform-specific frame allocation state to the physical memory manager. + //! + //! @note Once this function returns, the global allocator has been replaced by the platform-agnostic, kernel-defined + //! allocator. Any state of the platform specific allocator may be released. + //! + //! @param frame_count The number of frames present in the system. + //! @param handoff_handler A function to be invoked to transfer the platform-specific frame allocation state. The + //! allocator to hand off to is passed to the handler. + auto init_pmm(std::size_t frame_count, void (&handoff_handler)(frame_allocator &)) -> void; + + //! Get the currently active frame allocator. + auto get_frame_allocator() -> frame_allocator &; + + //! Set the currently active frame allocator. + //! + //! @param allocator A new frame allocator. + //! @return The previously active frame allocator. + auto set_frame_allocator(frame_allocator & allocator) -> std::optional; + + //! Set the currently active page mapper. + //! + //! @param mapper A new page mapper. + //! @return The previously active page mapper. + auto set_page_mapper(page_mapper & mapper) -> std::optional; + + //! Allocate a new frame of physical memory + //! + //! @warning This function will panic if no frame allocator has been registered. + //! + //! @return An engaged std::optional iff. a frame could be allocated, std::nullopt otherwise. + auto allocate_frame() -> std::optional; + + //! Allocate multiple new frames of physical memory + //! + //! @warning This function will panic if no frame allocator has been registered. + //! + //! @return An engaged std::optional iff. @p count frames could be allocated, std::nullopt otherwise. + auto allocate_many_frames(std::size_t count) -> std::optional>; + + //! Map a page onto a frame. + //! + //! @warning This function will panic if no page mapper has been registered, or the page has already been mapped. + //! This function will not ensure that the frame is not already in use. + //! + //! @param page The page to map. + //! @param frame The frame to map the page into. + //! @param flags The flags to apply to this mapping. + //! @return A pointer to the first byte of the mapped page. + auto map(page page, frame frame, page_mapper::flags flags = page_mapper::flags::empty) -> std::byte *; + + //! Unmap a page. + //! + //! @warning This function will panic if no page mapper has been registered, or the page is not mapped. + //! + //! @param page The page to unmap + auto unmap(page page) -> void; + + //! Initialize the Memory-mapped I/O region system. + //! + //! @param base The base address for the MMIO region. + //! @param page_count The number of pages the MMIO region is spans. + auto init_mmio(linear_address base, std::size_t page_count) -> void; + + //! Allocate a Memory-mapped I/O region of the given size. + //! + //! @warning This function will panic if the MMIO system has not been initialized! + //! @param page_count The number of pages to allocate. + auto allocate_mmio_region(std::size_t page_count) -> mmio_region; + + //! Map a region of Memory-mapped I/O address space to a given hardware address using the given flags. + //! + //! @warning This function will panic if no page mapper has been registered, or the page has already been mapped. + //! This function will not ensure that the frame is not already in use. + //! + //! This function will always set the @p uncached flag. + //! + //! @param region The region to map. + //! @param hw_base The base of the hardware region. + //! @param flags The flags to apply. + auto map_mmio_region(mmio_region region, physical_address hw_base, page_mapper::flags flags = {}) -> std::byte *; + + //! Release a Memory-mapped I/O region. + //! + //! @warning This function will panic if the MMIO system has not been initialized! + //! @param region The region to release. + auto release_mmio_region(mmio_region region) -> void; + + //! @} + + //! @addtogroup kapi-memory-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 kapi::memory + +#endif diff --git a/kapi/kapi/memory/address.hpp b/kapi/kapi/memory/address.hpp new file mode 100644 index 0000000..9231cfc --- /dev/null +++ b/kapi/kapi/memory/address.hpp @@ -0,0 +1,252 @@ +#ifndef TEACHOS_KAPI_MEMORY_ADDRESS_HPP +#define TEACHOS_KAPI_MEMORY_ADDRESS_HPP + +// IWYU pragma: private, include + +#include +#include + +#include +#include +#include +#include +#include + +namespace kapi::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 + struct address + { + //! Construct a null-address. + constexpr 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(pointer)} + {} + + //! Convert this address into a C++ pointer. + //! + //! @tparam T The type of the object this address should refer to. + //! @return This address as a typed pointer to the given type. + template + explicit operator ObjectType *() const noexcept + { + return std::bit_cast(m_value); + } + + //! Create a new address n beyond this one. + //! + //! @param n The amount to add to this address. + //! @return A new address, n further than this one. + [[nodiscard]] constexpr auto operator+(std::ptrdiff_t n) const noexcept -> address + { + return address{m_value + n}; + } + + //! Increment this address by a given amount. + //! + //! @param n The amount to Increment the address by. + //! @return A reference to this address. + constexpr auto operator+=(std::ptrdiff_t n) noexcept -> address & + { + m_value += n; + return *this; + } + + //! Increment this address by one. + //! + //! @return A reference to this address. + constexpr auto operator++() noexcept -> address & + { + return (*this += 1); + } + + //! Increment this address by one. + //! + //! @return A copy of this address before the increment. + constexpr auto operator++(int) noexcept -> address + { + auto copy = *this; + ++*this; + return copy; + } + + //! Create a new address n bytes before this one + //! + //! @param n The amount to subtract from this address + //! @return A nre address, @p n ahead of this one + [[nodiscard]] constexpr auto operator-(std::ptrdiff_t n) noexcept -> address + { + return address{m_value - n}; + } + + //! Decrement this address by a given amount. + //! + //! @param n The amount to Decrement the address by. + //! @return A reference to this address. + constexpr auto operator-=(std::ptrdiff_t n) noexcept -> address & + { + m_value -= n; + return *this; + } + + //! Decrement this address by one. + //! + //! @return A reference to this address. + constexpr auto operator--() noexcept -> address & + { + return (*this -= 1); + } + + //! Decrement this address by one. + //! + //! @return A copy of this address before the decrement. + constexpr auto operator--(int) noexcept -> address + { + auto copy = *this; + --*this; + return copy; + } + + //! Calculate the distance between this address and another one + //! + //! @param other The address to calculate the distance to. + //! @return The distance between this address and the given one. + [[nodiscard]] constexpr auto operator-(address const & other) noexcept -> std::ptrdiff_t + { + return m_value - other.m_value; + } + + //! Extract the lower bits of the address + //! + //! @note The only meaningful values for @p n are powers of two. + //! + //! @param n The divisor to use for extraction. + //! @return The lower bits of the address as defined by the divisor. + constexpr auto operator%(std::size_t n) const noexcept -> std::uintptr_t + { + return m_value % n; + } + + //! Extract the upper bits of the address + //! + //! @note The only meaningful values for @p n are powers of two. + //! + //! @param n The divisor to use for extraction. + //! @return The upper bits of the address as defined by the divisor. + constexpr auto operator/(std::size_t n) const noexcept -> std::uintptr_t + { + return m_value / n; + } + + //! 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 + constexpr auto operator&(MaskType mask) const noexcept -> MaskType + { + return static_cast(m_value & mask); + } + + constexpr auto operator+(kstd::units::bytes n) const noexcept -> address + { + return address{m_value + n.value}; + } + + constexpr auto operator+=(kstd::units::bytes n) noexcept -> address & + { + return *this = *this + n; + } + + //! 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; + + //! A physical address. + using physical_address = address; + +} // namespace kapi::memory + +namespace kstd +{ + + template + struct formatter> : kstd::formatter + { + constexpr auto static suffix = Type == kapi::memory::address_type::linear ? "%lin" : "%phy"; + + constexpr auto parse(format_parse_context & context) -> format_parse_context::iterator + { + auto result = formatter::parse(context); + if (!this->specifiers.type) + { + this->specifiers.type = 'p'; + this->specifiers.alternative_form = true; + } + return result; + } + + auto format(kapi::memory::address const & address, format_context & context) const -> void + { + formatter::format(address.raw(), context); + context.push(suffix); + } + }; + +} // namespace kstd + +#endif \ No newline at end of file diff --git a/kapi/kapi/memory/chunk.hpp b/kapi/kapi/memory/chunk.hpp new file mode 100644 index 0000000..485a890 --- /dev/null +++ b/kapi/kapi/memory/chunk.hpp @@ -0,0 +1,109 @@ +#ifndef TEACHOS_KAPI_MEMORY_CHUNK_HPP +#define TEACHOS_KAPI_MEMORY_CHUNK_HPP + +// IWYU pragma: private, include + +#include + +#include +#include + +namespace kapi::memory +{ + + //! @qualifier kernel-defined + //! A fixed-size unit of memory, indexed by a number. + //! + //! @tparam ChunkType The CRTP type of the deriving class + //! @tparam AddressType The type of addresses used to index this chunk + //! @tparam Size The size of this chunk. + template + struct chunk + { + //! The type of addresses used to index this chunk + using address_type = AddressType; + + //! The size of this chunk + constexpr auto static size = Size; + + //! Construct a new chunk handle for the chunk containing the given address. + //! + //! @param address An address contained by the desired chunk. + //! @return A handle to a chunk containing the given address. + constexpr auto static containing(address_type address) noexcept -> ChunkType + { + return ChunkType{address / size.value}; + } + + //! Get the start address of the chunk referenced by this handle. + //! + //! @return The address of the first byte contained by the chunk referenced by this handle. + [[nodiscard]] constexpr auto start_address() const noexcept -> address_type + { + return address_type{(m_number * size).value}; + } + + //! Get the number of the chunk referenced by this handle. + //! + //! @return The zero-based number of the chunk referenced by this handle. + [[nodiscard]] constexpr auto number() const noexcept -> std::size_t + { + return m_number; + } + + //! Get a handle n chunks after the one referenced by this handle. + //! + //! @param n The positive offset to this chunk. + //! @return A handle referencing the chunk n chunks after the one referenced by this handle. + constexpr auto operator+(std::size_t n) const noexcept -> ChunkType + { + return ChunkType{m_number + n}; + } + + //! Let this handle reference the next chunk after the currently reference one. + //! + //! @return A handle referencing the same chunk as this handle did before the operation. + constexpr auto operator++(int) noexcept -> ChunkType + { + auto copy = static_cast(*this); + ++*this; + return copy; + } + + //! Let this handle reference the next chunk after the currently reference one. + //! + //! @return A reference to this handle. + constexpr auto operator++() noexcept -> ChunkType & + { + ++m_number; + return static_cast(*this); + } + + //! Check if this chunk handle reference the same chunk as another one. + //! + //! @param other Another chunk handle. + constexpr auto operator==(chunk const & other) const noexcept -> bool = default; + + //! Compare the number of the chunk referenced by this handle to the one reference by another one. + //! + //! @param other Another chunk handle. + constexpr auto operator<=>(chunk const & other) const noexcept -> std::strong_ordering = default; + + private: + friend ChunkType; + + //! Construct a handle referencing the first chunk of the respective address space. + constexpr chunk() noexcept = default; + + //! Construct a handle referencing the chunk of memory with the given number. + explicit constexpr chunk(std::size_t number) noexcept + : m_number{number} + {} + + //! The number of the currently referenced chunk. + std::size_t m_number{}; + }; + +} // namespace kapi::memory + +#endif \ No newline at end of file diff --git a/kapi/kapi/memory/frame.hpp b/kapi/kapi/memory/frame.hpp new file mode 100644 index 0000000..e423fa4 --- /dev/null +++ b/kapi/kapi/memory/frame.hpp @@ -0,0 +1,48 @@ +#ifndef TEACHOS_KAPI_MEMORY_FRAME_HPP +#define TEACHOS_KAPI_MEMORY_FRAME_HPP + +// IWYU pragma: private, include + +#include +#include +#include + +#include + +namespace kapi::memory +{ + + //! @qualifier kernel-defined + //! A handle to a frame of physical memory. + //! + //! @note Contrary to the address types, this type is modeled using inheritance to support future extensions. + struct frame : chunk + { + frame() = default; + + frame(std::size_t number) + : chunk{number} + {} + + using difference_type = std::ptrdiff_t; + + //! @copydoc chunk::containing + //! + //! @note This factory shadows the base factory to aid in type deduction. + constexpr auto static containing(physical_address address) noexcept -> frame + { + return frame{chunk::containing(address)}; + } + + //! Convert a base chunk into a page. + //! + //! This constructor allows for conversion from chunk to a frame for + //! convenience. It is deliberately not explicit. + constexpr frame(chunk other) + : chunk{other} + {} + }; + +} // namespace kapi::memory + +#endif \ No newline at end of file diff --git a/kapi/kapi/memory/frame_allocator.hpp b/kapi/kapi/memory/frame_allocator.hpp new file mode 100644 index 0000000..784ea93 --- /dev/null +++ b/kapi/kapi/memory/frame_allocator.hpp @@ -0,0 +1,66 @@ +#ifndef TEACHOS_KAPI_MEMORY_FRAME_ALLOCATOR_HPP +#define TEACHOS_KAPI_MEMORY_FRAME_ALLOCATOR_HPP + +// IWYU pragma: private, include + +#include + +#include +#include +#include + +namespace kapi::memory +{ + + //! The interface of all frame allocators. + //! + //! A frame allocator is responsible for the allocation, and deallocation, of frames of physical memory. Frames + //! obtained from an allocator shall only be deallocated, or released, via the same allocator. When a frame allocated + //! from one allocator is release via a different one (instance or type), the behavior is undefined. + struct frame_allocator + { + frame_allocator(frame_allocator const &) = delete; + frame_allocator(frame_allocator &&) = delete; + auto operator=(frame_allocator const &) -> frame_allocator & = delete; + auto operator=(frame_allocator &&) -> frame_allocator & = delete; + + virtual ~frame_allocator() = default; + + //! Allocate a frame of physical memory. + //! + //! @return An engaged std::optional iff. a new frame could be allocated, std::nullopt otherwise. + virtual auto allocate() noexcept -> std::optional + { + return allocate_many(1).transform([](auto result) { return result.first; }); + } + + //! Mark the given frame as used + virtual auto mark_used(frame frame) -> void = 0; + + //! Allocate multiple consecutive frames of physical memory. + //! + //! @param count The number of frames to allocate + //! @return an engaged optional iff. a block of consecutive frames could be allocated, std::nullopt otherwise. + virtual auto allocate_many(std::size_t count) noexcept -> std::optional> = 0; + + //! Release a frame of physical memory. + //! + //! @param frame A frame of physical memory, previously acquired by a call to the #allocate function. + virtual auto release(frame frame) -> void + { + return release_many({frame, 1}); + } + + //! Release a frame of physical memory. + //! + //! @param frame_set A set of frames of physical memory, previously acquired by a call to the #allocate_many + //! function. + virtual auto release_many(std::pair frame_set) -> void = 0; + + protected: + frame_allocator() = default; + }; + +} // namespace kapi::memory + +#endif // TEACHOS_KAPI_MEMORY_FRAME_ALLOCATOR_HPP \ No newline at end of file diff --git a/kapi/kapi/memory/layout.hpp b/kapi/kapi/memory/layout.hpp new file mode 100644 index 0000000..733fa96 --- /dev/null +++ b/kapi/kapi/memory/layout.hpp @@ -0,0 +1,54 @@ +#ifndef TEACHOS_KAPI_MEMORY_LAYOUT_HPP +#define TEACHOS_KAPI_MEMORY_LAYOUT_HPP + +// IWYU pragma: private, include + +#include + +#include + +namespace kapi::memory +{ + + //! The size of a single page of virtual memory. + //! + //! Platforms that use different sizes of pages are expected to emulate 4 KiB pages towards the kernel. + constexpr auto page_size = kstd::units::KiB(4); + + //! The size of a single frame of physical memory. + //! + //! Platforms that use different sizes of frames are expected to emulate 4 KiB pages towards the kernel. + constexpr auto frame_size = kstd::units::KiB(4); + + //! The linear base address of the higher-half direct map. + //! + //! Platforms are expected to provide a mapping of at least the first 512 GiB of available memory at this address. + constexpr auto higher_half_direct_map_base = linear_address{0xffff'8000'0000'0000uz}; + + //! The linear base address of the kernel heap. + constexpr auto heap_base = linear_address{0xffff'c000'0000'0000uz}; + + //! The linear base address of the memory region reserved for the metadata required by the PMM. + constexpr auto pmm_metadata_base = linear_address{0xffff'd000'0000'0000uz}; + + //! The linear base address of all Memory Mapped I/O mappings. + constexpr auto mmio_base = linear_address{0xffff'e000'0000'0000uz}; + + //! 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/kapi/memory/page.hpp b/kapi/kapi/memory/page.hpp new file mode 100644 index 0000000..d987534 --- /dev/null +++ b/kapi/kapi/memory/page.hpp @@ -0,0 +1,38 @@ +#ifndef TEACHOS_KAPI_MEMORY_PAGE_HPP +#define TEACHOS_KAPI_MEMORY_PAGE_HPP + +// IWYU pragma: private, include + +#include +#include +#include + +#include + +namespace kapi::memory +{ + + //! @qualifier kernel-defined + //! A handle to a page of virtual memory. + //! + //! @note Contrary to the address types, this type is modeled using inheritance to support future extensions. + struct page : chunk + { + page() = default; + + page(std::size_t number) + : chunk{number} + {} + + //! Convert a base chunk into a page. + //! + //! This constructor allows for conversion from chunk to a page for convenience. + //! It is deliberately not explicit. + constexpr page(chunk other) + : chunk{other} + {} + }; + +} // namespace kapi::memory + +#endif \ No newline at end of file diff --git a/kapi/kapi/memory/page_mapper.hpp b/kapi/kapi/memory/page_mapper.hpp new file mode 100644 index 0000000..fb600b2 --- /dev/null +++ b/kapi/kapi/memory/page_mapper.hpp @@ -0,0 +1,90 @@ +#ifndef TEACHOS_KAPI_MEMORY_PAGE_MAPPER_HPP +#define TEACHOS_KAPI_MEMORY_PAGE_MAPPER_HPP + +// IWYU pragma: private, include + +#include +#include + +#include + +#include +#include +#include + +namespace kapi::memory +{ + + //! @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, //! 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. + global = 1 << 4, //! The page translation persists across context switches. + }; + + 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. + virtual auto map(page page, frame frame, flags flags) -> std::byte * = 0; + + //! 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) 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 + [[nodiscard]] auto map_as(page page, frame frame, flags flags) -> T * + { + return std::bit_cast(map(page, frame, flags)); + } + + protected: + page_mapper() = default; + }; + +} // namespace kapi::memory + +namespace kstd::ext +{ + template<> + struct is_bitfield_enum : std::true_type + { + }; +} // namespace kstd::ext + +#endif \ No newline at end of file diff --git a/kapi/kapi/system.hpp b/kapi/kapi/system.hpp new file mode 100644 index 0000000..8a20af9 --- /dev/null +++ b/kapi/kapi/system.hpp @@ -0,0 +1,32 @@ +#ifndef TEACHOS_KAPI_SYSTEM_HPP +#define TEACHOS_KAPI_SYSTEM_HPP + +#include +#include + +namespace kapi::system +{ + + //! @addtogroup kapi-system-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; + + //! @} // end group kernel-defined + + //! @addtogroup kapi-system-platform-defined + //! @{ + + //! A hook that runs once the memory subsystem has been initialized. + auto memory_initialized() -> void; + + //! @} // end group platform-defined + +} // namespace kapi::system + +#endif -- cgit v1.2.3 From 1246e00478fb5ab2a357de17066fd8738395d9f1 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 4 May 2026 08:20:42 +0200 Subject: debug: split gdb modules --- kapi/gdb/__init__.py | 15 +++++++++++++++ kapi/gdb/address.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 kapi/gdb/__init__.py create mode 100644 kapi/gdb/address.py (limited to 'kapi') diff --git a/kapi/gdb/__init__.py b/kapi/gdb/__init__.py new file mode 100644 index 0000000..c37c7b7 --- /dev/null +++ b/kapi/gdb/__init__.py @@ -0,0 +1,15 @@ +import gdb.printing + +from .address import KapiMemoryAddressPrinter + + +def build_pretty_printers(): + pp = gdb.printing.RegexpCollectionPrettyPrinter("kapi") + pp.add_printer( + "kapi_memory_address", "^kapi::memory::address<.*>$", KapiMemoryAddressPrinter + ) + return pp + + +def register_printers(objfile): + gdb.printing.register_pretty_printer(objfile, build_pretty_printers(), replace=True) diff --git a/kapi/gdb/address.py b/kapi/gdb/address.py new file mode 100644 index 0000000..677c9aa --- /dev/null +++ b/kapi/gdb/address.py @@ -0,0 +1,33 @@ +import gdb + + +class KapiMemoryAddressPrinter: + """Print kapi::MemoryAddress.""" + + def __init__(self, val): + self.val = val + self.address_type = val.type.template_argument(0) + + def to_string(self): + try: + raw_address = int(self.val["m_value"]) + type_string = str(self.address_type) + + if "linear" in type_string: + suffix = "%lin" + elif "physical" in type_string: + suffix = "%phy" + else: + suffix = "%???" + + return f"{raw_address:#018x}{suffix}" + except Exception as e: + return f"{self.val}: {e}" + + def children(self): + if "linear" in str(self.address_type): + yield ( + "std::byte *", + self.val["m_value"].cast(gdb.lookup_type("std::byte").pointer()), + ) + yield ("m_value", self.val["m_value"]) -- cgit v1.2.3 From 78e42a1b6e0a857865be1e60f82871ac13c91bb1 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 4 May 2026 12:01:01 +0200 Subject: debug: improve pretty printer implementations --- kapi/gdb/__init__.py | 4 ++++ kapi/gdb/address.py | 25 +++++++++++-------------- kapi/gdb/device.py | 9 +++++++++ 3 files changed, 24 insertions(+), 14 deletions(-) create mode 100644 kapi/gdb/device.py (limited to 'kapi') diff --git a/kapi/gdb/__init__.py b/kapi/gdb/__init__.py index c37c7b7..ce95628 100644 --- a/kapi/gdb/__init__.py +++ b/kapi/gdb/__init__.py @@ -1,6 +1,7 @@ import gdb.printing from .address import KapiMemoryAddressPrinter +from .device import KapiDevicesDevicePrinter def build_pretty_printers(): @@ -8,6 +9,9 @@ def build_pretty_printers(): pp.add_printer( "kapi_memory_address", "^kapi::memory::address<.*>$", KapiMemoryAddressPrinter ) + pp.add_printer( + "kapi_devices_device", "^kapi::devices::device$", KapiDevicesDevicePrinter + ) return pp diff --git a/kapi/gdb/address.py b/kapi/gdb/address.py index 677c9aa..24fe681 100644 --- a/kapi/gdb/address.py +++ b/kapi/gdb/address.py @@ -1,17 +1,16 @@ import gdb +from teachos import TeachOSBasePrinter -class KapiMemoryAddressPrinter: - """Print kapi::MemoryAddress.""" - +class KapiMemoryAddressPrinter(TeachOSBasePrinter): def __init__(self, val): - self.val = val - self.address_type = val.type.template_argument(0) + super().__init__(val) + self.__type = val.type.template_argument(0) def to_string(self): try: - raw_address = int(self.val["m_value"]) - type_string = str(self.address_type) + raw_address = int(self.value["m_value"]) + type_string = str(self.__type) if "linear" in type_string: suffix = "%lin" @@ -22,12 +21,10 @@ class KapiMemoryAddressPrinter: return f"{raw_address:#018x}{suffix}" except Exception as e: - return f"{self.val}: {e}" + return f"{self.value}: {e}" def children(self): - if "linear" in str(self.address_type): - yield ( - "std::byte *", - self.val["m_value"].cast(gdb.lookup_type("std::byte").pointer()), - ) - yield ("m_value", self.val["m_value"]) + if "linear" in str(self.__type): + pointer_type = gdb.lookup_type("std::byte").pointer() + yield ("[bytes]", self.value["m_value"].cast(pointer_type)) + yield from super().children() diff --git a/kapi/gdb/device.py b/kapi/gdb/device.py new file mode 100644 index 0000000..b655972 --- /dev/null +++ b/kapi/gdb/device.py @@ -0,0 +1,9 @@ +import gdb +from teachos import TeachOSBasePrinter + + +class KapiDevicesDevicePrinter(TeachOSBasePrinter): + def to_string(self): + return ( + f"{self.value['m_name']} @ {self.value['m_major']}:{self.value['m_minor']}" + ) -- cgit v1.2.3 From 6ac1537d07dffa3482bbccf710a77a7316191c2e Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 7 May 2026 12:09:27 +0200 Subject: debug: use gdb.ValuePrinter base class --- kapi/gdb/address.py | 15 ++++++++------- kapi/gdb/device.py | 17 ++++++++++++++--- 2 files changed, 22 insertions(+), 10 deletions(-) (limited to 'kapi') diff --git a/kapi/gdb/address.py b/kapi/gdb/address.py index 24fe681..429db1d 100644 --- a/kapi/gdb/address.py +++ b/kapi/gdb/address.py @@ -1,15 +1,14 @@ import gdb -from teachos import TeachOSBasePrinter -class KapiMemoryAddressPrinter(TeachOSBasePrinter): +class KapiMemoryAddressPrinter(gdb.ValuePrinter): def __init__(self, val): - super().__init__(val) + self.__val = val self.__type = val.type.template_argument(0) def to_string(self): try: - raw_address = int(self.value["m_value"]) + raw_address = int(self.__val["m_value"]) type_string = str(self.__type) if "linear" in type_string: @@ -21,10 +20,12 @@ class KapiMemoryAddressPrinter(TeachOSBasePrinter): return f"{raw_address:#018x}{suffix}" except Exception as e: - return f"{self.value}: {e}" + return f"{self.__val}: {e}" def children(self): if "linear" in str(self.__type): pointer_type = gdb.lookup_type("std::byte").pointer() - yield ("[bytes]", self.value["m_value"].cast(pointer_type)) - yield from super().children() + yield ("[bytes]", self.__val["m_value"].cast(pointer_type)) + + def display_hint(self): + return None diff --git a/kapi/gdb/device.py b/kapi/gdb/device.py index b655972..8e515ef 100644 --- a/kapi/gdb/device.py +++ b/kapi/gdb/device.py @@ -1,9 +1,20 @@ import gdb -from teachos import TeachOSBasePrinter -class KapiDevicesDevicePrinter(TeachOSBasePrinter): +class KapiDevicesDevicePrinter(gdb.ValuePrinter): + def __init__(self, val): + self.__val = val + def to_string(self): return ( - f"{self.value['m_name']} @ {self.value['m_major']}:{self.value['m_minor']}" + f"{self.__val['m_name']} @ {self.__val['m_major']}:{self.__val['m_minor']}" ) + + def children(self): + yield ("major", self.__val["m_major"]) + yield ("minor", self.__val["m_minor"]) + yield ("name", self.__val["m_name"]) + yield ("parent", self.__val["m_parent"]) + + def display_hint(self): + return None -- cgit v1.2.3 From 07fb219869099c719b0fbfeae81b95512487639e Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 8 May 2026 17:12:24 +0200 Subject: debug: add page and frame formatters --- kapi/gdb/__init__.py | 9 +++++++-- kapi/gdb/address.py | 31 ------------------------------- kapi/gdb/device.py | 20 -------------------- kapi/gdb/devices/__init__.py | 1 + kapi/gdb/devices/device.py | 20 ++++++++++++++++++++ kapi/gdb/memory/__init__.py | 4 ++++ kapi/gdb/memory/address.py | 31 +++++++++++++++++++++++++++++++ kapi/gdb/memory/chunk.py | 41 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 104 insertions(+), 53 deletions(-) delete mode 100644 kapi/gdb/address.py delete mode 100644 kapi/gdb/device.py create mode 100644 kapi/gdb/devices/__init__.py create mode 100644 kapi/gdb/devices/device.py create mode 100644 kapi/gdb/memory/__init__.py create mode 100644 kapi/gdb/memory/address.py create mode 100644 kapi/gdb/memory/chunk.py (limited to 'kapi') diff --git a/kapi/gdb/__init__.py b/kapi/gdb/__init__.py index ce95628..afb68f8 100644 --- a/kapi/gdb/__init__.py +++ b/kapi/gdb/__init__.py @@ -1,7 +1,7 @@ import gdb.printing -from .address import KapiMemoryAddressPrinter -from .device import KapiDevicesDevicePrinter +from .memory import * +from .devices import * def build_pretty_printers(): @@ -9,6 +9,11 @@ def build_pretty_printers(): pp.add_printer( "kapi_memory_address", "^kapi::memory::address<.*>$", KapiMemoryAddressPrinter ) + pp.add_printer( + "kapi_memory_chunk", "^kapi::memory::chunk<.*>$", KapiMemoryChunkPrinter + ) + pp.add_printer("kapi_memory_frame", "^kapi::memory::frame$", KapiMemoryFramePrinter) + pp.add_printer("kapi_memory_page", "^kapi::memory::page$", KapiMemoryPagePrinter) pp.add_printer( "kapi_devices_device", "^kapi::devices::device$", KapiDevicesDevicePrinter ) diff --git a/kapi/gdb/address.py b/kapi/gdb/address.py deleted file mode 100644 index 429db1d..0000000 --- a/kapi/gdb/address.py +++ /dev/null @@ -1,31 +0,0 @@ -import gdb - - -class KapiMemoryAddressPrinter(gdb.ValuePrinter): - def __init__(self, val): - self.__val = val - self.__type = val.type.template_argument(0) - - def to_string(self): - try: - raw_address = int(self.__val["m_value"]) - type_string = str(self.__type) - - if "linear" in type_string: - suffix = "%lin" - elif "physical" in type_string: - suffix = "%phy" - else: - suffix = "%???" - - return f"{raw_address:#018x}{suffix}" - except Exception as e: - return f"{self.__val}: {e}" - - def children(self): - if "linear" in str(self.__type): - pointer_type = gdb.lookup_type("std::byte").pointer() - yield ("[bytes]", self.__val["m_value"].cast(pointer_type)) - - def display_hint(self): - return None diff --git a/kapi/gdb/device.py b/kapi/gdb/device.py deleted file mode 100644 index 8e515ef..0000000 --- a/kapi/gdb/device.py +++ /dev/null @@ -1,20 +0,0 @@ -import gdb - - -class KapiDevicesDevicePrinter(gdb.ValuePrinter): - def __init__(self, val): - self.__val = val - - def to_string(self): - return ( - f"{self.__val['m_name']} @ {self.__val['m_major']}:{self.__val['m_minor']}" - ) - - def children(self): - yield ("major", self.__val["m_major"]) - yield ("minor", self.__val["m_minor"]) - yield ("name", self.__val["m_name"]) - yield ("parent", self.__val["m_parent"]) - - def display_hint(self): - return None diff --git a/kapi/gdb/devices/__init__.py b/kapi/gdb/devices/__init__.py new file mode 100644 index 0000000..3bab1ea --- /dev/null +++ b/kapi/gdb/devices/__init__.py @@ -0,0 +1 @@ +from .device import KapiDevicesDevicePrinter diff --git a/kapi/gdb/devices/device.py b/kapi/gdb/devices/device.py new file mode 100644 index 0000000..8e515ef --- /dev/null +++ b/kapi/gdb/devices/device.py @@ -0,0 +1,20 @@ +import gdb + + +class KapiDevicesDevicePrinter(gdb.ValuePrinter): + def __init__(self, val): + self.__val = val + + def to_string(self): + return ( + f"{self.__val['m_name']} @ {self.__val['m_major']}:{self.__val['m_minor']}" + ) + + def children(self): + yield ("major", self.__val["m_major"]) + yield ("minor", self.__val["m_minor"]) + yield ("name", self.__val["m_name"]) + yield ("parent", self.__val["m_parent"]) + + def display_hint(self): + return None diff --git a/kapi/gdb/memory/__init__.py b/kapi/gdb/memory/__init__.py new file mode 100644 index 0000000..2aa6564 --- /dev/null +++ b/kapi/gdb/memory/__init__.py @@ -0,0 +1,4 @@ +from .address import KapiMemoryAddressPrinter +from .chunk import KapiMemoryFramePrinter +from .chunk import KapiMemoryPagePrinter +from .chunk import KapiMemoryChunkPrinter diff --git a/kapi/gdb/memory/address.py b/kapi/gdb/memory/address.py new file mode 100644 index 0000000..429db1d --- /dev/null +++ b/kapi/gdb/memory/address.py @@ -0,0 +1,31 @@ +import gdb + + +class KapiMemoryAddressPrinter(gdb.ValuePrinter): + def __init__(self, val): + self.__val = val + self.__type = val.type.template_argument(0) + + def to_string(self): + try: + raw_address = int(self.__val["m_value"]) + type_string = str(self.__type) + + if "linear" in type_string: + suffix = "%lin" + elif "physical" in type_string: + suffix = "%phy" + else: + suffix = "%???" + + return f"{raw_address:#018x}{suffix}" + except Exception as e: + return f"{self.__val}: {e}" + + def children(self): + if "linear" in str(self.__type): + pointer_type = gdb.lookup_type("std::byte").pointer() + yield ("[bytes]", self.__val["m_value"].cast(pointer_type)) + + def display_hint(self): + return None diff --git a/kapi/gdb/memory/chunk.py b/kapi/gdb/memory/chunk.py new file mode 100644 index 0000000..74b1407 --- /dev/null +++ b/kapi/gdb/memory/chunk.py @@ -0,0 +1,41 @@ +import gdb +from teachos import format_size + + +class KapiMemoryChunkPrinter(gdb.ValuePrinter): + + def __init__(self, val: gdb.Value, typename="chunk"): + self.__val = val + try: + self.__number = int(val["m_number"]) + except gdb.error: + self.__number = "" + + try: + self.__size = int(gdb.parse_and_eval(f"{val.type.name}::size")["value"]) + except gdb.error: + self.__size = "" + + self.__typename = typename + + def to_string(self): + return f"{self.__typename} {self.__number} of size {format_size(self.__size)}" + + def children(self): + yield ("number", self.__number) + yield ("size", self.__size) + + def display_hint(self): + return None + + +class KapiMemoryFramePrinter(KapiMemoryChunkPrinter): + + def __init__(self, val): + super().__init__(val, "frame") + + +class KapiMemoryPagePrinter(KapiMemoryChunkPrinter): + + def __init__(self, val): + super().__init__(val, "page") -- cgit v1.2.3 From 8ec011d9f5ad79c1e951127d3906a08e282649d1 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 8 May 2026 18:14:08 +0200 Subject: debug: add pretty printer for boot modules --- kapi/gdb/__init__.py | 8 +++++++- kapi/gdb/boot_modules/__init__.py | 1 + kapi/gdb/boot_modules/boot_module.py | 23 +++++++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 kapi/gdb/boot_modules/__init__.py create mode 100644 kapi/gdb/boot_modules/boot_module.py (limited to 'kapi') diff --git a/kapi/gdb/__init__.py b/kapi/gdb/__init__.py index afb68f8..88b1d05 100644 --- a/kapi/gdb/__init__.py +++ b/kapi/gdb/__init__.py @@ -1,7 +1,8 @@ import gdb.printing -from .memory import * +from .boot_modules import * from .devices import * +from .memory import * def build_pretty_printers(): @@ -17,6 +18,11 @@ def build_pretty_printers(): pp.add_printer( "kapi_devices_device", "^kapi::devices::device$", KapiDevicesDevicePrinter ) + pp.add_printer( + "kapi_boot_modules_boot_module", + "^kapi::boot_modules::boot_module$", + KapiBootModulesBootModulePrinter, + ) return pp diff --git a/kapi/gdb/boot_modules/__init__.py b/kapi/gdb/boot_modules/__init__.py new file mode 100644 index 0000000..fedab65 --- /dev/null +++ b/kapi/gdb/boot_modules/__init__.py @@ -0,0 +1 @@ +from .boot_module import KapiBootModulesBootModulePrinter diff --git a/kapi/gdb/boot_modules/boot_module.py b/kapi/gdb/boot_modules/boot_module.py new file mode 100644 index 0000000..f0d558b --- /dev/null +++ b/kapi/gdb/boot_modules/boot_module.py @@ -0,0 +1,23 @@ +import gdb +from teachos import format_size + + +class KapiBootModulesBootModulePrinter(gdb.ValuePrinter): + def __init__(self, val): + self.__val = val + self.__name = val["name"] + self.__start = val["start_address"] + self.__size = val["size"] + self.__pointer_type = gdb.lookup_type("std::byte").pointer() + self.__pretty_name = self.__name if str(self.__name) != '""' else "" + + def to_string(self): + return f"boot module {self.__pretty_name} of size {format_size(int(self.__size))}, at {self.__start.cast(self.__pointer_type)}" + + def children(self): + yield ("name", self.__name) + yield ("start_address", self.__start) + yield ("size", self.__size) + + def display_hint(self): + return None -- cgit v1.2.3 From 2cb7a2575e8eb46df36dae108fae661b91801540 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sun, 10 May 2026 12:18:01 +0200 Subject: debug: add pretty printer for boot modules registry --- kapi/gdb/__init__.py | 5 +++++ kapi/gdb/boot_modules/__init__.py | 1 + kapi/gdb/boot_modules/boot_module.py | 4 ++-- kapi/gdb/boot_modules/boot_module_registry.py | 20 ++++++++++++++++++++ 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 kapi/gdb/boot_modules/boot_module_registry.py (limited to 'kapi') diff --git a/kapi/gdb/__init__.py b/kapi/gdb/__init__.py index 88b1d05..1b36753 100644 --- a/kapi/gdb/__init__.py +++ b/kapi/gdb/__init__.py @@ -23,6 +23,11 @@ def build_pretty_printers(): "^kapi::boot_modules::boot_module$", KapiBootModulesBootModulePrinter, ) + pp.add_printer( + "kapi_boot_modules_boot_module_registry", + "^kapi::boot_modules::boot_module_registry$", + KapiBootModulesBootModuleRegistryPrinter, + ) return pp diff --git a/kapi/gdb/boot_modules/__init__.py b/kapi/gdb/boot_modules/__init__.py index fedab65..2a54136 100644 --- a/kapi/gdb/boot_modules/__init__.py +++ b/kapi/gdb/boot_modules/__init__.py @@ -1 +1,2 @@ from .boot_module import KapiBootModulesBootModulePrinter +from .boot_module_registry import KapiBootModulesBootModuleRegistryPrinter diff --git a/kapi/gdb/boot_modules/boot_module.py b/kapi/gdb/boot_modules/boot_module.py index f0d558b..b26ecf1 100644 --- a/kapi/gdb/boot_modules/boot_module.py +++ b/kapi/gdb/boot_modules/boot_module.py @@ -9,10 +9,10 @@ class KapiBootModulesBootModulePrinter(gdb.ValuePrinter): self.__start = val["start_address"] self.__size = val["size"] self.__pointer_type = gdb.lookup_type("std::byte").pointer() - self.__pretty_name = self.__name if str(self.__name) != '""' else "" + self.__pretty_name = " " + str(self.__name) if str(self.__name) != '""' else "" def to_string(self): - return f"boot module {self.__pretty_name} of size {format_size(int(self.__size))}, at {self.__start.cast(self.__pointer_type)}" + return f"boot module{self.__pretty_name} of size {format_size(int(self.__size))}, at {self.__start.cast(self.__pointer_type)}" def children(self): yield ("name", self.__name) diff --git a/kapi/gdb/boot_modules/boot_module_registry.py b/kapi/gdb/boot_modules/boot_module_registry.py new file mode 100644 index 0000000..599a823 --- /dev/null +++ b/kapi/gdb/boot_modules/boot_module_registry.py @@ -0,0 +1,20 @@ +import gdb +from teachos import format_size + + +class KapiBootModulesBootModuleRegistryPrinter(gdb.ValuePrinter): + def __init__(self, val: gdb.Value): + self.__val = val + self.__modules = val["m_modules"] + self.__size = int(self.__modules["m_size"]) + self.__element_type = gdb.lookup_type("kapi::boot_modules::boot_module") + + def to_string(self): + return f"boot module registry of size {self.__size}" + + def children(self): + yield ("[size]", self.__size) + yield ("m_modules", self.__modules) + + def display_hint(self): + return None -- cgit v1.2.3 From f3b75be5725a5a975cf73926e73aa63efe928026 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sun, 10 May 2026 12:27:16 +0200 Subject: debug: show data in boot modules --- kapi/gdb/boot_modules/boot_module.py | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) (limited to 'kapi') diff --git a/kapi/gdb/boot_modules/boot_module.py b/kapi/gdb/boot_modules/boot_module.py index b26ecf1..97e6584 100644 --- a/kapi/gdb/boot_modules/boot_module.py +++ b/kapi/gdb/boot_modules/boot_module.py @@ -3,21 +3,42 @@ from teachos import format_size class KapiBootModulesBootModulePrinter(gdb.ValuePrinter): + class Iterator: + def __init__(self, begin: gdb.Value, end: gdb.Value): + self._item = begin + self._end = end + self._count = 0 + + def __iter__(self): + return self + + def __next__(self): + count = self._count + self._count = count + 1 + + if self._item == self._end: + raise StopIteration + + element = self._item.dereference() + self._item += 1 + return (f"[{count}]", element) + def __init__(self, val): + self.__pointer_type = gdb.lookup_type("std::byte").pointer() + self.__val = val self.__name = val["name"] self.__start = val["start_address"] - self.__size = val["size"] - self.__pointer_type = gdb.lookup_type("std::byte").pointer() + self.__size = int(val["size"]) + self.__begin = val["start_address"]["m_value"].cast(self.__pointer_type) + self.__end = self.__begin + self.__size self.__pretty_name = " " + str(self.__name) if str(self.__name) != '""' else "" def to_string(self): - return f"boot module{self.__pretty_name} of size {format_size(int(self.__size))}, at {self.__start.cast(self.__pointer_type)}" + return f"boot module{self.__pretty_name} of size {format_size(self.__size)}, at {self.__start.cast(self.__pointer_type)}" def children(self): - yield ("name", self.__name) - yield ("start_address", self.__start) - yield ("size", self.__size) + return self.Iterator(self.__begin, self.__end) def display_hint(self): - return None + return "array" -- cgit v1.2.3 From df549fb7a3ed3ff9d675da6a90595c78bed7a1f8 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 10 May 2026 13:20:47 +0200 Subject: return const boot_module_registry reference --- kapi/kapi/boot_modules.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kapi') diff --git a/kapi/kapi/boot_modules.hpp b/kapi/kapi/boot_modules.hpp index 026479d..2a88f74 100644 --- a/kapi/kapi/boot_modules.hpp +++ b/kapi/kapi/boot_modules.hpp @@ -25,7 +25,7 @@ namespace kapi::boot_modules //! Get the boot module registry. //! //! @returns The boot module registry. - auto get_boot_module_registry() -> boot_module_registry &; + auto get_boot_module_registry() -> boot_module_registry const &; } // namespace kapi::boot_modules #endif \ No newline at end of file -- cgit v1.2.3 From 3b2f36d242eb895fd893ec7a674ff608f44f69ac Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 16 May 2026 16:12:36 +0200 Subject: refactoring --- kapi/kapi/filesystem.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'kapi') diff --git a/kapi/kapi/filesystem.hpp b/kapi/kapi/filesystem.hpp index 94d42ce..fdaed73 100644 --- a/kapi/kapi/filesystem.hpp +++ b/kapi/kapi/filesystem.hpp @@ -23,7 +23,7 @@ namespace kapi::filesystem @return 0 on success, -1 on failure. @qualifier kernel-defined */ - auto mount(std::string_view source, std::string_view target) -> int; + auto mount(std::string_view source, std::string_view target) -> ssize_t; /** @brief Unmounts a filesystem from the specified @p target path. @@ -31,7 +31,7 @@ namespace kapi::filesystem @return 0 on success, -1 on failure. @qualifier kernel-defined */ - auto umount(std::string_view target) -> int; + auto umount(std::string_view target) -> ssize_t; /** @brief Opens a file at the specified @p path. @@ -39,7 +39,7 @@ namespace kapi::filesystem @return A file descriptor on success, -1 on failure. @qualifier kernel-defined */ - auto open(std::string_view path) -> int; + auto open(std::string_view path) -> ssize_t; /** @brief Closes a @p file_descriptor. @@ -47,7 +47,7 @@ namespace kapi::filesystem @return 0 on success, -1 on failure. @qualifier kernel-defined */ - auto close(int file_descriptor) -> int; + auto close(size_t file_descriptor) -> ssize_t; /** @brief Reads @p size bytes into @p buffer from a @p file_descriptor. @@ -57,7 +57,7 @@ namespace kapi::filesystem @return The number of bytes read on success, -1 on failure. @qualifier kernel-defined */ - auto read(int file_descriptor, void * buffer, size_t size) -> ssize_t; + auto read(size_t file_descriptor, void * buffer, size_t size) -> ssize_t; /** @brief Writes @p size bytes from @p buffer to a @p file_descriptor. @@ -67,7 +67,7 @@ namespace kapi::filesystem @return The number of bytes written on success, -1 on failure. @qualifier kernel-defined */ - auto write(int file_descriptor, void const * buffer, size_t size) -> ssize_t; + auto write(size_t file_descriptor, void const * buffer, size_t size) -> ssize_t; } // namespace kapi::filesystem #endif // TEACHOS_KAPI_FILESYSTEM_HPP \ No newline at end of file -- cgit v1.2.3 From 2063d3e165a1b92a46c73badf56927228ed4d5e8 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 25 May 2026 10:15:21 +0200 Subject: Refactor ssize_t --- kapi/kapi/filesystem.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'kapi') diff --git a/kapi/kapi/filesystem.hpp b/kapi/kapi/filesystem.hpp index fdaed73..3bd9aaf 100644 --- a/kapi/kapi/filesystem.hpp +++ b/kapi/kapi/filesystem.hpp @@ -1,11 +1,11 @@ #ifndef TEACHOS_KAPI_FILESYSTEM_HPP #define TEACHOS_KAPI_FILESYSTEM_HPP +#include + #include #include -#include - namespace kapi::filesystem { /** @@ -23,7 +23,7 @@ namespace kapi::filesystem @return 0 on success, -1 on failure. @qualifier kernel-defined */ - auto mount(std::string_view source, std::string_view target) -> ssize_t; + auto mount(std::string_view source, std::string_view target) -> kstd::ssize_t; /** @brief Unmounts a filesystem from the specified @p target path. @@ -31,7 +31,7 @@ namespace kapi::filesystem @return 0 on success, -1 on failure. @qualifier kernel-defined */ - auto umount(std::string_view target) -> ssize_t; + auto umount(std::string_view target) -> kstd::ssize_t; /** @brief Opens a file at the specified @p path. @@ -39,7 +39,7 @@ namespace kapi::filesystem @return A file descriptor on success, -1 on failure. @qualifier kernel-defined */ - auto open(std::string_view path) -> ssize_t; + auto open(std::string_view path) -> kstd::ssize_t; /** @brief Closes a @p file_descriptor. @@ -47,7 +47,7 @@ namespace kapi::filesystem @return 0 on success, -1 on failure. @qualifier kernel-defined */ - auto close(size_t file_descriptor) -> ssize_t; + auto close(size_t file_descriptor) -> kstd::ssize_t; /** @brief Reads @p size bytes into @p buffer from a @p file_descriptor. @@ -57,7 +57,7 @@ namespace kapi::filesystem @return The number of bytes read on success, -1 on failure. @qualifier kernel-defined */ - auto read(size_t file_descriptor, void * buffer, size_t size) -> ssize_t; + auto read(size_t file_descriptor, void * buffer, size_t size) -> kstd::ssize_t; /** @brief Writes @p size bytes from @p buffer to a @p file_descriptor. @@ -67,7 +67,7 @@ namespace kapi::filesystem @return The number of bytes written on success, -1 on failure. @qualifier kernel-defined */ - auto write(size_t file_descriptor, void const * buffer, size_t size) -> ssize_t; + auto write(size_t file_descriptor, void const * buffer, size_t size) -> kstd::ssize_t; } // namespace kapi::filesystem #endif // TEACHOS_KAPI_FILESYSTEM_HPP \ No newline at end of file -- cgit v1.2.3