diff options
| author | Marcel Braun <marcel.braun@ost.ch> | 2026-04-02 08:48:00 +0200 |
|---|---|---|
| committer | Marcel Braun <marcel.braun@ost.ch> | 2026-04-02 08:48:00 +0200 |
| commit | 0c01a95325b26151ff3c9a70142f5dc83ff7d53f (patch) | |
| tree | 9bf034f544ae773b653554a54edfce232f835754 /kernel/src/test_support/page_mapper.cpp | |
| parent | 022d3e872de9c5a6a52c67f74af13706552330c0 (diff) | |
| parent | 3eb680cf5bcef626505cac82820996d8db4170d7 (diff) | |
| download | teachos-0c01a95325b26151ff3c9a70142f5dc83ff7d53f.tar.xz teachos-0c01a95325b26151ff3c9a70142f5dc83ff7d53f.zip | |
Merge branch 'fmorgner/develop-SA-FS26/kernel-bht' into 'develop-BA-FS26'
Add experimental support for kernel tests
See merge request teachos/kernel!20
Diffstat (limited to 'kernel/src/test_support/page_mapper.cpp')
| -rw-r--r-- | kernel/src/test_support/page_mapper.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/kernel/src/test_support/page_mapper.cpp b/kernel/src/test_support/page_mapper.cpp new file mode 100644 index 0000000..abdcae5 --- /dev/null +++ b/kernel/src/test_support/page_mapper.cpp @@ -0,0 +1,78 @@ +#include "kernel/test_support/page_mapper.hpp" + +#include "kapi/memory.hpp" + +#include <kstd/units> + +#include <cstddef> +#include <format> +#include <stdexcept> +#include <sys/mman.h> + +namespace kernel::tests +{ + + page_mapper::page_mapper(kstd::units::bytes memory_size) + : memory{memory_size} + {} + + auto page_mapper::map(kapi::memory::page page, kapi::memory::frame frame, flags) -> std::byte * + { + auto result = page_mappings.insert({page.number(), frame}); + if (!result.second) + { + auto error = std::format("Page {} was already mapped!", page.number()); + throw std::invalid_argument{error}; + } + + auto page_address = page.start_address(); + auto sandbox_start = memory.heap_base(); + auto sandbox_end = sandbox_start + memory.heap_size(); + + if (page_address >= sandbox_start && page_address < sandbox_end) + { + auto virtual_target = static_cast<std::byte *>(page_address); + auto physical_offset = frame.number() * kapi::memory::frame::size; + auto mapped_ptr = mmap(virtual_target, kapi::memory::page::size.value, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_FIXED, memory.memory_descriptor(), physical_offset.value); + if (mapped_ptr == MAP_FAILED) + { + throw std::runtime_error("Failed to map page"); + } + + return static_cast<std::byte *>(mapped_ptr); + } + else if (page_address >= kapi::memory::mmio_base) + { + throw std::runtime_error("MMIO mapping not yet supported in testing!"); + } + else if (page_address >= kapi::memory::higher_half_direct_map_base) + { + auto offset = frame.number() * kapi::memory::frame::size; + return memory.ram_base() + offset; + } + + return nullptr; + } + + auto page_mapper::unmap(kapi::memory::page page) -> void + { + if (!try_unmap(page)) + { + auto error = std::format("Page {} was never mapped!", page.number()); + throw std::invalid_argument{error}; + } + } + + auto page_mapper::try_unmap(kapi::memory::page page) noexcept -> bool + { + if (page_mappings.contains(page.number())) + { + page_mappings.erase(page.number()); + return true; + } + + return false; + } + +} // namespace kernel::tests
\ No newline at end of file |
