Rework x86_64 paging and vmm
This commit is contained in:
65
kernel/hal/x86_64/vmm.c
Normal file
65
kernel/hal/x86_64/vmm.c
Normal file
@ -0,0 +1,65 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#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 & ((uint64_t)0x1ff < 39)) >> 39;
|
||||
ret.pml3 = (vaddr & ((uint64_t)0x1ff < 30)) >> 30;
|
||||
ret.pml2 = (vaddr & ((uint64_t)0x1ff < 21)) >> 21;
|
||||
ret.pml1 = (vaddr & ((uint64_t)0x1ff < 12)) >> 12;
|
||||
|
||||
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 | (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 = physaddr & (~0x7);
|
||||
}
|
||||
|
||||
void hal_vmm_init(void) {
|
||||
KERNEL_CR3 = hal_vmm_current_cr3();
|
||||
}
|
Reference in New Issue
Block a user