#include #include #include "vmm.h" #include "hal/hal.h" #include "bootinfo/bootinfo.h" #include "pmm/pmm.h" PgTable *KERNEL_CR3 = NULL; PgTable *hal_vmm_current_cr3(void) { PgTable *cr3; asm volatile("mov %%cr3, %0" : "=r"(cr3)); return cr3; } PgIndex hal_vmm_pageindex(uint64_t vaddr) { PgIndex ret; ret.pml4 = (vaddr >> 39) & 0x1ff; ret.pml3 = (vaddr >> 30) & 0x1ff; ret.pml2 = (vaddr >> 21) & 0x1ff; ret.pml1 = (vaddr >> 12) & 0x1ff; return ret; } uint64_t *hal_vmm_nexttable(uint64_t *table, uint64_t ent) { uint8_t *addr; if (table[ent] & HAL_PG_PRESENT) { addr = (uint8_t *)(table[ent] & ~((uint64_t)0xfff)); } else { addr = pmm_alloc(1); hal_memset(BOOT_INFO.hhdm_off + addr, 0, HAL_PAGE_SIZE); table[ent] = (uint64_t)addr | HAL_PG_USER | HAL_PG_RW | HAL_PG_PRESENT; } return (uint64_t *)(BOOT_INFO.hhdm_off + addr); } void hal_vmm_map_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr, uint32_t flags) { PgIndex pi = hal_vmm_pageindex(virtaddr); uint64_t *pml3 = hal_vmm_nexttable((uint64_t *)pml4, pi.pml4); uint64_t *pml2 = hal_vmm_nexttable((uint64_t *)pml3, pi.pml3); uint64_t *pml1 = hal_vmm_nexttable((uint64_t *)pml2, pi.pml2); uint64_t *pte = &pml1[pi.pml1]; *pte = (physaddr & ~0xFFF) | (flags & 0x7); } void hal_vmm_unmap_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr) { PgIndex pi = hal_vmm_pageindex(virtaddr); uint64_t *pml3 = hal_vmm_nexttable((uint64_t *)pml4, pi.pml4); uint64_t *pml2 = hal_vmm_nexttable((uint64_t *)pml3, pi.pml3); uint64_t *pml1 = hal_vmm_nexttable((uint64_t *)pml2, pi.pml2); uint64_t *pte = &pml1[pi.pml1]; *pte &= ~HAL_PG_PRESENT; } void hal_vmm_init(void) { KERNEL_CR3 = hal_vmm_current_cr3(); }