error_t vmmngr_map_page(pdirectory* dir, physical_addr phys, virtual_addr virt, uint32 flags) { // our goal is to get the pt_entry indicated by virt and set its frame to phys. pd_entry* e = vmmngr_pdirectory_lookup_entry(dir, virt); if (pd_entry_test_attrib(e, I86_PDE_PRESENT) == false) // table is not present if (vmmngr_create_table(dir, virt, flags) != ERROR_OK) return ERROR_OCCUR; // here we have a guaranteed working table (perhaps empty) ptable* table = (ptable*)pd_entry_get_frame(*e); pt_entry* page = vmmngr_ptable_lookup_entry(table, virt); // we have the page if (page == 0) { //PANIC("HERE"); return ERROR_OCCUR; } //*page = 0; // delete possible previous information (pt_entry is just a uint32) *page |= flags; // and reset pt_entry_set_frame(page, phys); vmmngr_flush_TLB_entry(virt); return ERROR_OK; }
void vmmngr_free_page_addr(virtual_addr addr) { pd_entry* e = vmmngr_pdirectory_lookup_entry(vmmngr_get_directory(), addr); ptable* table = (ptable*)pd_entry_get_frame(*e); pt_entry* page = vmmngr_ptable_lookup_entry(table, addr); vmmngr_free_page(page); }
void vmmngr_set_user(virtual_addr addr, int user) { ptable * ptable = vmmngr_get_ptable_address(addr); pt_entry * pte = vmmngr_ptable_lookup_entry(ptable, addr); if (user) { pt_entry_add_attrib(pte, I86_PTE_USER); } else { pt_entry_del_attrib(pte, I86_PTE_USER); } }
void vmmngr_set_writeable(virtual_addr addr, int writeable) { ptable * ptable = vmmngr_get_ptable_address(addr); pt_entry * pte = vmmngr_ptable_lookup_entry(ptable, addr); if (writeable) { pt_entry_add_attrib(pte, I86_PTE_WRITABLE); } else { pt_entry_del_attrib(pte, I86_PTE_WRITABLE); } }
bool vmmngr_is_page_present(virtual_addr addr) { pd_entry* e = vmmngr_pdirectory_lookup_entry(vmmngr_get_directory(), addr); if (e == 0 || pd_entry_is_present(*e) == false) return false; ptable* table = (ptable*)pd_entry_get_frame(*e); if (table == 0) return false; pt_entry* page = vmmngr_ptable_lookup_entry(table, addr); if (page == 0 || pt_entry_is_present(*page) == false) return false; return true; }
physical_addr vmmngr_get_phys_addr(virtual_addr addr) { pd_entry* e = vmmngr_pdirectory_lookup_entry(vmmngr_get_directory(), addr); if (!e) return 0; ptable* table = (ptable*)pd_entry_get_frame(*e); pt_entry* page = vmmngr_ptable_lookup_entry(table, addr); if (!page) return 0; physical_addr p_addr = pt_entry_get_frame(*page); p_addr += (addr & 0xfff); // add in-page offset return p_addr; }