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; }
int vmmngr_alloc_page(virtual_addr virt) { pdirectory * pd = (pdirectory *) PAGE_DIRECTORY_ADDRESS; pd_entry * pde = &pd->m_entries[PAGE_DIRECTORY_INDEX(virt)]; if ((!pd) || (!pde)) { return 0; } if (!pd_entry_is_present(*pde)) { ptable *newpt = pmmngr_alloc_block(); if (!newpt) { return 0; } *pde = (pd_entry) 0; pd_entry_add_attrib(pde, I86_PDE_PRESENT); pd_entry_add_attrib(pde, I86_PDE_WRITABLE); pd_entry_set_frame(pde, (physical_addr) newpt); memset(vmmngr_get_ptable_address(virt), 0, sizeof(ptable)); } ptable * pt = vmmngr_get_ptable_address(virt); pt_entry *pte = &pt->m_entries[PAGE_TABLE_INDEX(virt)]; if (pt_entry_is_present(*pte)) { return 1; } if (!vmmngr_commit_page(pte)) { return 0; } return 1; }
void vmmngr_map_page(void * phys, void * virt) { pageinfo pginf = vmmngr_virt_to_page_index(virt); pdirectory * page_directory = kernel_page_dir; //vmmngr_get_directory(); pd_entry * e = &page_directory->m_entries[PAGE_DIRECTORY_INDEX((uint32_t) virt)]; if (!pd_entry_is_present(*e)) { ptable * new_table = (ptable *) pmmngr_alloc_block(); if (!new_table) { return; } ptable * virtual_table = (ptable *) (0xFFC00000 + (pginf.pagetable * 0x1000)); pd_entry * entry = &kernel_page_dir->m_entries[pginf.pagetable]; pd_entry_add_attrib(entry, I86_PDE_PRESENT); pd_entry_add_attrib(entry, I86_PDE_WRITABLE); pd_entry_set_frame(entry, (physical_addr) new_table); memset(virtual_table, 0, sizeof(ptable)); pt_entry * page = &virtual_table->m_entries[pginf.page]; pt_entry_set_frame(page, (physical_addr) phys); pt_entry_add_attrib(page, I86_PTE_PRESENT); pt_entry_add_attrib(page, I86_PTE_WRITABLE); return; } ptable * table = (ptable *) PAGE_GET_PHYSICAL_ADDRESS(e); pt_entry * page = &table->m_entries[PAGE_TABLE_INDEX((uint32_t) virt)]; pt_entry_set_frame(page, (physical_addr) phys); pt_entry_add_attrib(page, I86_PTE_PRESENT); pt_entry_add_attrib(page, I86_PTE_WRITABLE); }
error_t vmmngr_create_table(pdirectory* dir, virtual_addr addr, uint32 flags) { pd_entry* entry = vmmngr_pdirectory_lookup_entry(dir, addr); if (!entry) return ERROR_OCCUR; if (pd_entry_is_present(*entry) == false) { ptable* table = (ptable*)pmmngr_alloc_block(); if (!table) return ERROR_OCCUR; // not enough memory!! memset(table, 0, sizeof(ptable)); pd_entry_set_frame(entry, (physical_addr)table); *entry |= flags; return ERROR_OK; } // TODO: Is the above test required? Since the check is done outside // entry already exists return ERROR_OK; }