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;
}
Example #2
0
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;	
}
Example #3
0
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;
}