/* 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; }
int main(int argc, char **argv) { //cout<<argc<<endl; //srand((int)time(NULL)); /** * Configuration */ for(int i = 1; i < argc; i++) { if(i == 1) { if(strcmp(argv[i], "1") == 0) { debugMode = true; } else { debugMode = false; } } else if(i == 2) { sscanf(argv[i],"%d",&numberOfTLBEntries); numberOfTLBEntries = getNearestBiggerPowerOfTwo(numberOfTLBEntries); } else if(i == 3) { sscanf(argv[i],"%d",&numberOfPageFrames); numberOfPageFrames = getNearestBiggerPowerOfTwo(numberOfPageFrames); } else if(i == 4) { sscanf(argv[i],"%d",&numberOfInstructions); } else if(i == 5) { sscanf(argv[i],"%d",&pageChangeAfterInstructionCount); } } /** * Initial State */ cout<<"Debug Mode: "<<debugMode<<endl; cout<<"Total number of TLB Entries: "<<numberOfTLBEntries<<endl; cout<<"Total number of Page Frames: "<<numberOfPageFrames<<endl; cout<<"Total number of Instructions: "<<numberOfInstructions<<endl; cout<<"Total number of Virtual Pages: "<<numberOfVirtualPages<<endl; cout<<"On Average Virtual Address Page Changes after: "<<pageChangeAfterInstructionCount<<endl; /** * Operation starts... * Create a pageTable, a TLB */ PageTable pageTable; TranslationLookaheadBuffer tlb(numberOfTLBEntries); pageTable.setTranslationLookaheadBuffer(&tlb); for(int i = 0; i < numberOfInstructions; i++) { Instruction nextInstruction = getNextInstruction(); if(debugMode) { nextInstruction.print(); } LookupResult l = tlb.lookup(nextInstruction.msbAddress); if(l.isFound == true) { //do nothing } else { if(debugMode) { printf("Cache Miss for page %02x\n",nextInstruction.msbAddress); } totalNumberOfCacheMisses += 1; l = pageTable.lookup(nextInstruction.msbAddress); if(l.isFound == true) { //do nothing } else { if(debugMode) { printf("Page fault on page %02x\n",nextInstruction.msbAddress); } totalNumberOfPageFaults += 1; pageTable.insert(nextInstruction.msbAddress); l = pageTable.lookup(nextInstruction.msbAddress); } tlb.insert(nextInstruction.msbAddress, l.frameIndex); //pageTable.insert(nextInstruction.msbAddress); //l = pageTable.lookup(nextInstruction.msbAddress); } // if(debugMode) { printf("Virtual Address: %02x%02x, Physical Address: %02x%02x\n", nextInstruction.msbAddress, nextInstruction.lsbAddress, l.frameIndex, nextInstruction.lsbAddress); } } cout<<"Total number of Cache Misses: "<<totalNumberOfCacheMisses<<endl; cout<<"Total number of Page Faults: "<<totalNumberOfPageFaults<<endl; cout<<"Total number of Page Used: "<<pageTable.getUsedPageCount()<<endl; cout<<"Total number of Page Changed: "<<pageChangeCount<<endl; /*TranslationLookaheadBuffer tlb; unsigned char accessPattern[] = "ABACBDADEDAEBAC"; for(int i = 0; i < 15; i++) { cout<<i<<","<<accessPattern[i]<<endl; LookupResult result = tlb.lookup(accessPattern[i]); if(result.isFound) { tlb.print(); } else { cout<<"Cache Miss"<<endl; tlb.insert(accessPattern[i],accessPattern[i]); tlb.print(); } }*/ return 0; }