aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/memory/scoped_mapping.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/src/memory/scoped_mapping.cpp')
-rw-r--r--arch/x86_64/src/memory/scoped_mapping.cpp69
1 files changed, 69 insertions, 0 deletions
diff --git a/arch/x86_64/src/memory/scoped_mapping.cpp b/arch/x86_64/src/memory/scoped_mapping.cpp
new file mode 100644
index 0000000..a86aaed
--- /dev/null
+++ b/arch/x86_64/src/memory/scoped_mapping.cpp
@@ -0,0 +1,69 @@
+#include "x86_64/memory/scoped_mapping.hpp"
+
+#include "kapi/memory.hpp"
+#include "kapi/system.hpp"
+
+#include "x86_64/memory/mmu.hpp"
+#include "x86_64/memory/page_table.hpp"
+#include "x86_64/memory/paging_root.hpp"
+
+#include <cstddef>
+#include <utility>
+
+namespace teachos::memory::x86_64
+{
+
+ scoped_mapping::scoped_mapping(scoped_mapping && other) noexcept
+ : m_page{std::exchange(other.m_page, page{})}
+ , m_mapper{std::exchange(other.m_mapper, nullptr)}
+ , m_mapped{std::exchange(other.m_mapped, false)}
+ {}
+
+ scoped_mapping::scoped_mapping(page page, page_mapper & mapper)
+ : m_page{page}
+ , m_mapper{&mapper}
+ , m_mapped{false}
+ {
+ if (paging_root::get()->translate(page))
+ {
+ system::panic("[MEM] Tried to map a page that is already mapped!");
+ }
+ }
+
+ scoped_mapping::~scoped_mapping()
+ {
+ if (m_mapped)
+ {
+ unmap();
+ x86_64::tlb_flush(m_page.start_address());
+ }
+ }
+
+ auto scoped_mapping::operator=(scoped_mapping && other) noexcept -> scoped_mapping &
+ {
+ swap(*this, other);
+ return *this;
+ }
+
+ auto scoped_mapping::map(frame frame, page_table::entry::flags flags) -> std::byte *
+ {
+ auto result = m_mapper->map(m_page, frame, to_mapper_flags(flags));
+ m_mapped = true;
+ return result;
+ }
+
+ auto scoped_mapping::unmap() -> void
+ {
+ m_mapper->unmap(m_page);
+ m_mapped = false;
+ }
+
+ auto swap(scoped_mapping & lhs, scoped_mapping & rhs) -> void
+ {
+ using std::swap;
+ swap(lhs.m_page, rhs.m_page);
+ swap(lhs.m_mapper, rhs.m_mapper);
+ swap(lhs.m_mapped, rhs.m_mapped);
+ }
+
+} // namespace teachos::memory::x86_64 \ No newline at end of file