diff options
Diffstat (limited to 'src/vmm.h')
-rw-r--r-- | src/vmm.h | 57 |
1 files changed, 44 insertions, 13 deletions
@@ -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); |