/* translate virtual address to pysical address. handles tlbmiss, page faults, loads page to physical memory in case of page fault */ int translate(VirtualAddress address, PhysicalAddress &physicalAddress) { int rval = status_success; PageEntry pageEntry; /* the page entry from page table. We use this for lookup in page table, and get frame no from it */ Page page; /* in case we need to get page from backing store and add it to physical memory */ FrameNumber frameno; /* in case we need to add page to physical memory */ PageNumber pageno = -1; /* page number we will lookkup. get this from virtual address */ int offset = -1; /* offset we will lookkup. get this from virtual address */ bool pagehit = false; /* flags */ bool tlbhit = false; /* break address to page no offset */ zlog(ZLOG_LOC, "VirtualMemoryManager::translate- get page number and offset\n"); pageno = getPageNumberFromLogicalAddress(address); offset = getOffsetFromLogicalAddress(address); /* we are storing he required frame number in the frameno value, weather we get a hit from tlb, page table or page fault */ /* check in tlb */ tlb.lookup(pageno, frameno, tlbhit); if(true == tlbhit) { /* we are done here */ zlog(ZLOG_LOC, "VirtualMemoryManager::translate - tlbhit !!\n"); tlbhits++; } else { /* check in page table tlb miss */ zlog(ZLOG_LOC, "VirtualMemoryManager::translate- get page entry for page no : %d\n", pageno); if(status_success != pageTable.lookup(pageno, pageEntry)) { rval = status_failure; zlog(ZLOG_LOC, "VirtualMemoryManager::translate- unable to get page table entry\n"); goto exit1; } /* check if this is a page fault */ zlog(ZLOG_LOC, "VirtualMemoryManager::translate- check for page fault\n"); if(true == pageEntry.isValid) { /* we are done */ zlog(ZLOG_LOC, "VirtualMemoryManager::translate- page hit! \n"); frameno = pageEntry.frameNumber; pagehit = true; /* update counter */ pagehits++; } /* page fault code */ if(false == pagehit) { /* update counter */ pagefaults++; /* get page from backing store */ zlog(ZLOG_LOC, "VirtualMemoryManager::translate- page fault on page : %d, reading block : %d from backing store\n", pageno, pageno); if(status_success != backingStore.getPage(page, pageno*PageSize, PageSize)) { zlog(ZLOG_LOC, "VirtualMemoryManager::translate- unable to get page form backing store\n"); rval = status_failure; goto exit2; } /* add to physical memory */ zlog(ZLOG_LOC, "VirtualMemoryManager::translate- putting the page in physical memory\n"); if(status_success != physicalMemory.addPage(page, frameno)) { zlog(ZLOG_LOC, "VirtualMemoryManager::translate- unable to add page to physical memory\n"); rval = status_failure; goto exit2; } /* update page entry */ zlog(ZLOG_LOC, "VirtualMemoryManager::translate- update page Entry \n"); pageEntry.frameNumber = frameno; pageEntry.isModified = false; pageEntry.isValid = true; /* add page entry to page table */ zlog(ZLOG_LOC, "VirtualMemoryManager::translate- update page table\n"); if(status_success != pageTable.updatePageEntry(pageEntry, pageno)) { zlog(ZLOG_LOC, "VirtualMemoryManager::translate- unable to add entry to page table\n"); rval = status_failure; goto exit2; } zlog(ZLOG_LOC, "VirtualMemoryManager::translate- lookup page table again\n"); frameno = pageEntry.frameNumber; pagehit = true; } /* by this time we have a valid page frame mapping if there was a tlb miss, update tlb table */ if(false == tlbhit) { TlbEntry tlbEntry; tlbEntry.pageNumber = pageno; tlbEntry.frameNumber = frameno; tlbEntry.valid = true; tlb.addEntry(tlbEntry); } } /* page entry contains the frame number required */ physicalAddress = (frameno << numBitsForFrameOffset) + offset; exit2: exit1: return rval; }