aboutsummaryrefslogtreecommitdiff
path: root/kernel/src/test_support/simulated_memory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/src/test_support/simulated_memory.cpp')
-rw-r--r--kernel/src/test_support/simulated_memory.cpp93
1 files changed, 93 insertions, 0 deletions
diff --git a/kernel/src/test_support/simulated_memory.cpp b/kernel/src/test_support/simulated_memory.cpp
new file mode 100644
index 0000000..fa3d36c
--- /dev/null
+++ b/kernel/src/test_support/simulated_memory.cpp
@@ -0,0 +1,93 @@
+#include "kernel/test_support/simulated_memory.hpp"
+
+#include "kapi/memory.hpp"
+
+#include <kstd/units>
+
+#include <cstddef>
+#include <cstring>
+#include <stdexcept>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+using namespace kstd::units_literals;
+
+namespace kernel::tests
+{
+ namespace
+ {
+ constexpr auto virtual_size = 1_GiB;
+ }
+
+ simulated_memory::simulated_memory(kstd::units::bytes size)
+ : m_memory_descriptor{memfd_create("teachos_simulated_memory", 0)}
+ , m_size{size}
+ {
+ if (m_memory_descriptor < 0)
+ {
+ throw std::runtime_error("Failed to create simulated memory");
+ }
+
+ if (ftruncate(m_memory_descriptor, static_cast<off_t>(m_size.value)) < 0)
+ {
+ throw std::runtime_error("Failed to resize simulated memory");
+ }
+
+ auto mapped_pointer = mmap(nullptr, m_size.value, PROT_READ | PROT_WRITE, MAP_SHARED, m_memory_descriptor, 0);
+ if (mapped_pointer == MAP_FAILED)
+ {
+ throw std::runtime_error("Failed to map simulated memory");
+ }
+
+ m_physical_base = static_cast<std::byte *>(mapped_pointer);
+
+ auto virtual_pointer = mmap(nullptr, virtual_size.value, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (virtual_pointer == MAP_FAILED)
+ {
+ throw std::runtime_error("Failed to map simulated memory");
+ }
+
+ m_virtual_base = static_cast<std::byte *>(virtual_pointer);
+
+ clear();
+ }
+
+ simulated_memory::~simulated_memory()
+ {
+ munmap(m_physical_base, m_size.value);
+ munmap(m_virtual_base, virtual_size.value);
+ close(m_memory_descriptor);
+ }
+
+ auto simulated_memory::clear() -> void
+ {
+ std::memset(m_physical_base, 0, m_size.value);
+ }
+
+ auto simulated_memory::ram_base() noexcept -> std::byte *
+ {
+ return m_physical_base;
+ }
+
+ auto simulated_memory::ram_base() const noexcept -> std::byte const *
+ {
+ return m_physical_base;
+ }
+
+ auto simulated_memory::heap_base() const noexcept -> kapi::memory::linear_address
+ {
+ return kapi::memory::linear_address{m_virtual_base};
+ }
+
+ auto simulated_memory::heap_size() const noexcept -> kstd::units::bytes
+ {
+ return virtual_size;
+ }
+
+ auto simulated_memory::memory_descriptor() const noexcept -> int
+ {
+ return m_memory_descriptor;
+ }
+
+} // namespace kernel::tests \ No newline at end of file