From 80ae75bf039820ecb332ae1ab86ef6ce4e2675e4 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 16 Mar 2026 10:38:54 +0100 Subject: kapi/memory: support additional address arithmetic --- arch/x86_64/include/arch/memory/page_table.hpp | 4 +- kapi/include/kapi/memory/address.hpp | 104 +++++++++++++++++++++++-- kapi/include/kapi/memory/chunk.hpp | 2 +- kernel/kapi/memory.cpp | 3 +- kernel/src/memory/block_list_allocator.cpp | 2 +- 5 files changed, 102 insertions(+), 13 deletions(-) diff --git a/arch/x86_64/include/arch/memory/page_table.hpp b/arch/x86_64/include/arch/memory/page_table.hpp index 003dbf3..778c201 100644 --- a/arch/x86_64/include/arch/memory/page_table.hpp +++ b/arch/x86_64/include/arch/memory/page_table.hpp @@ -189,9 +189,9 @@ namespace arch::memory -> std::optional requires(Level == 4) { - auto offset = address.raw() % kapi::memory::page::size; + auto offset = address % kapi::memory::page::size; return translate(kapi::memory::page::containing(address)).transform([offset](auto frame) -> auto { - return kapi::memory::physical_address{frame.start_address().raw() + offset}; + return frame.start_address() + offset; }); } diff --git a/kapi/include/kapi/memory/address.hpp b/kapi/include/kapi/memory/address.hpp index e5cf50b..3bef358 100644 --- a/kapi/include/kapi/memory/address.hpp +++ b/kapi/include/kapi/memory/address.hpp @@ -50,30 +50,120 @@ namespace kapi::memory {} //! Convert this address into a C++ pointer. - explicit operator std::byte *() const noexcept + //! + //! @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); + return std::bit_cast(m_value); } //! Create a new address n beyond this one. //! - //! @param n The amount to increase the address by. + //! @param n The amount to add to this address. //! @return A new address, n further than this one. - constexpr auto operator+(std::uintptr_t n) const noexcept -> address + [[nodiscard]] constexpr auto operator+(std::ptrdiff_t n) const noexcept -> address { return address{m_value + n}; } - //! Increase this address by a given amount. + //! Increment this address by a given amount. //! - //! @param n The amount to increase the address by. + //! @param n The amount to Increment the address by. //! @return A reference to this address. - constexpr auto operator+=(std::uintptr_t n) noexcept -> 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. diff --git a/kapi/include/kapi/memory/chunk.hpp b/kapi/include/kapi/memory/chunk.hpp index 3d90326..4529535 100644 --- a/kapi/include/kapi/memory/chunk.hpp +++ b/kapi/include/kapi/memory/chunk.hpp @@ -30,7 +30,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.raw() / size}; + return ChunkType{address / size}; } //! Get the start address of the chunk referenced by this handle. diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp index 767bcd7..b1fb616 100644 --- a/kernel/kapi/memory.cpp +++ b/kernel/kapi/memory.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include #include @@ -130,7 +129,7 @@ namespace kapi::memory active_page_mapper->map(page, frame, flags); }); - auto bitmap_ptr = std::bit_cast(pmm_metadata_base.raw()); + auto bitmap_ptr = static_cast(pmm_metadata_base); auto bitmap = std::span{bitmap_ptr, (bitmap_bytes + sizeof(std::uint64_t) - 1uz) / sizeof(std::uint64_t)}; allocator.emplace(bitmap, frame_count); diff --git a/kernel/src/memory/block_list_allocator.cpp b/kernel/src/memory/block_list_allocator.cpp index cc91304..06b4581 100644 --- a/kernel/src/memory/block_list_allocator.cpp +++ b/kernel/src/memory/block_list_allocator.cpp @@ -108,7 +108,7 @@ namespace kernel::memory kapi::memory::map(page, *frame, flags); } - auto block = std::bit_cast(m_frontier.raw()); + auto block = static_cast(m_frontier); std::construct_at(block, frames_needed * kapi::memory::frame::size - sizeof(block_header), true, nullptr, nullptr); m_frontier += frames_needed * kapi::memory::frame::size; -- cgit v1.2.3