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]); } } } } }
Address X86Memory::lookupVirtual(X86Process *p, Address vaddr) { Address ret = ZERO; /* Map remote page tables. */ mapRemote(p, vaddr); /* Lookup the address, if mapped. */ if (remPageDir[DIRENTRY(vaddr)] & PAGE_PRESENT && remPageTab[TABENTRY(vaddr)] & PAGE_PRESENT) { ret = remPageTab[TABENTRY(vaddr)]; } return ret; }
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); }
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; }