Пример #1
0
/*
 * Maps a page (PAE).
 *     uint64_t VirtAddr -> the virtual address where to map the frame to.
 *     uint64_t PhysAddr -> the physical address of the frame to map to the page.
 */
void PAEPagingMap(uint64_t VirtAddr, uint64_t PhysAddr)
{
    char _CONST *ErrorFrameAlloc = "ERROR: Unable to allocate pages for the VMM.";

    PageDirEntry_t *PageDir;
    PageTableEntry_t *PageTable;

    PageDir = (PageDirEntry_t*)(uint32_t)(PDPT[PDPT_INDEX(VirtAddr)] & PAGE_MASK);

    // If page table isn't present, make one.
    if(!(PageDir[PD_INDEX(VirtAddr)] & PRESENT_BIT))
    {
        PageTable = (PageTableEntry_t*)AllocFrameFunc(POOL_BITMAP);
        if(!PageTable)
        {
            // Switch to text mode.
            VideoAPIFunc(VIDEO_VGA_SWITCH_MODE, MODE_80_25_TEXT);

            AbortBootFunc(ErrorFrameAlloc);
        }

        memset(PageTable, 0x00000000, PAGE_SIZE);

        PageDir[PD_INDEX(VirtAddr)] = (PageDirEntry_t)PageTable | PRESENT_BIT;
    }

    else
    {
        PageTable = (PageTableEntry_t*)(uint32_t)(PageDir[PD_INDEX(VirtAddr)] & PAGE_MASK);
    }

    PageTable[PT_INDEX(VirtAddr)] = PhysAddr | PRESENT_BIT;
}
Пример #2
0
bool arch_mm_context_read(struct vmm_context *ctx, void *output, addr_t address, size_t length)
{
	int pml4idx = PML4_INDEX(address);
	int pdptidx = PDPT_INDEX(address);
	int pdidx = PD_INDEX(address);

	addr_t destp;
	addr_t offset;
	addr_t *pml4v = (addr_t *)ctx->root_virtual;
	if(!pml4v[pml4idx]) {
		return false;
	}
	addr_t *pdptv = (addr_t *)((pml4v[pml4idx] & PAGE_MASK_PHYSICAL) + PHYS_PAGE_MAP);
	if(!pdptv[pdptidx]) {
		return false;
	}
	addr_t *pdv = (addr_t *)((pdptv[pdptidx] & PAGE_MASK_PHYSICAL) + PHYS_PAGE_MAP);
	if(!(pdv[pdidx] & PAGE_LARGE)) {
		int ptidx = PT_INDEX(address);
		offset = address & (0x1000 - 1);

		if(offset + length > 0x1000)
			PANIC(0, "mm_context_read crossed page boundary", EFAULT);

		if(!pdv[pdidx]) {
			return false;
		}
		addr_t *ptv = (addr_t *)((pdv[pdidx] & PAGE_MASK_PHYSICAL) + PHYS_PAGE_MAP);
		if(!ptv[ptidx]) {
			return false;
		}
		destp = ptv[ptidx] & PAGE_MASK_PHYSICAL;
	} else {
		offset = address & (0x200000 - 1);

		if(offset + length > 0x200000)
			PANIC(0, "mm_context_read crossed page boundary", EFAULT);

		if(!pdv[pdidx]) {
			return false;
		}
		destp = pdv[pdidx] & PAGE_MASK_PHYSICAL;
	}
	memcpy(output, (void *)(destp + PHYS_PAGE_MAP + offset), length);
	return true;
}
Пример #3
0
bool arch_mm_context_virtual_getmap(struct vmm_context *ctx, addr_t address, addr_t *phys, int *flags)
{
	int pml4idx = PML4_INDEX(address);
	int pdptidx = PDPT_INDEX(address);
	int pdidx = PD_INDEX(address);

	addr_t destp;
	addr_t *pml4v = (addr_t *)ctx->root_virtual;
	if(!pml4v[pml4idx]) {
		return false;
	}
	addr_t *pdptv = (addr_t *)((pml4v[pml4idx] & PAGE_MASK_PHYSICAL) + PHYS_PAGE_MAP);
	if(!pdptv[pdptidx]) {
		return false;
	}
	addr_t *pdv = (addr_t *)((pdptv[pdptidx] & PAGE_MASK_PHYSICAL) + PHYS_PAGE_MAP);
	if(!(pdv[pdidx] & PAGE_LARGE)) {
		int ptidx = PT_INDEX(address);

		if(!pdv[pdidx]) {
			return false;
		}
		addr_t *ptv = (addr_t *)((pdv[pdidx] & PAGE_MASK_PHYSICAL) + PHYS_PAGE_MAP);
		if(!ptv[ptidx]) {
			return false;
		}
		destp = ptv[ptidx];
	} else {
		if(!pdv[pdidx]) {
			return false;
		}
		destp = pdv[pdidx];
	}
	if(phys)
		*phys = destp & PAGE_MASK_PHYSICAL;
	if(flags)
		*flags = destp & ATTRIB_MASK;
	return true;
}