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_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); }
int vmmngr_commit_page(pt_entry * e) { void *p = pmmngr_alloc_block(); if (!p) { return 0; } pt_entry_set_frame(e, (physical_addr) p); pt_entry_add_attrib(e, I86_PTE_PRESENT); pt_entry_add_attrib(e, I86_PTE_WRITABLE); return 1; }
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); }