tlb.cc revision 5736
14997Sgblack@eecs.umich.edu/* 25268Sksewell@umich.edu * Copyright (c) 2001-2005 The Regents of The University of Michigan 35254Sksewell@umich.edu * Copyright (c) 2007 MIPS Technologies, Inc. 45254Sksewell@umich.edu * All rights reserved. 54997Sgblack@eecs.umich.edu * 65254Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 75254Sksewell@umich.edu * modification, are permitted provided that the following conditions are 85254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 95254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 105254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 115254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 125254Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 135254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 145254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 155254Sksewell@umich.edu * this software without specific prior written permission. 164997Sgblack@eecs.umich.edu * 175254Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 185254Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 195254Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 205254Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 215254Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 225254Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 235254Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 245254Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 255254Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 265254Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 275254Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 284997Sgblack@eecs.umich.edu * 295268Sksewell@umich.edu * Authors: Nathan Binkert 305268Sksewell@umich.edu * Steve Reinhardt 315268Sksewell@umich.edu * Jaidev Patwardhan 324997Sgblack@eecs.umich.edu */ 334997Sgblack@eecs.umich.edu 345222Sksewell@umich.edu#include <string> 355222Sksewell@umich.edu#include <vector> 364997Sgblack@eecs.umich.edu 375222Sksewell@umich.edu#include "arch/mips/pra_constants.hh" 385222Sksewell@umich.edu#include "arch/mips/pagetable.hh" 394997Sgblack@eecs.umich.edu#include "arch/mips/tlb.hh" 405222Sksewell@umich.edu#include "arch/mips/faults.hh" 415222Sksewell@umich.edu#include "arch/mips/utility.hh" 425222Sksewell@umich.edu#include "base/inifile.hh" 435222Sksewell@umich.edu#include "base/str.hh" 445222Sksewell@umich.edu#include "base/trace.hh" 455222Sksewell@umich.edu#include "cpu/thread_context.hh" 465224Sksewell@umich.edu#include "sim/process.hh" 475224Sksewell@umich.edu#include "mem/page_table.hh" 485222Sksewell@umich.edu#include "params/MipsDTB.hh" 495222Sksewell@umich.edu#include "params/MipsITB.hh" 505222Sksewell@umich.edu#include "params/MipsTLB.hh" 515222Sksewell@umich.edu#include "params/MipsUTB.hh" 524997Sgblack@eecs.umich.edu 535019Sgblack@eecs.umich.edu 545222Sksewell@umich.eduusing namespace std; 555222Sksewell@umich.eduusing namespace MipsISA; 565019Sgblack@eecs.umich.edu 575222Sksewell@umich.edu/////////////////////////////////////////////////////////////////////// 585222Sksewell@umich.edu// 595222Sksewell@umich.edu// MIPS TLB 605222Sksewell@umich.edu// 615019Sgblack@eecs.umich.edu 625543Ssaidi@eecs.umich.edu#define MODE2MASK(X) (1 << (X)) 635222Sksewell@umich.edu 645222Sksewell@umich.eduTLB::TLB(const Params *p) 655358Sgblack@eecs.umich.edu : BaseTLB(p), size(p->size), nlu(0) 665222Sksewell@umich.edu{ 675222Sksewell@umich.edu table = new MipsISA::PTE[size]; 685222Sksewell@umich.edu memset(table, 0, sizeof(MipsISA::PTE[size])); 695222Sksewell@umich.edu smallPages=0; 705222Sksewell@umich.edu} 715222Sksewell@umich.edu 725222Sksewell@umich.eduTLB::~TLB() 735222Sksewell@umich.edu{ 745222Sksewell@umich.edu if (table) 755222Sksewell@umich.edu delete [] table; 765222Sksewell@umich.edu} 775222Sksewell@umich.edu 785222Sksewell@umich.edu// look up an entry in the TLB 795222Sksewell@umich.eduMipsISA::PTE * 805222Sksewell@umich.eduTLB::lookup(Addr vpn, uint8_t asn) const 815222Sksewell@umich.edu{ 825222Sksewell@umich.edu // assume not found... 835222Sksewell@umich.edu MipsISA::PTE *retval = NULL; 845222Sksewell@umich.edu PageTable::const_iterator i = lookupTable.find(vpn); 855222Sksewell@umich.edu if (i != lookupTable.end()) { 865222Sksewell@umich.edu while (i->first == vpn) { 875222Sksewell@umich.edu int index = i->second; 885222Sksewell@umich.edu MipsISA::PTE *pte = &table[index]; 895222Sksewell@umich.edu 905222Sksewell@umich.edu /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 915222Sksewell@umich.edu Addr Mask = pte->Mask; 925222Sksewell@umich.edu Addr InvMask = ~Mask; 935222Sksewell@umich.edu Addr VPN = pte->VPN; 945543Ssaidi@eecs.umich.edu // warn("Valid: %d - %d\n",pte->V0,pte->V1); 955222Sksewell@umich.edu if(((vpn & InvMask) == (VPN & InvMask)) && (pte->G || (asn == pte->asid))) 965222Sksewell@umich.edu { // We have a VPN + ASID Match 975222Sksewell@umich.edu retval = pte; 985222Sksewell@umich.edu break; 995222Sksewell@umich.edu } 1005222Sksewell@umich.edu ++i; 1015222Sksewell@umich.edu } 1025019Sgblack@eecs.umich.edu } 1035019Sgblack@eecs.umich.edu 1045222Sksewell@umich.edu DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, 1055222Sksewell@umich.edu retval ? "hit" : "miss", retval ? retval->PFN1 : 0); 1065222Sksewell@umich.edu return retval; 1075222Sksewell@umich.edu} 1085222Sksewell@umich.edu 1095222Sksewell@umich.eduMipsISA::PTE* TLB::getEntry(unsigned Index) const 1105222Sksewell@umich.edu{ 1115222Sksewell@umich.edu // Make sure that Index is valid 1125222Sksewell@umich.edu assert(Index<size); 1135222Sksewell@umich.edu return &table[Index]; 1145222Sksewell@umich.edu} 1155222Sksewell@umich.edu 1165222Sksewell@umich.eduint TLB::probeEntry(Addr vpn,uint8_t asn) const 1175222Sksewell@umich.edu{ 1185222Sksewell@umich.edu // assume not found... 1195222Sksewell@umich.edu MipsISA::PTE *retval = NULL; 1205222Sksewell@umich.edu int Ind=-1; 1215222Sksewell@umich.edu PageTable::const_iterator i = lookupTable.find(vpn); 1225222Sksewell@umich.edu if (i != lookupTable.end()) { 1235222Sksewell@umich.edu while (i->first == vpn) { 1245222Sksewell@umich.edu int index = i->second; 1255222Sksewell@umich.edu MipsISA::PTE *pte = &table[index]; 1265222Sksewell@umich.edu 1275222Sksewell@umich.edu /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 1285222Sksewell@umich.edu Addr Mask = pte->Mask; 1295222Sksewell@umich.edu Addr InvMask = ~Mask; 1305222Sksewell@umich.edu Addr VPN = pte->VPN; 1315222Sksewell@umich.edu if(((vpn & InvMask) == (VPN & InvMask)) && (pte->G || (asn == pte->asid))) 1325222Sksewell@umich.edu { // We have a VPN + ASID Match 1335222Sksewell@umich.edu retval = pte; 1345222Sksewell@umich.edu Ind = index; 1355222Sksewell@umich.edu break; 1365222Sksewell@umich.edu } 1375222Sksewell@umich.edu 1385222Sksewell@umich.edu ++i; 1395222Sksewell@umich.edu } 1405222Sksewell@umich.edu } 1415222Sksewell@umich.edu DPRINTF(MipsPRA,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind); 1425222Sksewell@umich.edu return Ind; 1435222Sksewell@umich.edu} 1445222Sksewell@umich.eduFault inline 1455222Sksewell@umich.eduTLB::checkCacheability(RequestPtr &req) 1465222Sksewell@umich.edu{ 1475222Sksewell@umich.edu Addr VAddrUncacheable = 0xA0000000; 1485222Sksewell@umich.edu // In MIPS, cacheability is controlled by certain bits of the virtual address 1495222Sksewell@umich.edu // or by the TLB entry 1505222Sksewell@umich.edu if((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) { 1515222Sksewell@umich.edu // mark request as uncacheable 1525736Snate@binkert.org req->setFlags(Request::UNCACHEABLE); 1535222Sksewell@umich.edu } 1545222Sksewell@umich.edu return NoFault; 1555222Sksewell@umich.edu} 1565222Sksewell@umich.eduvoid TLB::insertAt(MipsISA::PTE &pte, unsigned Index, int _smallPages) 1575222Sksewell@umich.edu{ 1585222Sksewell@umich.edu smallPages=_smallPages; 1595222Sksewell@umich.edu if(Index > size){ 1605222Sksewell@umich.edu warn("Attempted to write at index (%d) beyond TLB size (%d)",Index,size); 1615222Sksewell@umich.edu } else { 1625222Sksewell@umich.edu // Update TLB 1635222Sksewell@umich.edu DPRINTF(TLB,"TLB[%d]: %x %x %x %x\n",Index,pte.Mask<<11,((pte.VPN << 11) | pte.asid),((pte.PFN0 <<6) | (pte.C0 << 3) | (pte.D0 << 2) | (pte.V0 <<1) | pte.G), 1645222Sksewell@umich.edu ((pte.PFN1 <<6) | (pte.C1 << 3) | (pte.D1 << 2) | (pte.V1 <<1) | pte.G)); 1655222Sksewell@umich.edu if(table[Index].V0 == true || table[Index].V1 == true){ // Previous entry is valid 1665222Sksewell@umich.edu PageTable::iterator i = lookupTable.find(table[Index].VPN); 1675222Sksewell@umich.edu lookupTable.erase(i); 1685222Sksewell@umich.edu } 1695222Sksewell@umich.edu table[Index]=pte; 1705222Sksewell@umich.edu // Update fast lookup table 1715222Sksewell@umich.edu lookupTable.insert(make_pair(table[Index].VPN, Index)); 1725222Sksewell@umich.edu // int TestIndex=probeEntry(pte.VPN,pte.asid); 1735222Sksewell@umich.edu // warn("Inserted at: %d, Found at: %d (%x)\n",Index,TestIndex,pte.Mask); 1745222Sksewell@umich.edu } 1755222Sksewell@umich.edu 1765222Sksewell@umich.edu} 1775222Sksewell@umich.edu 1785222Sksewell@umich.edu// insert a new TLB entry 1795222Sksewell@umich.eduvoid 1805222Sksewell@umich.eduTLB::insert(Addr addr, MipsISA::PTE &pte) 1815222Sksewell@umich.edu{ 1825222Sksewell@umich.edu fatal("TLB Insert not yet implemented\n"); 1835222Sksewell@umich.edu 1845222Sksewell@umich.edu 1855222Sksewell@umich.edu /* MipsISA::VAddr vaddr = addr; 1865222Sksewell@umich.edu if (table[nlu].valid) { 1875222Sksewell@umich.edu Addr oldvpn = table[nlu].tag; 1885222Sksewell@umich.edu PageTable::iterator i = lookupTable.find(oldvpn); 1895222Sksewell@umich.edu 1905222Sksewell@umich.edu if (i == lookupTable.end()) 1915222Sksewell@umich.edu panic("TLB entry not found in lookupTable"); 1925222Sksewell@umich.edu 1935222Sksewell@umich.edu int index; 1945222Sksewell@umich.edu while ((index = i->second) != nlu) { 1955222Sksewell@umich.edu if (table[index].tag != oldvpn) 1965222Sksewell@umich.edu panic("TLB entry not found in lookupTable"); 1975222Sksewell@umich.edu 1985222Sksewell@umich.edu ++i; 1995222Sksewell@umich.edu } 2005222Sksewell@umich.edu 2015222Sksewell@umich.edu DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); 2025222Sksewell@umich.edu 2035222Sksewell@umich.edu lookupTable.erase(i); 2045014Sgblack@eecs.umich.edu } 2055014Sgblack@eecs.umich.edu 2065222Sksewell@umich.edu DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn); 2075222Sksewell@umich.edu 2085222Sksewell@umich.edu table[nlu] = pte; 2095222Sksewell@umich.edu table[nlu].tag = vaddr.vpn(); 2105222Sksewell@umich.edu table[nlu].valid = true; 2115222Sksewell@umich.edu 2125222Sksewell@umich.edu lookupTable.insert(make_pair(vaddr.vpn(), nlu)); 2135222Sksewell@umich.edu nextnlu(); 2145222Sksewell@umich.edu */ 2155222Sksewell@umich.edu} 2165222Sksewell@umich.edu 2175222Sksewell@umich.eduvoid 2185222Sksewell@umich.eduTLB::flushAll() 2195222Sksewell@umich.edu{ 2205222Sksewell@umich.edu DPRINTF(TLB, "flushAll\n"); 2215222Sksewell@umich.edu memset(table, 0, sizeof(MipsISA::PTE[size])); 2225222Sksewell@umich.edu lookupTable.clear(); 2235222Sksewell@umich.edu nlu = 0; 2245222Sksewell@umich.edu} 2255222Sksewell@umich.edu 2265222Sksewell@umich.eduvoid 2275222Sksewell@umich.eduTLB::serialize(ostream &os) 2285222Sksewell@umich.edu{ 2295222Sksewell@umich.edu SERIALIZE_SCALAR(size); 2305222Sksewell@umich.edu SERIALIZE_SCALAR(nlu); 2315222Sksewell@umich.edu 2325222Sksewell@umich.edu for (int i = 0; i < size; i++) { 2335222Sksewell@umich.edu nameOut(os, csprintf("%s.PTE%d", name(), i)); 2345222Sksewell@umich.edu table[i].serialize(os); 2355222Sksewell@umich.edu } 2365222Sksewell@umich.edu} 2375222Sksewell@umich.edu 2385222Sksewell@umich.eduvoid 2395222Sksewell@umich.eduTLB::unserialize(Checkpoint *cp, const string §ion) 2405222Sksewell@umich.edu{ 2415222Sksewell@umich.edu UNSERIALIZE_SCALAR(size); 2425222Sksewell@umich.edu UNSERIALIZE_SCALAR(nlu); 2435222Sksewell@umich.edu 2445222Sksewell@umich.edu for (int i = 0; i < size; i++) { 2455222Sksewell@umich.edu table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); 2465222Sksewell@umich.edu if (table[i].V0 || table[i].V1) { 2475222Sksewell@umich.edu lookupTable.insert(make_pair(table[i].VPN, i)); 2485222Sksewell@umich.edu } 2495222Sksewell@umich.edu } 2505222Sksewell@umich.edu} 2515222Sksewell@umich.edu 2525222Sksewell@umich.eduvoid 2535222Sksewell@umich.eduTLB::regStats() 2545222Sksewell@umich.edu{ 2555222Sksewell@umich.edu read_hits 2565222Sksewell@umich.edu .name(name() + ".read_hits") 2575222Sksewell@umich.edu .desc("DTB read hits") 2585222Sksewell@umich.edu ; 2595222Sksewell@umich.edu 2605222Sksewell@umich.edu read_misses 2615222Sksewell@umich.edu .name(name() + ".read_misses") 2625222Sksewell@umich.edu .desc("DTB read misses") 2635222Sksewell@umich.edu ; 2645222Sksewell@umich.edu 2655222Sksewell@umich.edu 2665222Sksewell@umich.edu read_accesses 2675222Sksewell@umich.edu .name(name() + ".read_accesses") 2685222Sksewell@umich.edu .desc("DTB read accesses") 2695222Sksewell@umich.edu ; 2705222Sksewell@umich.edu 2715222Sksewell@umich.edu write_hits 2725222Sksewell@umich.edu .name(name() + ".write_hits") 2735222Sksewell@umich.edu .desc("DTB write hits") 2745222Sksewell@umich.edu ; 2755222Sksewell@umich.edu 2765222Sksewell@umich.edu write_misses 2775222Sksewell@umich.edu .name(name() + ".write_misses") 2785222Sksewell@umich.edu .desc("DTB write misses") 2795222Sksewell@umich.edu ; 2805222Sksewell@umich.edu 2815222Sksewell@umich.edu 2825222Sksewell@umich.edu write_accesses 2835222Sksewell@umich.edu .name(name() + ".write_accesses") 2845222Sksewell@umich.edu .desc("DTB write accesses") 2855222Sksewell@umich.edu ; 2865222Sksewell@umich.edu 2875222Sksewell@umich.edu hits 2885222Sksewell@umich.edu .name(name() + ".hits") 2895222Sksewell@umich.edu .desc("DTB hits") 2905222Sksewell@umich.edu ; 2915222Sksewell@umich.edu 2925222Sksewell@umich.edu misses 2935222Sksewell@umich.edu .name(name() + ".misses") 2945222Sksewell@umich.edu .desc("DTB misses") 2955222Sksewell@umich.edu ; 2965222Sksewell@umich.edu 2975222Sksewell@umich.edu invalids 2985222Sksewell@umich.edu .name(name() + ".invalids") 2995222Sksewell@umich.edu .desc("DTB access violations") 3005222Sksewell@umich.edu ; 3015222Sksewell@umich.edu 3025222Sksewell@umich.edu accesses 3035222Sksewell@umich.edu .name(name() + ".accesses") 3045222Sksewell@umich.edu .desc("DTB accesses") 3055222Sksewell@umich.edu ; 3065222Sksewell@umich.edu 3075222Sksewell@umich.edu hits = read_hits + write_hits; 3085222Sksewell@umich.edu misses = read_misses + write_misses; 3095222Sksewell@umich.edu accesses = read_accesses + write_accesses; 3105222Sksewell@umich.edu} 3115222Sksewell@umich.edu 3125222Sksewell@umich.eduFault 3135222Sksewell@umich.eduITB::translate(RequestPtr &req, ThreadContext *tc) 3145222Sksewell@umich.edu{ 3155224Sksewell@umich.edu#if !FULL_SYSTEM 3165224Sksewell@umich.edu Process * p = tc->getProcessPtr(); 3175224Sksewell@umich.edu 3185224Sksewell@umich.edu Fault fault = p->pTable->translate(req); 3195224Sksewell@umich.edu if(fault != NoFault) 3205224Sksewell@umich.edu return fault; 3215224Sksewell@umich.edu 3225224Sksewell@umich.edu return NoFault; 3235224Sksewell@umich.edu#else 3245222Sksewell@umich.edu if(MipsISA::IsKSeg0(req->getVaddr())) 3255014Sgblack@eecs.umich.edu { 3265222Sksewell@umich.edu // Address will not be translated through TLB, set response, and go! 3275222Sksewell@umich.edu req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); 3285222Sksewell@umich.edu if(MipsISA::getOperatingMode(tc->readMiscReg(MipsISA::Status)) != mode_kernel || req->isMisaligned()) 3295222Sksewell@umich.edu { 3305222Sksewell@umich.edu AddressErrorFault *Flt = new AddressErrorFault(); 3315222Sksewell@umich.edu /* BadVAddr must be set */ 3325222Sksewell@umich.edu Flt->BadVAddr = req->getVaddr(); 3335222Sksewell@umich.edu return Flt; 3345222Sksewell@umich.edu } 3355014Sgblack@eecs.umich.edu } 3365222Sksewell@umich.edu else if(MipsISA::IsKSeg1(req->getVaddr())) 3375222Sksewell@umich.edu { 3385222Sksewell@umich.edu // Address will not be translated through TLB, set response, and go! 3395222Sksewell@umich.edu req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); 3405222Sksewell@umich.edu } 3415222Sksewell@umich.edu else 3425222Sksewell@umich.edu { 3435222Sksewell@umich.edu /* This is an optimization - smallPages is updated every time a TLB operation is performed 3445222Sksewell@umich.edu That way, we don't need to look at Config3 _ SP and PageGrain _ ESP every time we 3455222Sksewell@umich.edu do a TLB lookup */ 3465222Sksewell@umich.edu Addr VPN; 3475222Sksewell@umich.edu if(smallPages==1){ 3485222Sksewell@umich.edu VPN=((req->getVaddr() >> 11)); 3495222Sksewell@umich.edu } else { 3505222Sksewell@umich.edu VPN=((req->getVaddr() >> 11) & 0xFFFFFFFC); 3515222Sksewell@umich.edu } 3525222Sksewell@umich.edu uint8_t Asid = req->getAsid(); 3535222Sksewell@umich.edu if(req->isMisaligned()){ // Unaligned address! 3545222Sksewell@umich.edu AddressErrorFault *Flt = new AddressErrorFault(); 3555222Sksewell@umich.edu /* BadVAddr must be set */ 3565222Sksewell@umich.edu Flt->BadVAddr = req->getVaddr(); 3575222Sksewell@umich.edu return Flt; 3585222Sksewell@umich.edu } 3595222Sksewell@umich.edu MipsISA::PTE *pte = lookup(VPN,Asid); 3605222Sksewell@umich.edu if(pte != NULL) 3615222Sksewell@umich.edu {// Ok, found something 3625222Sksewell@umich.edu /* Check for valid bits */ 3635222Sksewell@umich.edu int EvenOdd; 3645222Sksewell@umich.edu bool Valid; 3655222Sksewell@umich.edu if((((req->getVaddr()) >> pte->AddrShiftAmount) & 1) ==0){ 3665222Sksewell@umich.edu // Check even bits 3675222Sksewell@umich.edu Valid = pte->V0; 3685222Sksewell@umich.edu EvenOdd = 0; 3695222Sksewell@umich.edu } else { 3705222Sksewell@umich.edu // Check odd bits 3715222Sksewell@umich.edu Valid = pte->V1; 3725222Sksewell@umich.edu EvenOdd = 1; 3735222Sksewell@umich.edu } 3745222Sksewell@umich.edu 3755222Sksewell@umich.edu if(Valid == false) 3765222Sksewell@umich.edu {//Invalid entry 3775222Sksewell@umich.edu ItbInvalidFault *Flt = new ItbInvalidFault(); 3785222Sksewell@umich.edu /* EntryHi VPN, ASID fields must be set */ 3795222Sksewell@umich.edu Flt->EntryHi_Asid = Asid; 3805222Sksewell@umich.edu Flt->EntryHi_VPN2 = (VPN>>2); 3815222Sksewell@umich.edu Flt->EntryHi_VPN2X = (VPN & 0x3); 3825222Sksewell@umich.edu 3835222Sksewell@umich.edu /* BadVAddr must be set */ 3845222Sksewell@umich.edu Flt->BadVAddr = req->getVaddr(); 3855222Sksewell@umich.edu 3865222Sksewell@umich.edu /* Context must be set */ 3875222Sksewell@umich.edu Flt->Context_BadVPN2 = (VPN >> 2); 3885222Sksewell@umich.edu return Flt; 3895222Sksewell@umich.edu } 3905222Sksewell@umich.edu else 3915222Sksewell@umich.edu {// Ok, this is really a match, set paddr 3925543Ssaidi@eecs.umich.edu // hits++; 3935222Sksewell@umich.edu Addr PAddr; 3945222Sksewell@umich.edu if(EvenOdd == 0){ 3955222Sksewell@umich.edu PAddr = pte->PFN0; 3965222Sksewell@umich.edu }else{ 3975222Sksewell@umich.edu PAddr = pte->PFN1; 3985222Sksewell@umich.edu } 3995222Sksewell@umich.edu PAddr >>= (pte->AddrShiftAmount-12); 4005222Sksewell@umich.edu PAddr <<= pte->AddrShiftAmount; 4015222Sksewell@umich.edu PAddr |= ((req->getVaddr()) & pte->OffsetMask); 4025222Sksewell@umich.edu req->setPaddr(PAddr); 4035222Sksewell@umich.edu 4045222Sksewell@umich.edu 4055222Sksewell@umich.edu } 4065222Sksewell@umich.edu } 4075222Sksewell@umich.edu else 4085222Sksewell@umich.edu { // Didn't find any match, return a TLB Refill Exception 4095543Ssaidi@eecs.umich.edu // misses++; 4105222Sksewell@umich.edu ItbRefillFault *Flt=new ItbRefillFault(); 4115222Sksewell@umich.edu /* EntryHi VPN, ASID fields must be set */ 4125222Sksewell@umich.edu Flt->EntryHi_Asid = Asid; 4135222Sksewell@umich.edu Flt->EntryHi_VPN2 = (VPN>>2); 4145222Sksewell@umich.edu Flt->EntryHi_VPN2X = (VPN & 0x3); 4155222Sksewell@umich.edu 4165222Sksewell@umich.edu 4175222Sksewell@umich.edu /* BadVAddr must be set */ 4185222Sksewell@umich.edu Flt->BadVAddr = req->getVaddr(); 4195222Sksewell@umich.edu 4205222Sksewell@umich.edu /* Context must be set */ 4215222Sksewell@umich.edu Flt->Context_BadVPN2 = (VPN >> 2); 4225222Sksewell@umich.edu return Flt; 4235222Sksewell@umich.edu } 4245222Sksewell@umich.edu } 4255222Sksewell@umich.edu return checkCacheability(req); 4265224Sksewell@umich.edu#endif 4275222Sksewell@umich.edu} 4285222Sksewell@umich.edu 4295222Sksewell@umich.eduFault 4305222Sksewell@umich.eduDTB::translate(RequestPtr &req, ThreadContext *tc, bool write) 4315222Sksewell@umich.edu{ 4325224Sksewell@umich.edu#if !FULL_SYSTEM 4335224Sksewell@umich.edu Process * p = tc->getProcessPtr(); 4345224Sksewell@umich.edu 4355224Sksewell@umich.edu Fault fault = p->pTable->translate(req); 4365224Sksewell@umich.edu if(fault != NoFault) 4375224Sksewell@umich.edu return fault; 4385224Sksewell@umich.edu 4395224Sksewell@umich.edu return NoFault; 4405224Sksewell@umich.edu#else 4415222Sksewell@umich.edu if(MipsISA::IsKSeg0(req->getVaddr())) 4425222Sksewell@umich.edu { 4435222Sksewell@umich.edu // Address will not be translated through TLB, set response, and go! 4445222Sksewell@umich.edu req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); 4455222Sksewell@umich.edu if(MipsISA::getOperatingMode(tc->readMiscReg(MipsISA::Status)) != mode_kernel || req->isMisaligned()) 4465222Sksewell@umich.edu { 4475222Sksewell@umich.edu StoreAddressErrorFault *Flt = new StoreAddressErrorFault(); 4485222Sksewell@umich.edu /* BadVAddr must be set */ 4495222Sksewell@umich.edu Flt->BadVAddr = req->getVaddr(); 4505222Sksewell@umich.edu 4515222Sksewell@umich.edu return Flt; 4525222Sksewell@umich.edu } 4535222Sksewell@umich.edu } 4545222Sksewell@umich.edu else if(MipsISA::IsKSeg1(req->getVaddr())) 4555222Sksewell@umich.edu { 4565222Sksewell@umich.edu // Address will not be translated through TLB, set response, and go! 4575222Sksewell@umich.edu req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); 4585222Sksewell@umich.edu } 4595222Sksewell@umich.edu else 4605222Sksewell@umich.edu { 4615222Sksewell@umich.edu /* This is an optimization - smallPages is updated every time a TLB operation is performed 4625222Sksewell@umich.edu That way, we don't need to look at Config3 _ SP and PageGrain _ ESP every time we 4635222Sksewell@umich.edu do a TLB lookup */ 4645222Sksewell@umich.edu Addr VPN=((req->getVaddr() >> 11) & 0xFFFFFFFC); 4655222Sksewell@umich.edu if(smallPages==1){ 4665222Sksewell@umich.edu VPN=((req->getVaddr() >> 11)); 4675222Sksewell@umich.edu } 4685222Sksewell@umich.edu uint8_t Asid = req->getAsid(); 4695222Sksewell@umich.edu MipsISA::PTE *pte = lookup(VPN,Asid); 4705222Sksewell@umich.edu if(req->isMisaligned()){ // Unaligned address! 4715222Sksewell@umich.edu StoreAddressErrorFault *Flt = new StoreAddressErrorFault(); 4725222Sksewell@umich.edu /* BadVAddr must be set */ 4735222Sksewell@umich.edu Flt->BadVAddr = req->getVaddr(); 4745222Sksewell@umich.edu return Flt; 4755222Sksewell@umich.edu } 4765222Sksewell@umich.edu if(pte != NULL) 4775222Sksewell@umich.edu {// Ok, found something 4785222Sksewell@umich.edu /* Check for valid bits */ 4795222Sksewell@umich.edu int EvenOdd; 4805222Sksewell@umich.edu bool Valid; 4815222Sksewell@umich.edu bool Dirty; 4825222Sksewell@umich.edu if(((((req->getVaddr()) >> pte->AddrShiftAmount) & 1)) ==0){ 4835222Sksewell@umich.edu // Check even bits 4845222Sksewell@umich.edu Valid = pte->V0; 4855222Sksewell@umich.edu Dirty = pte->D0; 4865222Sksewell@umich.edu EvenOdd = 0; 4875222Sksewell@umich.edu 4885222Sksewell@umich.edu } else { 4895222Sksewell@umich.edu // Check odd bits 4905222Sksewell@umich.edu Valid = pte->V1; 4915222Sksewell@umich.edu Dirty = pte->D1; 4925222Sksewell@umich.edu EvenOdd = 1; 4935222Sksewell@umich.edu } 4945222Sksewell@umich.edu 4955222Sksewell@umich.edu if(Valid == false) 4965222Sksewell@umich.edu {//Invalid entry 4975543Ssaidi@eecs.umich.edu // invalids++; 4985222Sksewell@umich.edu DtbInvalidFault *Flt = new DtbInvalidFault(); 4995222Sksewell@umich.edu /* EntryHi VPN, ASID fields must be set */ 5005222Sksewell@umich.edu Flt->EntryHi_Asid = Asid; 5015222Sksewell@umich.edu Flt->EntryHi_VPN2 = (VPN>>2); 5025222Sksewell@umich.edu Flt->EntryHi_VPN2X = (VPN & 0x3); 5035222Sksewell@umich.edu 5045222Sksewell@umich.edu 5055222Sksewell@umich.edu /* BadVAddr must be set */ 5065222Sksewell@umich.edu Flt->BadVAddr = req->getVaddr(); 5075222Sksewell@umich.edu 5085222Sksewell@umich.edu /* Context must be set */ 5095222Sksewell@umich.edu Flt->Context_BadVPN2 = (VPN >> 2); 5105222Sksewell@umich.edu 5115222Sksewell@umich.edu return Flt; 5125222Sksewell@umich.edu } 5135222Sksewell@umich.edu else 5145222Sksewell@umich.edu {// Ok, this is really a match, set paddr 5155543Ssaidi@eecs.umich.edu // hits++; 5165222Sksewell@umich.edu if(!Dirty) 5175222Sksewell@umich.edu { 5185222Sksewell@umich.edu TLBModifiedFault *Flt = new TLBModifiedFault(); 5195222Sksewell@umich.edu /* EntryHi VPN, ASID fields must be set */ 5205222Sksewell@umich.edu Flt->EntryHi_Asid = Asid; 5215222Sksewell@umich.edu Flt->EntryHi_VPN2 = (VPN>>2); 5225222Sksewell@umich.edu Flt->EntryHi_VPN2X = (VPN & 0x3); 5235222Sksewell@umich.edu 5245222Sksewell@umich.edu 5255222Sksewell@umich.edu /* BadVAddr must be set */ 5265222Sksewell@umich.edu Flt->BadVAddr = req->getVaddr(); 5275222Sksewell@umich.edu 5285222Sksewell@umich.edu /* Context must be set */ 5295222Sksewell@umich.edu Flt->Context_BadVPN2 = (VPN >> 2); 5305222Sksewell@umich.edu return Flt; 5315222Sksewell@umich.edu 5325222Sksewell@umich.edu } 5335222Sksewell@umich.edu Addr PAddr; 5345222Sksewell@umich.edu if(EvenOdd == 0){ 5355222Sksewell@umich.edu PAddr = pte->PFN0; 5365222Sksewell@umich.edu }else{ 5375222Sksewell@umich.edu PAddr = pte->PFN1; 5385222Sksewell@umich.edu } 5395222Sksewell@umich.edu PAddr >>= (pte->AddrShiftAmount-12); 5405222Sksewell@umich.edu PAddr <<= pte->AddrShiftAmount; 5415222Sksewell@umich.edu PAddr |= ((req->getVaddr()) & pte->OffsetMask); 5425222Sksewell@umich.edu req->setPaddr(PAddr); 5435222Sksewell@umich.edu } 5445222Sksewell@umich.edu } 5455222Sksewell@umich.edu else 5465222Sksewell@umich.edu { // Didn't find any match, return a TLB Refill Exception 5475543Ssaidi@eecs.umich.edu // misses++; 5485222Sksewell@umich.edu DtbRefillFault *Flt=new DtbRefillFault(); 5495222Sksewell@umich.edu /* EntryHi VPN, ASID fields must be set */ 5505222Sksewell@umich.edu Flt->EntryHi_Asid = Asid; 5515222Sksewell@umich.edu Flt->EntryHi_VPN2 = (VPN>>2); 5525222Sksewell@umich.edu Flt->EntryHi_VPN2X = (VPN & 0x3); 5535222Sksewell@umich.edu 5545222Sksewell@umich.edu 5555222Sksewell@umich.edu /* BadVAddr must be set */ 5565222Sksewell@umich.edu Flt->BadVAddr = req->getVaddr(); 5575222Sksewell@umich.edu 5585222Sksewell@umich.edu /* Context must be set */ 5595222Sksewell@umich.edu Flt->Context_BadVPN2 = (VPN >> 2); 5605222Sksewell@umich.edu return Flt; 5615222Sksewell@umich.edu } 5625222Sksewell@umich.edu } 5635222Sksewell@umich.edu return checkCacheability(req); 5645224Sksewell@umich.edu#endif 5655222Sksewell@umich.edu} 5665222Sksewell@umich.edu 5675222Sksewell@umich.edu/////////////////////////////////////////////////////////////////////// 5685222Sksewell@umich.edu// 5695222Sksewell@umich.edu// Mips ITB 5705222Sksewell@umich.edu// 5715222Sksewell@umich.eduITB::ITB(const Params *p) 5725222Sksewell@umich.edu : TLB(p) 5735222Sksewell@umich.edu{} 5745222Sksewell@umich.edu 5755222Sksewell@umich.edu 5765222Sksewell@umich.edu// void 5775222Sksewell@umich.edu// ITB::regStats() 5785222Sksewell@umich.edu// { 5795222Sksewell@umich.edu// /* hits - causes failure for some reason 5805543Ssaidi@eecs.umich.edu// .name(name() + ".hits") 5815543Ssaidi@eecs.umich.edu// .desc("ITB hits"); 5825222Sksewell@umich.edu// misses 5835543Ssaidi@eecs.umich.edu// .name(name() + ".misses") 5845543Ssaidi@eecs.umich.edu// .desc("ITB misses"); 5855222Sksewell@umich.edu// acv 5865543Ssaidi@eecs.umich.edu// .name(name() + ".acv") 5875543Ssaidi@eecs.umich.edu// .desc("ITB acv"); 5885222Sksewell@umich.edu// accesses 5895543Ssaidi@eecs.umich.edu// .name(name() + ".accesses") 5905543Ssaidi@eecs.umich.edu// .desc("ITB accesses"); 5915222Sksewell@umich.edu 5925543Ssaidi@eecs.umich.edu// accesses = hits + misses + invalids; */ 5935222Sksewell@umich.edu// } 5945222Sksewell@umich.edu 5955222Sksewell@umich.edu 5965222Sksewell@umich.edu 5975222Sksewell@umich.edu/////////////////////////////////////////////////////////////////////// 5985222Sksewell@umich.edu// 5995222Sksewell@umich.edu// Mips DTB 6005222Sksewell@umich.edu// 6015222Sksewell@umich.eduDTB::DTB(const Params *p) 6025222Sksewell@umich.edu : TLB(p) 6035222Sksewell@umich.edu{} 6045222Sksewell@umich.edu 6055222Sksewell@umich.edu/////////////////////////////////////////////////////////////////////// 6065222Sksewell@umich.edu// 6075222Sksewell@umich.edu// Mips UTB 6085222Sksewell@umich.edu// 6095222Sksewell@umich.eduUTB::UTB(const Params *p) 6105222Sksewell@umich.edu : ITB(p), DTB(p) 6115222Sksewell@umich.edu{} 6125222Sksewell@umich.edu 6135222Sksewell@umich.edu 6145222Sksewell@umich.edu 6155222Sksewell@umich.eduMipsISA::PTE & 6165222Sksewell@umich.eduTLB::index(bool advance) 6175222Sksewell@umich.edu{ 6185222Sksewell@umich.edu MipsISA::PTE *pte = &table[nlu]; 6195222Sksewell@umich.edu 6205222Sksewell@umich.edu if (advance) 6215222Sksewell@umich.edu nextnlu(); 6225222Sksewell@umich.edu 6235222Sksewell@umich.edu return *pte; 6245222Sksewell@umich.edu} 6254997Sgblack@eecs.umich.edu 6264997Sgblack@eecs.umich.eduMipsISA::ITB * 6274997Sgblack@eecs.umich.eduMipsITBParams::create() 6284997Sgblack@eecs.umich.edu{ 6295034Smilesck@eecs.umich.edu return new MipsISA::ITB(this); 6304997Sgblack@eecs.umich.edu} 6314997Sgblack@eecs.umich.edu 6324997Sgblack@eecs.umich.eduMipsISA::DTB * 6334997Sgblack@eecs.umich.eduMipsDTBParams::create() 6344997Sgblack@eecs.umich.edu{ 6355034Smilesck@eecs.umich.edu return new MipsISA::DTB(this); 6364997Sgblack@eecs.umich.edu} 6375222Sksewell@umich.edu 6385222Sksewell@umich.eduMipsISA::UTB * 6395222Sksewell@umich.eduMipsUTBParams::create() 6405222Sksewell@umich.edu{ 6415222Sksewell@umich.edu return new MipsISA::UTB(this); 6425222Sksewell@umich.edu} 643