aboutsummaryrefslogtreecommitdiff
path: root/src/vmm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/vmm.h')
-rw-r--r--src/vmm.h57
1 files changed, 44 insertions, 13 deletions
diff --git a/src/vmm.h b/src/vmm.h
index 9de487b..252e5bb 100644
--- a/src/vmm.h
+++ b/src/vmm.h
@@ -1,31 +1,62 @@
-#include <stdlib.h>
-
#pragma once
+#include <result.h>
+#include <stdlib.h>
extern "C" void dump_address();
-struct page_table {
- uint32_t* addr;
-};
-
class vmm {
public:
+ enum Error { NoError, TableNotAllocated, AddressAlreadyMapped };
+
+ struct address {
+ size_t offset : 12 = 0;
+ size_t page_idx : 10 = 0;
+ size_t table_idx : 10 = 0;
+
+ constexpr address(uint32_t addr)
+ : offset{static_cast<size_t>(addr & 0x3ff)},
+ page_idx{static_cast<size_t>((addr >> 12) & 0x3ff)},
+ table_idx{static_cast<size_t>(addr >> 22)} {}
+
+ constexpr address(size_t table, size_t page) : page_idx{page}, table_idx{table} {}
+
+ constexpr operator uint32_t() const {
+ return static_cast<uint32_t>(table_idx << 22) | static_cast<uint32_t>(page_idx << 12) |
+ static_cast<uint32_t>(offset);
+ }
+ } __attribute__((packed));
+
vmm(uint32_t* addr = nullptr);
- constexpr static size_t table_id(uint32_t offset) {
+ [[deprecated]] constexpr static size_t table_id(uint32_t offset) {
offset &= 0xfff00000;
offset /= (4 * 1024 * 1024);
return static_cast<size_t>(offset);
}
- constexpr static size_t page_id(uint32_t offset) { return static_cast<size_t>(offset / 4096); }
+ [[deprecated]] constexpr static size_t page_id(uint32_t offset) { return static_cast<size_t>(offset / 4096); }
- uint32_t map(uint32_t phys_addr, uint32_t offset);
+ static void reload() {
+ uint32_t cr0;
+ asm volatile("mov %%cr0, %0" : "=r"(cr0));
+ asm volatile("mov %0, %%cr0" : : "r"(cr0));
+ }
+
+ [[nodiscard]] Result<uint32_t, Error> map(uint32_t phys_addr, const address dest);
private:
+ class page_table {
+ public:
+ page_table(uint32_t);
+ bool set(size_t idx, uint32_t a) {
+ if (pages[idx] != 0) return false;
+ pages[idx] = a | 0x003;
+ return true;
+ }
+
+ private:
+ uint32_t* pages;
+ };
+
uint32_t* directory;
};
-static_assert(vmm::table_id(0x00001234) == 0);
-static_assert(vmm::table_id(0x00400000) == 1);
-static_assert(vmm::table_id(0xc0000000) == 768);
-static_assert(vmm::table_id(0xc03ff000) == 768);