Untitled
unknown
c_cpp
a year ago
2.2 kB
13
Indexable
int map_page(uintptr_t vaddr, uintptr_t paddr, PageAttributes attrs) {
vaddr = _align_down(vaddr);
paddr = _align_down(paddr);
if (vaddr == 0) return -1;
uint32_t indices[2] = {_pd_index(vaddr), _pt_index(vaddr)};
PTE* tables[2] = {RECURSIVE_PD, NULL};
for (int i = 0; i < 2; i++) { // walk page table levels
switch (i) {
case 0:
goto _pd;
case 1:
goto _pt;
}
_pd:
if (!tables[0][indices[0]].present) {
PTE* new_pt = (PTE*)pmm_alloc_page();
if (!new_pt) return -1;
_zero_pt((PTE*)((uintptr_t)new_pt));
PageAttributes new_attrs = {
.present = 1,
.rw = 1,
.user = attrs.user,
.frame_addr = ((uintptr_t)new_pt) >> 12
};
SET_PF((PTE*)&tables[0][indices[0]], new_attrs);
}
tables[1] = RECURSIVE_PT(indices[0]);
continue;
_pt:
if (tables[1][indices[1]].present) {
pmm_free_page((void*)(tables[1][indices[1]].frame_addr << 12));
}
attrs.frame_addr = paddr >> 12;
SET_PF(&tables[1][indices[1]], attrs);
break;
}
asm volatile ("invlpg (%0)" : : "a" (vaddr));
return 0;
}
int unmap_page(uintptr_t vaddr) {
vaddr = _align_down(vaddr);
uint32_t pd_idx = _pd_index(vaddr);
uint32_t pt_idx = _pt_index(vaddr);
if (!RECURSIVE_PD[pd_idx].present) return -1;
PTE* pt = RECURSIVE_PT(pd_idx);
if (!pt[pt_idx].present) return -1;
pmm_free_page((void*)(pt[pt_idx].frame_addr << 12));
PageAttributes zero = {0};
SET_PF(&pt[pt_idx], zero);
bool pt_empty = true;
for (int i = 0; i < PAGE_TABLE_SIZE; i++) {
if (pt[i].present) {
pt_empty = false;
break;
}
}
if (pt_empty) {
pmm_free_page((void*)(RECURSIVE_PD[pd_idx].table_addr << 12));
PageAttributes zero_pd = {0};
SET_PF((PTE*)&RECURSIVE_PD[pd_idx], zero_pd);
}
asm volatile ("invlpg (%0)" : : "a" (vaddr));
return 0;
}
Editor is loading...
Leave a Comment