|
|
|
@ -165,6 +165,50 @@ uintptr_t unmap_page(void *virt)
|
|
|
|
|
return phys;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum pflags get_pflags(void *page)
|
|
|
|
|
{
|
|
|
|
|
usize pd_index = ((uintptr_t)page >> PAGE_SHIFT) / 1024;
|
|
|
|
|
usize pt_index = ((uintptr_t)page >> PAGE_SHIFT) % 1024;
|
|
|
|
|
|
|
|
|
|
struct x86_page_directory_entry *pde = &X86_CURRENT_PD->entries[pd_index];
|
|
|
|
|
if (pde->huge) {
|
|
|
|
|
return *(unsigned long *)pde & ~PAGE_MASK;
|
|
|
|
|
} else if (pde->present) {
|
|
|
|
|
struct x86_page_table_entry *pte = &X86_CURRENT_PT(pd_index)->entries[pt_index];
|
|
|
|
|
return *(unsigned long *)pte & ~PAGE_MASK;
|
|
|
|
|
} else {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int set_pflags(void *page, enum pflags pflags)
|
|
|
|
|
{
|
|
|
|
|
usize pd_index = ((uintptr_t)page >> PAGE_SHIFT) / 1024;
|
|
|
|
|
usize pt_index = ((uintptr_t)page >> PAGE_SHIFT) % 1024;
|
|
|
|
|
|
|
|
|
|
struct x86_page_directory_entry *pde = &X86_CURRENT_PD->entries[pd_index];
|
|
|
|
|
if (pflags & P_HUGE) {
|
|
|
|
|
/* if the PDE referred to a Page Table, free it first */
|
|
|
|
|
if (pde->present && !pde->huge)
|
|
|
|
|
free_pages((void *)((uintptr_t)pde->shifted_address << PAGE_SHIFT));
|
|
|
|
|
|
|
|
|
|
unsigned long pde_raw = *(unsigned long *)pde;
|
|
|
|
|
pde_raw &= PAGE_MASK;
|
|
|
|
|
pde_raw |= (pflags & ~PAGE_MASK);
|
|
|
|
|
*(unsigned long *)pde = pde_raw;
|
|
|
|
|
} else if (pde->present) {
|
|
|
|
|
struct x86_page_table_entry *pte = X86_CURRENT_PTE(pd_index, pt_index);
|
|
|
|
|
unsigned long pte_raw = *(unsigned long *)pte;
|
|
|
|
|
pte_raw &= PAGE_MASK;
|
|
|
|
|
pte_raw |= (pflags & ~PAGE_MASK);
|
|
|
|
|
*(unsigned long *)pte = pte_raw;
|
|
|
|
|
} else {
|
|
|
|
|
return -EEXIST;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void x86_isr_page_fault(trap_frame_t *frame, u32 error_code)
|
|
|
|
|
{
|
|
|
|
|
void *address;
|
|
|
|
|