/******************************************************************************* * Looks up an address in the current page table. If the entry for the given * page is not valid, increments count_pagefaults and traps to the OS. * * @param vpn The virtual page number to lookup. * @param write If the access is a write, this is 1. Otherwise, it is 0. * @return The physical frame number of the page we are accessing. */ pfn_t pagetable_lookup(vpn_t vpn, int write) { pfn_t pfn = current_pagetable[vpn].pfn; /* CHANGE ME */ /* FIX ME - Part 2 * Determine the PFN corresponding to the passed in VPN. * Perform the lookup using the current_pagetable. */ if ((current_pagetable[vpn]).valid) { return pfn; } count_pagefaults++; return pagefault_handler(vpn, write); }
/******************************************************************************* * Looks up an address in the current page table. If the entry for the given * page is not valid, traps to the OS. * * @param vpn The virtual page number to lookup. * @param write If the access is a write, this is 1. Otherwise, it is 0. * @return The physical frame number of the page we are accessing. */ pfn_t pagetable_lookup(vpn_t vpn, int write) { pfn_t pfn; /* FIX ME - Part 2 * Determine the PFN corresponding to the passed in VPN. * current_pagetable variable accesses the process page table. * if the pagetable entry is not valid, increment count_pagefaults, call * pagefault_handler (traps to OS, returns frame number), and change pagetable * entry to now be valid */ if(!current_pagetable[vpn].valid){ count_pagefaults++; pfn = pagefault_handler(vpn,write); }else{ pfn = current_pagetable[vpn].pfn; } return pfn; }
/******************************************************************************* * Looks up an address in the current page table. If the entry for the given * page is not valid, increments count_pagefaults and traps to the OS. * * @param vpn The virtual page number to lookup. * @param write If the access is a write, this is 1. Otherwise, it is 0. * @return The physical frame number of the page we are accessing. */ pfn_t pagetable_lookup(vpn_t vpn, int write) { pfn_t pfn; /* Determine the PFN corresponding to the passed in VPN. * Perform the lookup using the current_pagetable. */ pte_t *pte = current_pagetable + vpn; pte->used = 1; // mark virtual frame as used if (pte->valid) { pfn = pte->pfn; // get physical frame number } else { // page fault! count_pagefaults++; pfn = pagefault_handler(vpn, write); // trap into pagefault_handler } return pfn; }
int MMU(int pid, int addr, char type) { int frameNo; int pageNo = (addr >> 8); int offset = addr - (pageNo << 8); int physicalAddr; bool tlb_hit = false; bool page_hit = false; int lru; int tlbFrame = pageNo % (TLB_ENTRY/2); if(pageNo > NUM_PAGE) { printf("invalid page number (NUM_PAGE = 0x%x): pid %d, addr %x\n", NUM_PAGE, pid, addr); return -1; } if(pid > NUM_PROC-1) { printf("invalid pid (NUM_PROC = %d): pid %d, addr %x\n", NUM_PROC, pid, addr); return -1; } for(int i = 0; i < 2; i++) { int check = tlb[pid][tlbFrame].entry[i]; if (tlb[pid][tlbFrame].valid[i] && check == pageNo) { tlb_hit = true; tlb[pid][tlbFrame].lru = !tlb[pid][tlbFrame].lru; pageTable.stats.tlbHitCount++; frameNo = tlb[pid][tlbFrame].frameNo[i]; break; } } if (pageTable.entry[pid][pageNo].valid) { page_hit = true; pageTable.stats.hitCount++; if (!tlb_hit) { if (replacementPolicy == LRU) { lruHelper(pageTable.entry[pid][pageNo].frameNo); } if (replacementPolicy == CLOCK) { clockHelper(pageTable.entry[pid][pageNo].frameNo); } } } else { frameNo = pagefault_handler(pid, pageNo, type); disk_read(frameNo, pid, pageNo); pageTable.stats.missCount++; } if (!tlb_hit) { lru = tlb[pid][tlbFrame].lru; tlb[pid][tlbFrame].entry[lru] = pageNo; tlb[pid][tlbFrame].frameNo[lru] = frameNo; tlb[pid][tlbFrame].lru = !lru; tlb[pid][tlbFrame].valid[lru] = true; pageTable.stats.tlbMissCount++; pageTable.entry[pid][pageNo].dirty = true; } physicalAddr = (frameNo << 8) + offset; print_result(pid, type, tlb_hit, page_hit, addr, physicalAddr); return physicalAddr; }