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; }
void vmmngr_initialize(physical_addr dir_address) { int i = 0; int frame = 0; int virt = 0; ptable * table = (ptable *) pmmngr_alloc_block(); if (!table) { return; } ptable * table2 = (ptable *) pmmngr_alloc_block(); if (!table2) { pmmngr_free_block(table); return; } memset(table, 0, sizeof(ptable)); for (i = 0, frame = 0x0, virt = 0x00000000; i < 1024; ++i, frame+=4096, virt+=4096) { pt_entry page = 0; pt_entry_add_attrib(&page, I86_PTE_PRESENT); pt_entry_set_frame(&page, frame); table->m_entries[PAGE_TABLE_INDEX(virt)] = page; } for (i = 0, frame = 0x0, virt = 0xc0000000; i < 1024; ++i, frame+=4096, virt+=4096) { pt_entry page = 0; pt_entry_add_attrib(&page, I86_PTE_PRESENT); pt_entry_set_frame(&page, frame); table2->m_entries[PAGE_TABLE_INDEX(virt)] = page; } pdirectory * dir = (pdirectory *) dir_address;// pmmngr_alloc_block(); if (!dir) { pmmngr_free_block(table); pmmngr_free_block(table2); return; } memset(dir, 0, sizeof(pdirectory)); pd_entry * entry = &dir->m_entries[PAGE_DIRECTORY_INDEX(0x00000000)]; pd_entry_add_attrib(entry, I86_PDE_PRESENT); pd_entry_add_attrib(entry, I86_PDE_WRITABLE); pd_entry_set_frame(entry, (physical_addr) table); pd_entry * entry2 = &dir->m_entries[PAGE_DIRECTORY_INDEX(0xc0000000)]; pd_entry_add_attrib(entry2, I86_PDE_PRESENT); pd_entry_add_attrib(entry2, I86_PDE_WRITABLE); pd_entry_set_frame(entry2, (physical_addr) table2); pd_entry * entry3 = &dir->m_entries[PAGE_DIRECTORY_INDEX(0xFFC00000)]; pd_entry_add_attrib(entry3, I86_PDE_PRESENT); pd_entry_add_attrib(entry3, I86_PDE_WRITABLE); pd_entry_set_frame(entry3, (physical_addr) dir); vmmngr_switch_pdirectory(dir); pmmngr_paging_enable(1); }