Exemple #1
0
Address MemoryServer::findFreeRange(ProcessID procID, Size size)
{
    Address *pageDir, *pageTab, vaddr, vbegin;

    /* Initialize variables. */
    vbegin  = ZERO;
    vaddr   = 1024 * 1024 * 16;
    pageDir = PAGETABADDR_FROM(PAGETABFROM, PAGEUSERFROM);
    pageTab = PAGETABADDR_FROM(vaddr, PAGEUSERFROM);

    /* Map page tables. */
    VMCtl(procID, MapTables);

    /* Scan tables. */
    for (Size inc = PAGESIZE; DIRENTRY(vaddr) < PAGEDIR_MAX ; vaddr += inc)
    {
	/* Is the hole big enough? */
	if (vbegin && vaddr - vbegin >= size)
	{
	    break;
	}
	/* Increment per page table. */
	inc = PAGETAB_MAX * PAGESIZE;
	
	/* Try the current address. */
	if (pageDir[DIRENTRY(vaddr)] & PAGE_RESERVED)
	{
	    vbegin = ZERO; continue;
	}
	else if (pageDir[DIRENTRY(vaddr)] & PAGE_PRESENT)
	{
	    /* Look further into the page table. */
	    inc     = PAGESIZE;
	    pageTab = PAGETABADDR_FROM(vaddr, PAGEUSERFROM);
	
	    if (pageTab[TABENTRY(vaddr)] & PAGE_PRESENT)
	    {
		vbegin = ZERO; continue;
	    }
	}
	/* Reset start address if needed. */
	if (!vbegin)
	{
	    vbegin = vaddr;
	}
    }
    /* Clean up. */
    VMCtl(procID, UnMapTables);
    
    /* Done. */
    return vbegin;
}
Exemple #2
0
Address X86Memory::findFree(Address pageTabFrom, Address *pageDirPtr)
{
    Address  vaddr = 0xa0000000;
    Address *pageTabPtr = PAGETABADDR_FROM(vaddr, pageTabFrom);

    /* Find a free virtual address. */
    while (pageDirPtr[DIRENTRY(vaddr)] & PAGE_PRESENT &&
           pageTabPtr[TABENTRY(vaddr)] & PAGE_PRESENT)
    {
        /* Look for the next page in line. */
        vaddr     += PAGESIZE;
        pageTabPtr = PAGETABADDR_FROM(vaddr, pageTabFrom);
    }
    return vaddr;
}
Exemple #3
0
void MemoryServer::reservePrivate(MemoryMessage *msg)
{
    Address *pageDir;
    
    /* Verify virtual addresses. */
    if (!(msg->virtualAddress >= 1024*1024*16))
    {
	msg->result = EINVAL;
	return;
    }
    /* Point page directory. */
    pageDir = (Address *) PAGETABADDR_FROM(PAGETABFROM,
					   PAGEUSERFROM);
    /* Map page directory. */
    VMCtl(msg->from, MapTables);

    /* Loop directory. Mark them reserved. */
    for (Address i = msg->virtualAddress;
		 i < msg->virtualAddress + msg->bytes;
	         i += (PAGESIZE * PAGETAB_MAX))
    {
	pageDir[DIRENTRY(i)] |= PAGE_RESERVED;
    }
    /* Unmap. */
    VMCtl(msg->from, UnMapTables);
    
    /* Done. */
    msg->result = ESUCCESS;
}
Exemple #4
0
void X86Memory::releaseAll(X86Process *p)
{
    /* Map page tables. */
    mapRemote(p, 0x0);

    /* Mark all our physical pages free. */
    for (Size i = 0; i < 1024; i++)
    {
	/* May we release these physical pages? */
        if ((remPageDir[i] & PAGE_PRESENT) && !(remPageDir[i] & PAGE_PINNED))
        {
	    /* Repoint page table. */
            remPageTab = PAGETABADDR_FROM(i * PAGESIZE * 1024,
					  PAGETABFROM_REMOTE);

	    /* Scan page table. */
            for (Size j = 0; j < 1024; j++)
            {
                if (remPageTab[j] & PAGE_PRESENT && !(remPageTab[j] & PAGE_PINNED))
                {
                    memory->releasePhysical(remPageTab[j]);
                }
            }
        }
    }
}
Exemple #5
0
void X86Memory::mapRemote(X86Process *p, Address pageTabAddr,
			  Address pageDirAddr, ulong prot)
{
    /* Map remote page directory and page table. */
    myPageDir[DIRENTRY(pageDirAddr)] =
	p->getPageDirectory() | (PAGE_PRESENT|PAGE_RW|PAGE_PINNED|prot);
    remPageTab = PAGETABADDR_FROM(pageTabAddr, PAGETABFROM_REMOTE);
    
    /* Refresh entire TLB cache. */
    tlb_flush_all();
}
Exemple #6
0
bool X86Memory::access(X86Process *p, Address vaddr, Size sz, ulong prot)
{
    Size bytes = 0;
    Address vfrom = vaddr;

    /* Map remote pages. */
    mapRemote(p, vaddr);

    /* Verify protection bits. */
    while (bytes < sz &&
	   remPageDir[DIRENTRY(vaddr)] & prot &&
           remPageTab[TABENTRY(vaddr)] & prot)
    {
	vaddr += PAGESIZE;
	bytes += ((vfrom & PAGEMASK) + PAGESIZE) - vfrom;
	vfrom  = vaddr & PAGEMASK;
	remPageTab = PAGETABADDR_FROM(vaddr, PAGETABFROM_REMOTE);
    }
    /* Do we have a match? */
    return (bytes >= sz);
}
Exemple #7
0
Address X86Memory::mapVirtual(X86Process *p, Address paddr,
			      Address vaddr, ulong prot)
{
    /* Map remote pages. */
    mapRemote(p, vaddr);

    /* Virtual address specified? */
    if (vaddr == ZERO)
    {
	vaddr = findFree(PAGETABFROM_REMOTE, remPageDir);
    }
    /* Repoint to the correct (remote) page table. */
    remPageTab = PAGETABADDR_FROM(vaddr, PAGETABFROM_REMOTE);
    
    /* Does the remote process have the page table in memory? */
    if (!(remPageDir[DIRENTRY(vaddr)] & PAGE_PRESENT))
    {
	/* Nope, allocate a page table first. */
	Address newPageTab  = memory->allocatePhysical(PAGESIZE);
	newPageTab |= PAGE_PRESENT | PAGE_RW | prot;
	
	/* Map the new page table into remote memory. */
	remPageDir[DIRENTRY(vaddr)] = newPageTab;
	
	/* Update caches. */
	tlb_flush(remPageTab);
	
	/* Zero the new page. */
	memset(remPageTab, 0, PAGESIZE);
    }
    /* Map physical address to remote virtual address. */
    remPageTab[TABENTRY(vaddr)] = (paddr & PAGEMASK) | prot;
    tlb_flush(vaddr);

    /* Success. */
    return (Address) vaddr;
}