#pragma once #include #include extern "C" void dump_address(); 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(addr & 0x3ff)}, page_idx{static_cast((addr >> 12) & 0x3ff)}, table_idx{static_cast(addr >> 22)} {} constexpr address(size_t table, size_t page) : page_idx{page}, table_idx{table} {} constexpr operator uint32_t() const { return static_cast(table_idx << 22) | static_cast(page_idx << 12) | static_cast(offset); } } __attribute__((packed)); vmm(uint32_t* addr = nullptr); [[deprecated]] constexpr static size_t table_id(uint32_t offset) { offset &= 0xfff00000; offset /= (4 * 1024 * 1024); return static_cast(offset); } [[deprecated]] constexpr static size_t page_id(uint32_t offset) { return static_cast(offset / 4096); } static void reload() { uint32_t cr0; asm volatile("mov %%cr0, %0" : "=r"(cr0)); asm volatile("mov %0, %%cr0" : : "r"(cr0)); } [[nodiscard]] Result 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; };