aboutsummaryrefslogtreecommitdiff
path: root/src/vmm.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/vmm.cc')
-rw-r--r--src/vmm.cc50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/vmm.cc b/src/vmm.cc
index 346e6ab..483f02f 100644
--- a/src/vmm.cc
+++ b/src/vmm.cc
@@ -1,3 +1,4 @@
+#include "vmm.h"
#include <stdlib.h>
typedef void (*constructor)();
@@ -47,3 +48,52 @@ void dump_address() {
" end: ", uhex{reinterpret_cast<uint32_t>(&end_bss)}, '\n');
}
} // extern "C"
+
+/* boot.S page directory and kernel page table */
+extern uint32_t kernel_pagedir;
+extern uint32_t kernel_ptable0;
+
+constexpr uint32_t to_vma(uint32_t page_dir_address) {
+ page_dir_address &= 0xfffff000;
+ page_dir_address += 0xc0000000;
+ page_dir_address -= 0x00400000;
+ return page_dir_address;
+}
+
+vmm::vmm(uint32_t* addr) : directory{(addr == nullptr) ? &kernel_pagedir : addr} {
+ printk("page directory is at ", uhex{reinterpret_cast<uint32_t>(directory)}, '\n');
+ printk("page table 768 ", uhex{reinterpret_cast<uint32_t>(directory[768])}, '\n');
+ printk("page table 768 vma ", uhex{to_vma(reinterpret_cast<uint32_t>(directory[768]))}, '\n');
+ printk("kernel_ptable0 is at ", uhex{reinterpret_cast<uint32_t>(&kernel_ptable0)}, '\n');
+
+ uint32_t* page = reinterpret_cast<uint32_t*>(&kernel_ptable0);
+ for (size_t i = 0; i < 32; ++i) {
+ printk(uhex{page[i] & 0xfffff000}, ' ');
+ if (i % 4 == 3) printk('\n');
+ }
+}
+
+uint32_t vmm::map(uint32_t phys_addr, uint32_t dest) {
+ const auto phys_offset = phys_addr % 4096;
+ const auto phys_page = phys_addr - phys_offset;
+
+ const auto table = table_id(dest);
+ const auto page = page_id(dest - table * 4 * 1024 * 1024);
+
+ printk("phys_addr page: ", uhex{phys_page}, '\n');
+ printk(" offset: ", uhex{phys_offset}, '\n');
+ printk(" table: ", table, '\n');
+ printk(" page: ", page, '\n');
+
+ if (directory[table] == 0) return 0;
+
+ uint32_t* page_table = reinterpret_cast<uint32_t*>(to_vma(reinterpret_cast<uint32_t>(directory[table])));
+ if (page_table[page] != 0) return 0;
+ page_table[page] = phys_page | 0x003;
+
+ uint32_t cr0;
+ asm volatile("mov %%cr0, %0" : "=r"(cr0));
+ asm volatile("mov %0, %%cr0" : : "r"(cr0));
+
+ return table * 4 * 1024 * 1024 + page * 4 * 1024 + phys_offset;
+}