aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/arch/boot/boot.hpp4
-rw-r--r--arch/x86_64/arch/cpu/global_descriptor_table.hpp2
-rw-r--r--arch/x86_64/arch/cpu/initialization.cpp6
-rw-r--r--arch/x86_64/arch/cpu/interrupts.cpp14
-rw-r--r--arch/x86_64/arch/devices/init.cpp10
-rw-r--r--arch/x86_64/arch/drivers/cpu/lapic.cpp5
-rw-r--r--arch/x86_64/arch/memory/higher_half_mapper.cpp15
-rw-r--r--arch/x86_64/arch/memory/higher_half_mapper.hpp10
-rw-r--r--arch/x86_64/arch/memory/kernel_mapper.cpp3
-rw-r--r--arch/x86_64/arch/memory/kernel_mapper.hpp6
-rw-r--r--arch/x86_64/arch/memory/page_utilities.hpp7
-rw-r--r--arch/x86_64/arch/memory/region_allocator.hpp7
-rw-r--r--arch/x86_64/arch/vga/text/buffer.cpp6
-rw-r--r--arch/x86_64/arch/vga/text/buffer.hpp4
-rw-r--r--arch/x86_64/arch/vga/text/device.cpp10
-rw-r--r--arch/x86_64/kapi/memory.cpp12
-rw-r--r--kapi/kapi/memory.hpp8
-rw-r--r--kapi/kapi/memory/address.hpp24
-rw-r--r--kapi/kapi/memory/page_mapper.hpp5
-rw-r--r--kernel/kapi/memory.cpp10
-rw-r--r--kernel/kernel/test_support/page_mapper.cpp5
-rw-r--r--kernel/kernel/test_support/page_mapper.hpp3
-rw-r--r--kernel/kernel/test_support/simulated_memory.cpp19
-rw-r--r--kernel/kernel/test_support/simulated_memory.hpp11
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