Ejemplo n.º 1
0
void map_page(uint32_t *page_dir, uint32_t virt_page_num, uint32_t phy_page_num,
        bool global, bool user, bool read_write)
{
    uint16_t pd_idx = PD_IDX(virt_page_num),
             pt_idx = PT_IDX(virt_page_num);
    uint32_t *page_table;

    if(!(page_dir[pd_idx] & 0x1)) {
        uint32_t pt_page_num = alloc_phy_page(0, 1023);
        map_kernel_page(pt_page_num, pt_page_num, true, false, true);
        memset((void *)(pt_page_num << 12), 0, 4096);
        page_dir[pd_idx] = make_pde(pt_page_num, user, read_write);
    }

    page_table = (uint32_t *)(page_dir[pd_idx] & 0xfffff000);
    page_table[pt_idx] = make_pte(phy_page_num, global, user, read_write);
    ++phy_mem_rc[phy_page_num];
    __asm__ volatile(
        ".intel_syntax noprefix;"
        "mov eax, cr3;"
        "mov cr3, eax;"
        ".att_syntax;"
        :::"eax"
    );
}
Ejemplo n.º 2
0
Archivo: map.c Proyecto: spectrec/ann
pte_t *mmap_lookup(pml4e_t *pml4, uint64_t va, bool create)
{
	struct page *page4pdp = NULL, *page4pd = NULL, *page4pt = NULL;
	pdpe_t pml4e = pml4[PML4_IDX(va)];

	if ((pml4e & PML4E_P) != 0)
		goto pml4e_found;
	if (create == false)
		return NULL;

	// Prepare new page directory pointer
	if ((page4pdp = page_alloc()) == NULL)
		return NULL;
	memset(page2kva(page4pdp), 0, PAGE_SIZE);
	page4pdp->ref = 1;

	// Insert new pdp into PML4
	pml4e = pml4[PML4_IDX(va)] = page2pa(page4pdp) | PML4E_P | PML4E_W | PML4E_U;

pml4e_found:
	assert((pml4e & PML4E_P) != 0);

	pdpe_t *pdp = VADDR(PML4E_ADDR(pml4e));
	pdpe_t pdpe = pdp[PDP_IDX(va)];

	if ((pdpe & PDPE_P) != 0)
		goto pdpe_found;
	if (create == false)
		return NULL;

	// Prepare new page directory
	if ((page4pd = page_alloc()) == NULL)
		return NULL;
	memset(page2kva(page4pd), 0, PAGE_SIZE);
	page4pd->ref = 1;

	// Insert new page directory into page directory pointer table
	pdpe = pdp[PDP_IDX(va)] = page2pa(page4pd) | PDPE_P | PDPE_W | PDPE_U;

pdpe_found:
	assert((pdpe & PDPE_P) != 0);

	pde_t *pd = VADDR(PDPE_ADDR(pdpe));
	pde_t pde = pd[PD_IDX(va)];

	if ((pde & PDE_P) != 0)
		goto pde_found;
	if (create == false)
		return NULL;

	// Prepare new page table
	if ((page4pt = page_alloc()) == NULL)
		return NULL;
	memset(page2kva(page4pt), 0, PAGE_SIZE);
	page4pt->ref = 1;

	// Insert new page table into page directory
	pde = pd[PD_IDX(va)] = page2pa(page4pt) | PDE_P | PTE_W | PDE_U;

pde_found:
	assert((pde & PDE_P) != 0);

	pte_t *pt = VADDR(PDE_ADDR(pde));

	return &pt[PT_IDX(va)];
}