tlb.cc revision 5268
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
625222Sksewell@umich.edu#define MODE2MASK(X)			(1 << (X))
635222Sksewell@umich.edu
645222Sksewell@umich.eduTLB::TLB(const Params *p)
655222Sksewell@umich.edu    : SimObject(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;
945222Sksewell@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
1525222Sksewell@umich.edu    req->setFlags(req->getFlags() | 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 &section)
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
3925222Sksewell@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
4095222Sksewell@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
4975222Sksewell@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
5155222Sksewell@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
5475222Sksewell@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
5805222Sksewell@umich.edu// 	.name(name() + ".hits")
5815222Sksewell@umich.edu// 	.desc("ITB hits");
5825222Sksewell@umich.edu//     misses
5835222Sksewell@umich.edu// 	.name(name() + ".misses")
5845222Sksewell@umich.edu// 	.desc("ITB misses");
5855222Sksewell@umich.edu//     acv
5865222Sksewell@umich.edu// 	.name(name() + ".acv")
5875222Sksewell@umich.edu// 	.desc("ITB acv");
5885222Sksewell@umich.edu//     accesses
5895222Sksewell@umich.edu// 	.name(name() + ".accesses")
5905222Sksewell@umich.edu// 	.desc("ITB accesses");
5915222Sksewell@umich.edu
5925222Sksewell@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