diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-09-10 08:53:57 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-09-10 08:53:57 +0200 |
| commit | 5449acc193f96d2ffaeb224aad5cea16bf753cdb (patch) | |
| tree | 2a939bc19d7f7f365800e2d275d3cc85a7bcbe54 | |
| parent | da6cf94fc47f38cab580e9df1c6e6a46894aded5 (diff) | |
| download | kernel-5449acc193f96d2ffaeb224aad5cea16bf753cdb.tar.xz kernel-5449acc193f96d2ffaeb224aad5cea16bf753cdb.zip | |
x86_64: replace raw pointers with observer_ptr
24 files changed, 133 insertions, 73 deletions
diff --git a/arch/x86_64/arch/boot/boot.hpp b/arch/x86_64/arch/boot/boot.hpp index c790152c..566d1486 100644 --- a/arch/x86_64/arch/boot/boot.hpp +++ b/arch/x86_64/arch/boot/boot.hpp @@ -33,6 +33,8 @@ #include <kapi/boot.hpp> // IWYU pragma: export +#include <kstd/memory.hpp> + #include <multiboot2/information.hpp> #include <cstddef> @@ -43,7 +45,7 @@ namespace kapi::boot struct information { //! A pointer to the loader provided Multiboot2 Information structure. - multiboot2::information_view const * mbi; + kstd::observer_ptr<multiboot2::information_view const> mbi; //! The index of the next character to be written in the VGA text buffer after handoff. std::size_t vga_buffer_index; diff --git a/arch/x86_64/arch/cpu/global_descriptor_table.hpp b/arch/x86_64/arch/cpu/global_descriptor_table.hpp index 0bd7677d..34aac3e0 100644 --- a/arch/x86_64/arch/cpu/global_descriptor_table.hpp +++ b/arch/x86_64/arch/cpu/global_descriptor_table.hpp @@ -46,7 +46,7 @@ namespace arch::cpu : m_descriptors{} { auto descriptor_data = std::array{ - std::pair{std::bit_cast<std::byte const *>(&descriptors), sizeof(descriptors)} + std::pair{reinterpret_cast<std::byte const *>(&descriptors), sizeof(descriptors)} ... }; auto written_size = 0uz; diff --git a/arch/x86_64/arch/cpu/initialization.cpp b/arch/x86_64/arch/cpu/initialization.cpp index be1cc9f8..cae40d38 100644 --- a/arch/x86_64/arch/cpu/initialization.cpp +++ b/arch/x86_64/arch/cpu/initialization.cpp @@ -88,9 +88,9 @@ namespace arch::cpu .base_high = 0, }; - constexpr auto make_tss_descriptor(task_state_segment const * tss_ptr) -> system_segment_descriptor + constexpr auto make_tss_descriptor(task_state_segment const & tss) -> system_segment_descriptor { - auto const address = std::bit_cast<std::uintptr_t>(tss_ptr); + auto const address = std::bit_cast<std::uintptr_t>(&tss); auto const limit = sizeof(task_state_segment) - 1; return system_segment_descriptor{ @@ -134,7 +134,7 @@ namespace arch::cpu auto initialize_descriptors() -> void { - auto static tss_descriptor = make_tss_descriptor(&tss); + auto static tss_descriptor = make_tss_descriptor(tss); auto static gdt = global_descriptor_table{ gdt_null_descriptor, gdt_kernel_code_descriptor, gdt_kernel_data_descriptor, diff --git a/arch/x86_64/arch/cpu/interrupts.cpp b/arch/x86_64/arch/cpu/interrupts.cpp index f27c3a2e..2b166306 100644 --- a/arch/x86_64/arch/cpu/interrupts.cpp +++ b/arch/x86_64/arch/cpu/interrupts.cpp @@ -8,6 +8,7 @@ #include <kapi/memory.hpp> #include <kapi/system.hpp> +#include <kstd/memory.hpp> #include <kstd/print.hpp> #include <kstd/units.hpp> @@ -100,7 +101,7 @@ namespace arch::cpu } } - auto dispatch_exception(interrupt_frame * frame) -> bool + auto dispatch_exception(kstd::observer_ptr<interrupt_frame const> frame) -> bool { auto type = to_exception_type(static_cast<exception>(frame->interrupt.number)); auto fault_address = kapi::memory::linear_address{}; @@ -122,7 +123,7 @@ namespace arch::cpu } } - auto acknowledge_pic_interrupt(interrupt_frame * frame) -> void + auto acknowledge_pic_interrupt(kstd::observer_ptr<interrupt_frame const> frame) -> void { if (frame->interrupt.number >= pic_slave_irq_start) { @@ -131,7 +132,7 @@ namespace arch::cpu pic_master_control_port::write(pic_end_of_interrupt); } - auto handle_double_fault(interrupt_frame * frame) -> void + auto handle_double_fault(kstd::observer_ptr<interrupt_frame const> frame) -> void { auto const rsp = frame->cpu_saved.rsp; auto const rip = frame->cpu_saved.rip; @@ -162,17 +163,18 @@ namespace arch::cpu { extern std::uintptr_t const isr_stub_table[256]; + // Note: this function receives a plain pointer because it is called from the assembly ISR stub. auto interrupt_dispatch(interrupt_frame * frame) -> void { auto [number, code] = frame->interrupt; if (number == static_cast<std::uint64_t>(exception::double_fault)) { - handle_double_fault(frame); + handle_double_fault(kstd::make_observer(frame)); } else if (number < number_of_exception_vectors) { - if (!dispatch_exception(frame)) + if (!dispatch_exception(kstd::make_observer(frame))) { if (has_error_code(static_cast<exception>(number))) { @@ -194,7 +196,7 @@ namespace arch::cpu kstd::println(kstd::print_sink::stderr, "[ARCH:CPU] Unhandled interrupt {:#04x} (IRQ{})", number, irq_number); } - acknowledge_pic_interrupt(frame); + acknowledge_pic_interrupt(kstd::make_observer(frame)); } } } diff --git a/arch/x86_64/arch/devices/init.cpp b/arch/x86_64/arch/devices/init.cpp index 639e8870..830c6d0a 100644 --- a/arch/x86_64/arch/devices/init.cpp +++ b/arch/x86_64/arch/devices/init.cpp @@ -12,6 +12,8 @@ #include <kstd/memory.hpp> #include <kstd/print.hpp> +#include <cstddef> + namespace arch::devices { @@ -21,21 +23,21 @@ namespace arch::devices auto get_acpi_root_pointer() -> kstd::observer_ptr<::acpi::rsdp const> { auto const & mbi = kapi::boot::bootstrap_information.mbi; - auto system_description_pointer = static_cast<::acpi::rsdp const *>(nullptr); + auto system_description_pointer = kstd::observer_ptr<std::byte const>(nullptr); if (auto const & xsdp = mbi->maybe_acpi_xsdp()) { auto data = xsdp->pointer().data(); - system_description_pointer = reinterpret_cast<::acpi::xsdp const *>(data); + system_description_pointer = kstd::make_observer(data); } else if (auto const & rsdp = mbi->maybe_acpi_rsdp()) { auto data = rsdp->pointer().data(); - system_description_pointer = reinterpret_cast<::acpi::rsdp const *>(data); + system_description_pointer = kstd::make_observer(data); } - return kstd::make_observer(system_description_pointer); + return kstd::observer_ptr(reinterpret_cast<::acpi::rsdp const *>(system_description_pointer.get())); } } // namespace diff --git a/arch/x86_64/arch/drivers/cpu/lapic.cpp b/arch/x86_64/arch/drivers/cpu/lapic.cpp index 3b7c2d45..5cc62d4c 100644 --- a/arch/x86_64/arch/drivers/cpu/lapic.cpp +++ b/arch/x86_64/arch/drivers/cpu/lapic.cpp @@ -162,13 +162,14 @@ namespace arch::drivers::cpu auto lapic::read_register(registers id) const -> std::uint32_t { - auto reg = static_cast<std::uint32_t volatile *>(m_mapped_region.first + std::to_underlying(id)); + auto reg = + static_cast<kstd::observer_ptr<std::uint32_t volatile const>>(m_mapped_region.first + std::to_underlying(id)); return *reg; } auto lapic::write_register(registers id, std::uint32_t value) -> void { - auto reg = static_cast<std::uint32_t volatile *>(m_mapped_region.first + std::to_underlying(id)); + auto reg = static_cast<kstd::observer_ptr<std::uint32_t volatile>>(m_mapped_region.first + std::to_underlying(id)); *reg = value; } diff --git a/arch/x86_64/arch/memory/higher_half_mapper.cpp b/arch/x86_64/arch/memory/higher_half_mapper.cpp index 974b00a0..8a069c86 100644 --- a/arch/x86_64/arch/memory/higher_half_mapper.cpp +++ b/arch/x86_64/arch/memory/higher_half_mapper.cpp @@ -6,6 +6,8 @@ #include <kapi/memory.hpp> #include <kapi/system.hpp> +#include <kstd/memory.hpp> + #include <algorithm> #include <array> #include <cstddef> @@ -16,11 +18,12 @@ namespace arch::memory { - higher_half_mapper::higher_half_mapper(page_table * root) + higher_half_mapper::higher_half_mapper(kstd::observer_ptr<page_table> root) : m_root{root} {} - auto higher_half_mapper::map(kapi::memory::page page, kapi::memory::frame frame, flags flags) -> std::byte * + auto higher_half_mapper::map(kapi::memory::page page, kapi::memory::frame frame, flags flags) + -> kstd::observer_ptr<std::byte> { auto table = get_or_create_page_table(page); if (!table) @@ -38,7 +41,7 @@ namespace arch::memory entry.frame(frame, to_table_flags(flags) | page_table::entry::flags::present); - return static_cast<std::byte *>(page.start_address()); + return static_cast<kstd::observer_ptr<std::byte>>(page.start_address()); } auto higher_half_mapper::unmap(kapi::memory::page page) -> void @@ -51,7 +54,7 @@ namespace arch::memory auto higher_half_mapper::try_unmap(kapi::memory::page page) noexcept -> bool { - auto table_path = std::array<std::pair<page_table *, std::size_t>, 4>{}; + auto table_path = std::array<std::pair<kstd::observer_ptr<page_table>, std::size_t>, 4>{}; table_path[0] = std::pair{m_root, pml_index(4, page)}; for (auto level = 4uz; level > 1uz; --level) @@ -85,7 +88,7 @@ namespace arch::memory return true; } - auto higher_half_mapper::get_or_create_page_table(kapi::memory::page page) noexcept -> page_table * + auto higher_half_mapper::get_or_create_page_table(kapi::memory::page page) noexcept -> kstd::observer_ptr<page_table> { auto table = m_root; @@ -103,7 +106,7 @@ namespace arch::memory } auto new_table = to_higher_half_pointer<page_table>(table_frame->start_address()); - std::construct_at(new_table); + std::construct_at(new_table.get()); auto const flags = page_table::entry::flags::present | page_table::entry::flags::writable | page_table::entry::flags::user_accessible; diff --git a/arch/x86_64/arch/memory/higher_half_mapper.hpp b/arch/x86_64/arch/memory/higher_half_mapper.hpp index 4f6574ff..45ff100a 100644 --- a/arch/x86_64/arch/memory/higher_half_mapper.hpp +++ b/arch/x86_64/arch/memory/higher_half_mapper.hpp @@ -5,6 +5,8 @@ #include <kapi/memory.hpp> +#include <kstd/memory.hpp> + #include <cstddef> namespace arch::memory @@ -16,10 +18,10 @@ namespace arch::memory //! Construct a new mapper for a hierarchy rooted in the given PML. //! //! @param root The root of the hierarchy to operate on. - explicit higher_half_mapper(page_table * root); + explicit higher_half_mapper(kstd::observer_ptr<page_table> root); //! @copydoc kapi::memory::page_mapper::map - auto map(kapi::memory::page page, kapi::memory::frame frame, flags flags) -> std::byte * override; + auto map(kapi::memory::page page, kapi::memory::frame frame, flags flags) -> kstd::observer_ptr<std::byte> override; //! @copydoc kapi::memory::page_mapper::unmap auto unmap(kapi::memory::page page) -> void override; @@ -34,9 +36,9 @@ namespace arch::memory //! //! @param page The page to get the PML1 for. //! @return The PML1 that manages the given page, nullptr it the system runs out of memory. - auto get_or_create_page_table(kapi::memory::page page) noexcept -> page_table *; + auto get_or_create_page_table(kapi::memory::page page) noexcept -> kstd::observer_ptr<page_table>; - page_table * m_root; + kstd::observer_ptr<page_table> m_root; }; } // namespace arch::memory diff --git a/arch/x86_64/arch/memory/kernel_mapper.cpp b/arch/x86_64/arch/memory/kernel_mapper.cpp index 070a7866..7d9d9bb5 100644 --- a/arch/x86_64/arch/memory/kernel_mapper.cpp +++ b/arch/x86_64/arch/memory/kernel_mapper.cpp @@ -8,6 +8,7 @@ #include <elf/format.hpp> #include <elf/section_header.hpp> +#include <kstd/memory.hpp> #include <kstd/print.hpp> #include <kstd/units.hpp> @@ -40,7 +41,7 @@ namespace arch::memory } // namespace - kernel_mapper::kernel_mapper(multiboot2::information_view const * mbi) + kernel_mapper::kernel_mapper(kstd::observer_ptr<multiboot2::information_view const> mbi) : m_mbi{std::move(mbi)} , m_kernel_load_base{std::bit_cast<std::uintptr_t>(&arch::boot::TEACHOS_VMA)} {} diff --git a/arch/x86_64/arch/memory/kernel_mapper.hpp b/arch/x86_64/arch/memory/kernel_mapper.hpp index aeb936dc..2adf8fd9 100644 --- a/arch/x86_64/arch/memory/kernel_mapper.hpp +++ b/arch/x86_64/arch/memory/kernel_mapper.hpp @@ -6,6 +6,8 @@ #include <elf/format.hpp> #include <elf/section_header.hpp> +#include <kstd/memory.hpp> + #include <multiboot2/information.hpp> #include <cstdint> @@ -18,7 +20,7 @@ namespace arch::memory { using section_header_type = elf::section_header<elf::format::elf64>; - explicit kernel_mapper(multiboot2::information_view const * mbi); + explicit kernel_mapper(kstd::observer_ptr<multiboot2::information_view const> mbi); auto remap_kernel(kapi::memory::page_mapper & mapper) -> void; @@ -26,7 +28,7 @@ namespace arch::memory auto map_section(section_header_type const & section, std::string_view name, kapi::memory::page_mapper & mapper) -> void; - multiboot2::information_view const * m_mbi; + kstd::observer_ptr<multiboot2::information_view const> m_mbi; std::uintptr_t m_kernel_load_base; }; diff --git a/arch/x86_64/arch/memory/page_utilities.hpp b/arch/x86_64/arch/memory/page_utilities.hpp index 478f776d..cf334cf8 100644 --- a/arch/x86_64/arch/memory/page_utilities.hpp +++ b/arch/x86_64/arch/memory/page_utilities.hpp @@ -3,6 +3,8 @@ #include <kapi/memory.hpp> +#include <kstd/memory.hpp> + #include <cstddef> namespace arch::memory @@ -17,11 +19,12 @@ namespace arch::memory } template<typename ValueType = void> - [[nodiscard]] constexpr auto to_higher_half_pointer(kapi::memory::physical_address address) -> ValueType * + [[nodiscard]] constexpr auto to_higher_half_pointer(kapi::memory::physical_address address) + -> kstd::observer_ptr<ValueType> { using namespace kapi::memory; auto const higher_half_address = higher_half_direct_map_base + address.raw(); - return static_cast<ValueType *>(higher_half_address); + return static_cast<kstd::observer_ptr<ValueType>>(higher_half_address); } } // namespace arch::memory diff --git a/arch/x86_64/arch/memory/region_allocator.hpp b/arch/x86_64/arch/memory/region_allocator.hpp index 61cc1d4d..be3c32bb 100644 --- a/arch/x86_64/arch/memory/region_allocator.hpp +++ b/arch/x86_64/arch/memory/region_allocator.hpp @@ -5,6 +5,8 @@ #include <kapi/memory/frame.hpp> #include <kapi/memory/frame_allocator.hpp> +#include <kstd/memory.hpp> + #include <multiboot2/information.hpp> #include <cstddef> @@ -46,7 +48,7 @@ namespace arch::memory //! The loader supplied Multiboot2 information structure. //! //! This is used to query boot module ranges so these frames can be excluded from early allocations. - multiboot2::information_view const * mbi; + kstd::observer_ptr<multiboot2::information_view const> mbi; }; using region = multiboot2::memory_map::region; @@ -85,7 +87,8 @@ namespace arch::memory kapi::memory::frame m_kernel_end; //!< The end of the kernel image in physical memory. kapi::memory::frame m_multiboot_start; //!< The start of the Multiboot2 information in physical memory. kapi::memory::frame m_multiboot_end; //!< The end of the Multiboot2 information in physical memory. - multiboot2::information_view const * m_multiboot_information; //!< Source of Multiboot2 module ranges. + kstd::observer_ptr<multiboot2::information_view const> + m_multiboot_information; //!< Source of Multiboot2 module ranges. }; } // namespace arch::memory diff --git a/arch/x86_64/arch/vga/text/buffer.cpp b/arch/x86_64/arch/vga/text/buffer.cpp index 498b9a39..3557777b 100644 --- a/arch/x86_64/arch/vga/text/buffer.cpp +++ b/arch/x86_64/arch/vga/text/buffer.cpp @@ -2,6 +2,8 @@ #include <arch/vga/text/attribute.hpp> +#include <kstd/memory.hpp> + #include <algorithm> #include <bit> #include <cstddef> @@ -11,10 +13,10 @@ namespace arch::vga::text { - buffer::buffer(std::size_t width, std::size_t height, cell * start, std::size_t position) + buffer::buffer(std::size_t width, std::size_t height, kstd::observer_ptr<cell> start, std::size_t position) : m_width{width} , m_height{height} - , m_buffer{start, m_width * m_height} + , m_buffer{start.get(), m_width * m_height} , m_position{position} {} diff --git a/arch/x86_64/arch/vga/text/buffer.hpp b/arch/x86_64/arch/vga/text/buffer.hpp index 7827b1af..15dbcb0f 100644 --- a/arch/x86_64/arch/vga/text/buffer.hpp +++ b/arch/x86_64/arch/vga/text/buffer.hpp @@ -5,6 +5,8 @@ #include <arch/vga/text/attribute.hpp> +#include <kstd/memory.hpp> + #include <cstddef> #include <span> #include <string_view> @@ -29,7 +31,7 @@ namespace arch::vga::text //! @param height The height of the buffer //! @param start A pointer to the first byte of the buffer. //! @param position The starting position for the first write to the buffer - buffer(std::size_t width, std::size_t height, cell * start, std::size_t position = 0); + buffer(std::size_t width, std::size_t height, kstd::observer_ptr<cell> start, std::size_t position = 0); //! Clear the buffer. //! diff --git a/arch/x86_64/arch/vga/text/device.cpp b/arch/x86_64/arch/vga/text/device.cpp index 84683585..e7140e43 100644 --- a/arch/x86_64/arch/vga/text/device.cpp +++ b/arch/x86_64/arch/vga/text/device.cpp @@ -5,6 +5,8 @@ #include <kapi/cio.hpp> +#include <kstd/memory.hpp> + #include <bit> #include <cstddef> #include <cstdint> @@ -22,10 +24,10 @@ namespace arch::vga::text } // namespace device::device() - : m_buffer{ - default_buffer_width, default_buffer_height, - std::bit_cast<buffer::cell *>(default_buffer_address + std::bit_cast<std::uintptr_t>(&boot::TEACHOS_VMA)), - kapi::boot::bootstrap_information.vga_buffer_index} + : m_buffer{default_buffer_width, default_buffer_height, + kstd::observer_ptr{reinterpret_cast<buffer::cell *>( + default_buffer_address + std::bit_cast<std::uintptr_t>(&boot::TEACHOS_VMA))}, + kapi::boot::bootstrap_information.vga_buffer_index} { clear(); } diff --git a/arch/x86_64/kapi/memory.cpp b/arch/x86_64/kapi/memory.cpp index 03c5107c..307789cd 100644 --- a/arch/x86_64/kapi/memory.cpp +++ b/arch/x86_64/kapi/memory.cpp @@ -12,6 +12,7 @@ #include <kapi/boot.hpp> #include <kapi/system.hpp> +#include <kstd/memory.hpp> #include <kstd/print.hpp> #include <kstd/units.hpp> @@ -49,7 +50,7 @@ namespace kapi::memory } auto const & mbi = boot::bootstrap_information.mbi; - auto mbi_span = std::span{std::bit_cast<std::byte *>(mbi), static_cast<std::size_t>(mbi->size())}; + auto mbi_span = std::span{reinterpret_cast<std::byte const *>(mbi.get()), static_cast<std::size_t>(mbi->size())}; auto image_span = std::span{&arch::boot::_start_physical, &arch::boot::_end_physical}; return arch::memory::region_allocator::memory_information{ @@ -62,6 +63,9 @@ namespace kapi::memory auto establish_higher_half_direct_mapping() -> void { + // We can't use an observer_ptr here, since this first frame allocation is very likely to return frame number + // zero, which has a starting address of zero. observer_ptr will interpret this as being a nullptr and raise a + // panic on dereference. auto pml3_frame = kapi::memory::allocate_frame(); auto pml3 = static_cast<arch::memory::page_table *>(pml3_frame->start_address()); pml3->clear(); @@ -75,7 +79,7 @@ namespace kapi::memory }); auto current_cr3 = arch::cpu::cr3::read(); - auto pml4 = static_cast<arch::memory::page_table *>(current_cr3.address()); + auto pml4 = static_cast<kstd::observer_ptr<arch::memory::page_table>>(current_cr3.address()); (*pml4)[256].frame(*pml3_frame, arch::memory::page_table::entry::flags::present | arch::memory::page_table::entry::flags::writable | arch::memory::page_table::entry::flags::global); @@ -218,7 +222,7 @@ namespace kapi::memory system::panic("[ARCH:MEM] Failed to allocate new PML4!"); } auto new_pml4 = arch::memory::to_higher_half_pointer<arch::memory::page_table>(new_pml4_frame->start_address()); - std::construct_at(new_pml4); + std::construct_at(new_pml4.get()); higher_half_mapper.emplace(new_pml4); set_page_mapper(*higher_half_mapper); @@ -229,7 +233,7 @@ namespace kapi::memory remap_bootloader_modules(*higher_half_mapper); auto current_cr3 = arch::cpu::cr3::read(); - auto old_pml4 = static_cast<arch::memory::page_table *>(current_cr3.address()); + auto old_pml4 = static_cast<kstd::observer_ptr<arch::memory::page_table>>(current_cr3.address()); (*new_pml4)[256] = (*old_pml4)[256]; kstd::println("[ARCH:MEM] Switching to new paging hierarchy."); diff --git a/kapi/kapi/memory.hpp b/kapi/kapi/memory.hpp index 8ad8d6ec..4b14b553 100644 --- a/kapi/kapi/memory.hpp +++ b/kapi/kapi/memory.hpp @@ -9,6 +9,8 @@ #include <kapi/memory/page.hpp> // IWYU pragma: export #include <kapi/memory/page_mapper.hpp> // IWYU pragma: export +#include <kstd/memory.hpp> + #include <cstddef> #include <optional> #include <utility> @@ -72,7 +74,8 @@ namespace kapi::memory //! @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 *; + auto map(page page, frame frame, page_mapper::flags flags = page_mapper::flags::empty) + -> kstd::observer_ptr<std::byte>; //! Unmap a page. //! @@ -103,7 +106,8 @@ namespace kapi::memory //! @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 *; + auto map_mmio_region(mmio_region region, physical_address hw_base, page_mapper::flags flags = {}) + -> kstd::observer_ptr<std::byte>; //! Release a Memory-mapped I/O region. //! diff --git a/kapi/kapi/memory/address.hpp b/kapi/kapi/memory/address.hpp index 5b84a381..0fab06e0 100644 --- a/kapi/kapi/memory/address.hpp +++ b/kapi/kapi/memory/address.hpp @@ -4,6 +4,7 @@ // IWYU pragma: private, include <kapi/memory.hpp> #include <kstd/format.hpp> +#include <kstd/memory.hpp> #include <kstd/units.hpp> #include <bit> @@ -47,13 +48,20 @@ namespace kapi::memory //! Construct an address representing the given pointer value. //! //! @param pointer The pointer value to initialize this address with. - explicit address(std::byte * pointer) noexcept - : m_value{std::bit_cast<std::uintptr_t>(pointer)} + explicit address(std::byte const * pointer) noexcept + : m_value{reinterpret_cast<std::uintptr_t>(pointer)} + {} + + //! Construct an address representing the given pointer value. + //! + //! @param pointer The pointer value to initialize this address with. + explicit address(kstd::observer_ptr<std::byte const> pointer) noexcept + : m_value{reinterpret_cast<std::uintptr_t>(pointer.get())} {} //! Convert this address into a C++ pointer. //! - //! @tparam T The type of the object this address should refer to. + //! @tparam ObjectType The type of the object the pointer should refer to. //! @return This address as a typed pointer to the given type. template<typename ObjectType> explicit operator ObjectType *() const noexcept @@ -61,6 +69,16 @@ namespace kapi::memory return std::bit_cast<ObjectType *>(m_value); } + //! Convert this address into an observer pointer. + //! + //! @tparam ObjectType The type of the object the pointer should refer to. + //! @return An observer pointer pointing to the memory location represented by this address. + template<typename ObjectType> + explicit operator kstd::observer_ptr<ObjectType>() const noexcept + { + return kstd::make_observer(reinterpret_cast<ObjectType *>(m_value)); + } + //! Create a new address n beyond this one. //! //! @param n The amount to add to this address. diff --git a/kapi/kapi/memory/page_mapper.hpp b/kapi/kapi/memory/page_mapper.hpp index 3deb4702..a310e209 100644 --- a/kapi/kapi/memory/page_mapper.hpp +++ b/kapi/kapi/memory/page_mapper.hpp @@ -7,6 +7,7 @@ #include <kapi/memory/page.hpp> #include <kstd/bitfield_enum.hpp> +#include <kstd/memory.hpp> #include <cstddef> #include <cstdint> @@ -45,7 +46,7 @@ namespace kapi::memory //! @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; + virtual auto map(page page, frame frame, flags flags) -> kstd::observer_ptr<std::byte> = 0; //! Unmap the given page. //! @@ -70,7 +71,7 @@ namespace kapi::memory //! @param flags The flags to map the page with. //! @return A pointer to the first T in the page. template<typename T> - [[nodiscard]] auto map_as(page page, frame frame, flags flags) -> T * + [[nodiscard]] auto map_as(page page, frame frame, flags flags) -> kstd::observer_ptr<T> { return std::bit_cast<T *>(map(page, frame, flags)); } diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp index 1c6fa2c8..7a9f7249 100644 --- a/kernel/kapi/memory.cpp +++ b/kernel/kapi/memory.cpp @@ -5,6 +5,7 @@ #include <kapi/system.hpp> +#include <kstd/memory.hpp> #include <kstd/print.hpp> #include <kstd/units.hpp> @@ -45,7 +46,7 @@ namespace kapi::memory { bad_page_mapper static instance; - auto map(page, frame, flags) -> std::byte * override + auto map(page, frame, flags) -> kstd::observer_ptr<std::byte> override { system::panic("[OS:MEM] Tried to map a page without an active mapper."); } @@ -103,7 +104,7 @@ namespace kapi::memory return get_frame_allocator().allocate_many(count); } - auto map(page page, frame frame, page_mapper::flags flags) -> std::byte * + auto map(page page, frame frame, page_mapper::flags flags) -> kstd::observer_ptr<std::byte> { return active_page_mapper->map(page, frame, flags); } @@ -135,7 +136,7 @@ namespace kapi::memory auto mapped = active_page_mapper->map(page, frame, flags); if (!bitmap_ptr) { - bitmap_ptr = reinterpret_cast<std::uint64_t *>(mapped); + bitmap_ptr = reinterpret_cast<std::uint64_t *>(mapped.get()); } }); @@ -160,7 +161,8 @@ namespace kapi::memory return {region, page_count}; } - auto map_mmio_region(mmio_region region, 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) + -> kstd::observer_ptr<std::byte> { auto start_page = page::containing(region.first); auto start_frame = frame::containing(hw_base); diff --git a/kernel/kernel/test_support/page_mapper.cpp b/kernel/kernel/test_support/page_mapper.cpp index 3a0072b4..808e0810 100644 --- a/kernel/kernel/test_support/page_mapper.cpp +++ b/kernel/kernel/test_support/page_mapper.cpp @@ -2,6 +2,7 @@ #include <kapi/memory.hpp> +#include <kstd/memory.hpp> #include <kstd/units.hpp> #include <cstddef> @@ -15,7 +16,7 @@ namespace kernel::tests : memory{physical_size, virtual_size} {} - auto page_mapper::map(kapi::memory::page page, kapi::memory::frame frame, flags) -> std::byte * + auto page_mapper::map(kapi::memory::page page, kapi::memory::frame frame, flags) -> kstd::observer_ptr<std::byte> { auto result = page_mappings.insert({page.number(), frame}); if (!result.second) @@ -41,7 +42,7 @@ namespace kernel::tests else if (page_address >= kapi::memory::higher_half_direct_map_base) { auto offset = frame.number() * kapi::memory::frame::size; - return memory.physical_base() + offset; + return kstd::observer_ptr{memory.physical_base().get() + offset}; } return nullptr; diff --git a/kernel/kernel/test_support/page_mapper.hpp b/kernel/kernel/test_support/page_mapper.hpp index 09c07f13..c38eeaf3 100644 --- a/kernel/kernel/test_support/page_mapper.hpp +++ b/kernel/kernel/test_support/page_mapper.hpp @@ -5,6 +5,7 @@ #include <kapi/memory.hpp> +#include <kstd/memory.hpp> #include <kstd/units.hpp> #include <cstddef> @@ -27,7 +28,7 @@ namespace kernel::tests //! @throws std::invalid_argument if the page has already been mapped. //! @throws std::runtime_error if the page cannot be mapped. //! @throws std::runtime_error if the underlying simulated memory cannot map the page. - auto map(kapi::memory::page page, kapi::memory::frame frame, flags flags) -> std::byte * override; + auto map(kapi::memory::page page, kapi::memory::frame frame, flags flags) -> kstd::observer_ptr<std::byte> override; //! @copydoc kapi::memory::page_mapper::unmap //! diff --git a/kernel/kernel/test_support/simulated_memory.cpp b/kernel/kernel/test_support/simulated_memory.cpp index 7614816b..4255eed0 100644 --- a/kernel/kernel/test_support/simulated_memory.cpp +++ b/kernel/kernel/test_support/simulated_memory.cpp @@ -2,6 +2,7 @@ #include <kapi/memory.hpp> +#include <kstd/memory.hpp> #include <kstd/units.hpp> #include <cerrno> @@ -48,30 +49,30 @@ namespace kernel::tests throw std::runtime_error(error); } - m_physical_base = static_cast<std::byte *>(physical_storage); - m_virtual_base = static_cast<std::byte *>(virtual_pointer); + m_physical_base = kstd::make_observer<std::byte>(static_cast<std::byte *>(physical_storage)); + m_virtual_base = kstd::make_observer<std::byte>(static_cast<std::byte *>(virtual_pointer)); clear(); } simulated_memory::~simulated_memory() { - munmap(m_virtual_base, m_virtual_size.value); - munmap(m_physical_base, m_physical_size.value); + munmap(m_virtual_base.get(), m_virtual_size.value); + munmap(m_physical_base.get(), m_physical_size.value); close(m_descriptor); } auto simulated_memory::clear() -> void { - std::memset(m_physical_base, 0, m_physical_size.value); + std::memset(m_physical_base.get(), 0, m_physical_size.value); } - auto simulated_memory::physical_base() noexcept -> std::byte * + auto simulated_memory::physical_base() noexcept -> kstd::observer_ptr<std::byte> { return m_physical_base; } - auto simulated_memory::physical_base() const noexcept -> std::byte const * + auto simulated_memory::physical_base() const noexcept -> kstd::observer_ptr<std::byte const> { return m_physical_base; } @@ -91,7 +92,7 @@ namespace kernel::tests return m_virtual_size; } - auto simulated_memory::map(kstd::bytes size, std::byte * to, off_t offset) -> std::byte * + auto simulated_memory::map(kstd::bytes size, std::byte * to, off_t offset) -> kstd::observer_ptr<std::byte> { auto mapped_ptr = mmap(to, size.value, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, m_descriptor, offset); if (mapped_ptr == MAP_FAILED) @@ -100,7 +101,7 @@ namespace kernel::tests throw std::runtime_error(error); } - return static_cast<std::byte *>(mapped_ptr); + return kstd::observer_ptr{static_cast<std::byte *>(mapped_ptr)}; } } // namespace kernel::tests
\ No newline at end of file diff --git a/kernel/kernel/test_support/simulated_memory.hpp b/kernel/kernel/test_support/simulated_memory.hpp index e1046ef4..e6161437 100644 --- a/kernel/kernel/test_support/simulated_memory.hpp +++ b/kernel/kernel/test_support/simulated_memory.hpp @@ -3,6 +3,7 @@ #include <kapi/memory.hpp> +#include <kstd/memory.hpp> #include <kstd/units.hpp> #include <cstddef> @@ -32,10 +33,10 @@ namespace kernel::tests auto clear() -> void; //! Get the base address of the physical memory of this device. - [[nodiscard]] auto physical_base() noexcept -> std::byte *; + [[nodiscard]] auto physical_base() noexcept -> kstd::observer_ptr<std::byte>; //! Get the base address of the physical memory of this device. - [[nodiscard]] auto physical_base() const noexcept -> std::byte const *; + [[nodiscard]] auto physical_base() const noexcept -> kstd::observer_ptr<std::byte const>; //! Get the size of the physical memory of this device. [[nodiscard]] auto physical_size() const noexcept -> kstd::bytes; @@ -52,14 +53,14 @@ namespace kernel::tests //! @param to The base address of the virtual region. //! @param offset The offset into the physical memory to map. //! @return A pointer to the first byte of the mapped region. - [[nodiscard]] auto map(kstd::bytes size, std::byte * to, off_t offset) -> std::byte *; + [[nodiscard]] auto map(kstd::bytes size, std::byte * to, off_t offset) -> kstd::observer_ptr<std::byte>; private: int m_descriptor{}; kstd::bytes m_physical_size{0}; kstd::bytes m_virtual_size{0}; - std::byte * m_physical_base{nullptr}; - std::byte * m_virtual_base{nullptr}; + kstd::observer_ptr<std::byte> m_physical_base{nullptr}; + kstd::observer_ptr<std::byte> m_virtual_base{nullptr}; }; } // namespace kernel::tests |
