aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-04-01 17:26:13 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-04-01 17:26:13 +0200
commitb078f2bf4726b5c62584cebd84107ac1028bb083 (patch)
tree944b7bff1e51b6f769e7b0d3eca93126e785a988 /kernel
parent1a22d810ff2772d6b4dba5b1eb27d21285668c6f (diff)
downloadteachos-b078f2bf4726b5c62584cebd84107ac1028bb083.tar.xz
teachos-b078f2bf4726b5c62584cebd84107ac1028bb083.zip
kernel/tests: clean up fake memory implementation
Diffstat (limited to 'kernel')
-rw-r--r--kernel/CMakeLists.txt1
-rw-r--r--kernel/include/kernel/tests/bump_frame_allocator.hpp32
-rw-r--r--kernel/include/kernel/tests/page_mapper.hpp33
-rw-r--r--kernel/include/kernel/tests/simulated_memory.hpp18
-rw-r--r--kernel/src/test_support/kapi/memory.cpp92
-rw-r--r--kernel/src/test_support/page_mapper.cpp57
-rw-r--r--kernel/src/test_support/simulated_memory.cpp31
7 files changed, 166 insertions, 98 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index ffd5156..4264441 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -94,6 +94,7 @@ else()
"src/test_support/kapi/interrupts.cpp"
"src/test_support/kapi/memory.cpp"
"src/test_support/log_buffer.cpp"
+ "src/test_support/page_mapper.cpp"
"src/test_support/simulated_memory.cpp"
"src/test_support/state_reset_listener.cpp"
)
diff --git a/kernel/include/kernel/tests/bump_frame_allocator.hpp b/kernel/include/kernel/tests/bump_frame_allocator.hpp
new file mode 100644
index 0000000..8344423
--- /dev/null
+++ b/kernel/include/kernel/tests/bump_frame_allocator.hpp
@@ -0,0 +1,32 @@
+#ifndef TEACHOS_KERNEL_TESTS_BUMP_FRAME_ALLOCATOR_HPP
+#define TEACHOS_KERNEL_TESTS_BUMP_FRAME_ALLOCATOR_HPP
+
+#include "kapi/memory.hpp"
+
+#include <cstddef>
+#include <optional>
+#include <utility>
+
+namespace kernel::tests
+{
+
+ struct bump_frame_allocator : kapi::memory::frame_allocator
+ {
+ auto mark_used(kapi::memory::frame) -> void override {}
+
+ auto allocate_many(std::size_t count) noexcept
+ -> std::optional<std::pair<kapi::memory::frame, std::size_t>> override
+ {
+ auto start = next_free_frame;
+ next_free_frame += count;
+ return std::pair{kapi::memory::frame{start}, count};
+ }
+
+ auto release_many(std::pair<kapi::memory::frame, std::size_t>) -> void override {}
+
+ std::size_t next_free_frame{};
+ };
+
+} // namespace kernel::tests
+
+#endif \ No newline at end of file
diff --git a/kernel/include/kernel/tests/page_mapper.hpp b/kernel/include/kernel/tests/page_mapper.hpp
new file mode 100644
index 0000000..9969976
--- /dev/null
+++ b/kernel/include/kernel/tests/page_mapper.hpp
@@ -0,0 +1,33 @@
+#ifndef TEACHOS_KERNEL_TESTS_PAGE_MAPPER_HPP
+#define TEACHOS_KERNEL_TESTS_PAGE_MAPPER_HPP
+
+#include "kapi/memory.hpp"
+
+#include "kernel/tests/simulated_memory.hpp"
+
+#include <kstd/units>
+
+#include <cstddef>
+#include <cstdint>
+#include <unordered_map>
+
+namespace kernel::tests
+{
+
+ struct page_mapper : kapi::memory::page_mapper
+ {
+ explicit page_mapper(kstd::units::bytes memory_size);
+
+ auto map(kapi::memory::page page, kapi::memory::frame frame, flags) -> std::byte * override;
+
+ auto unmap(kapi::memory::page page) -> void override;
+
+ auto try_unmap(kapi::memory::page page) noexcept -> bool override;
+
+ kernel::tests::simulated_memory memory;
+ std::unordered_map<std::uint64_t, kapi::memory::frame> page_mappings;
+ };
+
+} // namespace kernel::tests
+
+#endif \ No newline at end of file
diff --git a/kernel/include/kernel/tests/simulated_memory.hpp b/kernel/include/kernel/tests/simulated_memory.hpp
index fee4d7a..446d558 100644
--- a/kernel/include/kernel/tests/simulated_memory.hpp
+++ b/kernel/include/kernel/tests/simulated_memory.hpp
@@ -4,18 +4,24 @@
#include <kstd/units>
#include <cstddef>
+#include <vector>
-namespace kernel::tests::simulated_memory
+namespace kernel::tests
{
- auto init(kstd::units::bytes size) -> void;
+ struct simulated_memory
+ {
+ explicit simulated_memory(kstd::units::bytes size);
- auto reset() -> void;
+ auto clear() -> void;
- auto pmm_metadata_base() -> std::byte *;
+ auto ram_base() noexcept -> std::byte *;
+ [[nodiscard]] auto ram_base() const noexcept -> std::byte const *;
- auto ram_base() -> std::byte *;
+ private:
+ std::vector<std::byte> m_memory;
+ };
-} // namespace kernel::tests::simulated_memory
+} // namespace kernel::tests
#endif \ No newline at end of file
diff --git a/kernel/src/test_support/kapi/memory.cpp b/kernel/src/test_support/kapi/memory.cpp
index 652a3d3..7b7a81e 100644
--- a/kernel/src/test_support/kapi/memory.cpp
+++ b/kernel/src/test_support/kapi/memory.cpp
@@ -2,15 +2,12 @@
#include <kapi/memory.hpp>
-#include "kernel/tests/simulated_memory.hpp"
+#include "kernel/tests/bump_frame_allocator.hpp"
+#include "kernel/tests/page_mapper.hpp"
-#include <kstd/print>
#include <kstd/units>
-#include <cstddef>
-#include <cstdint>
#include <optional>
-#include <utility>
namespace kapi::memory
{
@@ -18,97 +15,48 @@ namespace kapi::memory
namespace
{
//! The size of the simulated RAM.
- constexpr auto simulate_memory_size = kstd::units::MiB(32);
- constexpr auto number_of_simulated_frames = simulate_memory_size / frame::size;
+ constexpr auto memory_size = kstd::units::MiB(32);
+ constexpr auto number_of_frames = memory_size / frame::size;
- struct test_bootstrap_frame_allocator : frame_allocator
- {
- auto mark_used(frame) -> void override {}
-
- auto allocate_many(std::size_t count) noexcept -> std::optional<std::pair<frame, std::size_t>> override
- {
- auto start = next_free_frame;
- next_free_frame += count;
- return std::pair{frame{start}, count};
- }
-
- auto release_many(std::pair<frame, std::size_t>) -> void override {}
+ auto constinit bump_allocator = std::optional<kernel::tests::bump_frame_allocator>{};
+ auto constinit test_mapper = std::optional<kernel::tests::page_mapper>{};
- std::size_t next_free_frame{};
- };
-
- auto constinit bootstrap_allocator = std::optional<test_bootstrap_frame_allocator>{};
-
- struct test_page_mapper : page_mapper
- {
- auto map(page page, frame frame, flags flags) -> std::byte * override
- {
- kstd::println("mapping page {} onto frame {} with flags {}", page.number(), frame.number(),
- static_cast<std::uint64_t>(flags));
-
- if ((page.start_address() & pmm_metadata_base.raw()) == pmm_metadata_base.raw())
- {
- auto offset = page.start_address() & ~pmm_metadata_base.raw();
- return kernel::tests::simulated_memory::pmm_metadata_base() + offset;
- }
-
- return nullptr;
- }
-
- auto unmap(page page) -> void override
- {
- kstd::println("unmapping page {}", page.number());
- }
-
- auto try_unmap(page page) noexcept -> bool override
- {
- kstd::println("trying to unmap page {}", page.number());
- return false;
- }
- };
-
- auto constinit test_mapper = std::optional<test_page_mapper>{};
+ auto constinit old_allocator = std::optional<frame_allocator *>{};
+ auto constinit old_mapper = std::optional<page_mapper *>{};
auto handoff_to_kernel_pmm(frame_allocator & new_allocator) -> void
{
- auto first_free_frame = bootstrap_allocator->next_free_frame;
- auto number_of_free_frames = number_of_simulated_frames - first_free_frame;
+ auto first_free_frame = bump_allocator->next_free_frame;
+ auto number_of_free_frames = number_of_frames - first_free_frame;
new_allocator.release_many({frame{first_free_frame}, number_of_free_frames});
}
- auto constinit previous_frame_allocator = std::optional<frame_allocator *>{};
- auto constinit previous_page_mapper = std::optional<page_mapper *>{};
-
} // namespace
auto init() -> void
{
- kernel::tests::simulated_memory::init(simulate_memory_size);
+ bump_allocator.emplace();
+ test_mapper.emplace(memory_size);
- bootstrap_allocator.emplace();
- test_mapper.emplace();
+ old_allocator = set_frame_allocator(*bump_allocator);
+ old_mapper = set_page_mapper(*test_mapper);
- previous_frame_allocator = set_frame_allocator(*bootstrap_allocator);
- previous_page_mapper = set_page_mapper(*test_mapper);
-
- init_pmm(simulate_memory_size / frame::size, handoff_to_kernel_pmm);
+ init_pmm(memory_size / frame::size, handoff_to_kernel_pmm);
}
auto reset() -> void
{
- kernel::tests::simulated_memory::reset();
-
- if (previous_frame_allocator && *previous_frame_allocator)
+ if (old_allocator && *old_allocator)
{
- set_frame_allocator(**previous_frame_allocator);
+ set_frame_allocator(**old_allocator);
}
- if (previous_page_mapper && *previous_page_mapper)
+ if (old_mapper && *old_mapper)
{
- set_page_mapper(**previous_page_mapper);
+ set_page_mapper(**old_mapper);
}
- bootstrap_allocator.reset();
+ bump_allocator.reset();
test_mapper.reset();
}
diff --git a/kernel/src/test_support/page_mapper.cpp b/kernel/src/test_support/page_mapper.cpp
new file mode 100644
index 0000000..a026ec3
--- /dev/null
+++ b/kernel/src/test_support/page_mapper.cpp
@@ -0,0 +1,57 @@
+#include "kernel/tests/page_mapper.hpp"
+
+#include "kapi/memory.hpp"
+
+#include <kstd/units>
+
+#include <cstddef>
+#include <format>
+#include <stdexcept>
+
+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 *
+ {
+ page_mappings.insert({page.number(), frame});
+
+ auto page_address = page.start_address();
+
+ if (page_address >= kapi::memory::mmio_base)
+ {
+ throw std::invalid_argument{"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
diff --git a/kernel/src/test_support/simulated_memory.cpp b/kernel/src/test_support/simulated_memory.cpp
index 49e172f..d23350b 100644
--- a/kernel/src/test_support/simulated_memory.cpp
+++ b/kernel/src/test_support/simulated_memory.cpp
@@ -5,35 +5,26 @@
#include <cstddef>
#include <vector>
-namespace kernel::tests::simulated_memory
+namespace kernel::tests
{
- namespace
- {
- auto constinit ram_storage = std::vector<std::byte>{};
- auto constinit pmm_storage = std::vector<std::byte>{};
- } // namespace
-
- auto init(kstd::units::bytes size) -> void
- {
- ram_storage.resize(size / kstd::units::bytes{1});
- pmm_storage.resize(size / kstd::units::bytes{1});
- }
+ simulated_memory::simulated_memory(kstd::units::bytes size)
+ : m_memory{size / kstd::units::bytes{1}}
+ {}
- auto reset() -> void
+ auto simulated_memory::ram_base() noexcept -> std::byte *
{
- ram_storage.clear();
- pmm_storage.clear();
+ return m_memory.data();
}
- auto pmm_metadata_base() -> std::byte *
+ auto simulated_memory::ram_base() const noexcept -> std::byte const *
{
- return pmm_storage.data();
+ return m_memory.data();
}
- auto ram_base() -> std::byte *
+ auto simulated_memory::clear() -> void
{
- return ram_storage.data();
+ m_memory.clear();
}
-} // namespace kernel::tests::simulated_memory \ No newline at end of file
+} // namespace kernel::tests \ No newline at end of file