aboutsummaryrefslogtreecommitdiff
path: root/src/vmm.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/vmm.cc')
-rw-r--r--src/vmm.cc65
1 files changed, 27 insertions, 38 deletions
diff --git a/src/vmm.cc b/src/vmm.cc
index 483f02f..3c90c48 100644
--- a/src/vmm.cc
+++ b/src/vmm.cc
@@ -1,5 +1,4 @@
#include "vmm.h"
-#include <stdlib.h>
typedef void (*constructor)();
@@ -49,51 +48,41 @@ void dump_address() {
}
} // extern "C"
-/* boot.S page directory and kernel page table */
+/* boot.S externs */
extern uint32_t kernel_pagedir;
extern uint32_t kernel_ptable0;
+extern uint32_t VADDR_OFFSET;
-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');
- }
-}
+/* vmm */
+static_assert(sizeof(vmm::address) == 4);
+static_assert(vmm::address(0xc03ff000) == 0xc03ff000);
+static_assert(vmm::address(0xc03ff000).table_idx == 768);
+static_assert(vmm::address(0xc03ff000).page_idx == 1023);
+static_assert(vmm::address(0xc03ff000).offset == 0);
-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;
+vmm::vmm(uint32_t* addr) : directory{(addr == nullptr) ? &kernel_pagedir : addr} {}
- const auto table = table_id(dest);
- const auto page = page_id(dest - table * 4 * 1024 * 1024);
+Result<uint32_t, vmm::Error> vmm::map(uint32_t addr, const vmm::address dest) {
+ const auto phys_offset = addr % 4096;
+ const auto phys_paddr = addr & 0xfffff000;
- printk("phys_addr page: ", uhex{phys_page}, '\n');
- printk(" offset: ", uhex{phys_offset}, '\n');
- printk(" table: ", table, '\n');
- printk(" page: ", page, '\n');
+ // TODO allocate page table
+ if (directory[dest.table_idx] == 0) return Result<uint32_t, vmm::Error>{vmm::TableNotAllocated};
- if (directory[table] == 0) return 0;
+ page_table table{directory[dest.table_idx]};
- 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;
+ if (table.set(dest.page_idx, phys_paddr)) {
+ vmm::reload();
+ return Result<uint32_t, vmm::Error>{dest + phys_offset};
+ } else
+ return Result<uint32_t, vmm::Error>{vmm::AddressAlreadyMapped};
+}
- uint32_t cr0;
- asm volatile("mov %%cr0, %0" : "=r"(cr0));
- asm volatile("mov %0, %%cr0" : : "r"(cr0));
+vmm::page_table::page_table(uint32_t from) {
+ // TODO get flags
+ // convert physical address to a virtual address so we can read it
+ from &= 0xfffff000; // discard flags
+ from += reinterpret_cast<uint32_t>(&VADDR_OFFSET);
- return table * 4 * 1024 * 1024 + page * 4 * 1024 + phys_offset;
+ pages = reinterpret_cast<uint32_t*>(from);
}