tlb.cc revision 11523
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 328696Sguodeyuan@tsinghua.org.cn * Zhengxing Li 338696Sguodeyuan@tsinghua.org.cn * Deyuan Guo 344997Sgblack@eecs.umich.edu */ 354997Sgblack@eecs.umich.edu 365222Sksewell@umich.edu#include <string> 375222Sksewell@umich.edu#include <vector> 384997Sgblack@eecs.umich.edu 398229Snate@binkert.org#include "arch/mips/faults.hh" 408229Snate@binkert.org#include "arch/mips/pagetable.hh" 415222Sksewell@umich.edu#include "arch/mips/pra_constants.hh" 424997Sgblack@eecs.umich.edu#include "arch/mips/tlb.hh" 435222Sksewell@umich.edu#include "arch/mips/utility.hh" 445222Sksewell@umich.edu#include "base/inifile.hh" 455222Sksewell@umich.edu#include "base/str.hh" 465222Sksewell@umich.edu#include "base/trace.hh" 475222Sksewell@umich.edu#include "cpu/thread_context.hh" 488232Snate@binkert.org#include "debug/MipsPRA.hh" 498232Snate@binkert.org#include "debug/TLB.hh" 505224Sksewell@umich.edu#include "mem/page_table.hh" 515222Sksewell@umich.edu#include "params/MipsTLB.hh" 528229Snate@binkert.org#include "sim/process.hh" 534997Sgblack@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.eduTLB::TLB(const Params *p) 635358Sgblack@eecs.umich.edu : BaseTLB(p), size(p->size), nlu(0) 645222Sksewell@umich.edu{ 656378Sgblack@eecs.umich.edu table = new PTE[size]; 666378Sgblack@eecs.umich.edu memset(table, 0, sizeof(PTE[size])); 676378Sgblack@eecs.umich.edu smallPages = 0; 685222Sksewell@umich.edu} 695222Sksewell@umich.edu 705222Sksewell@umich.eduTLB::~TLB() 715222Sksewell@umich.edu{ 725222Sksewell@umich.edu if (table) 735222Sksewell@umich.edu delete [] table; 745222Sksewell@umich.edu} 755222Sksewell@umich.edu 765222Sksewell@umich.edu// look up an entry in the TLB 775222Sksewell@umich.eduMipsISA::PTE * 785222Sksewell@umich.eduTLB::lookup(Addr vpn, uint8_t asn) const 795222Sksewell@umich.edu{ 805222Sksewell@umich.edu // assume not found... 816378Sgblack@eecs.umich.edu PTE *retval = NULL; 825222Sksewell@umich.edu PageTable::const_iterator i = lookupTable.find(vpn); 835222Sksewell@umich.edu if (i != lookupTable.end()) { 845222Sksewell@umich.edu while (i->first == vpn) { 855222Sksewell@umich.edu int index = i->second; 866378Sgblack@eecs.umich.edu PTE *pte = &table[index]; 875222Sksewell@umich.edu 885222Sksewell@umich.edu /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 895222Sksewell@umich.edu Addr Mask = pte->Mask; 905222Sksewell@umich.edu Addr InvMask = ~Mask; 915222Sksewell@umich.edu Addr VPN = pte->VPN; 926378Sgblack@eecs.umich.edu if (((vpn & InvMask) == (VPN & InvMask)) && 936378Sgblack@eecs.umich.edu (pte->G || (asn == pte->asid))) { 946378Sgblack@eecs.umich.edu // We have a VPN + ASID Match 955222Sksewell@umich.edu retval = pte; 965222Sksewell@umich.edu break; 976378Sgblack@eecs.umich.edu } 985222Sksewell@umich.edu ++i; 995222Sksewell@umich.edu } 1005019Sgblack@eecs.umich.edu } 1015019Sgblack@eecs.umich.edu 1025222Sksewell@umich.edu DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, 1035222Sksewell@umich.edu retval ? "hit" : "miss", retval ? retval->PFN1 : 0); 1045222Sksewell@umich.edu return retval; 1055222Sksewell@umich.edu} 1065222Sksewell@umich.edu 1076378Sgblack@eecs.umich.eduMipsISA::PTE* 1086378Sgblack@eecs.umich.eduTLB::getEntry(unsigned Index) const 1095222Sksewell@umich.edu{ 1105222Sksewell@umich.edu // Make sure that Index is valid 1115222Sksewell@umich.edu assert(Index<size); 1125222Sksewell@umich.edu return &table[Index]; 1135222Sksewell@umich.edu} 1145222Sksewell@umich.edu 1156378Sgblack@eecs.umich.eduint 1166378Sgblack@eecs.umich.eduTLB::probeEntry(Addr vpn, uint8_t asn) const 1175222Sksewell@umich.edu{ 1185222Sksewell@umich.edu // assume not found... 1196378Sgblack@eecs.umich.edu int Ind = -1; 1205222Sksewell@umich.edu PageTable::const_iterator i = lookupTable.find(vpn); 1215222Sksewell@umich.edu if (i != lookupTable.end()) { 1225222Sksewell@umich.edu while (i->first == vpn) { 1235222Sksewell@umich.edu int index = i->second; 1246378Sgblack@eecs.umich.edu PTE *pte = &table[index]; 1255222Sksewell@umich.edu 1265222Sksewell@umich.edu /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 1275222Sksewell@umich.edu Addr Mask = pte->Mask; 1285222Sksewell@umich.edu Addr InvMask = ~Mask; 1296378Sgblack@eecs.umich.edu Addr VPN = pte->VPN; 1306378Sgblack@eecs.umich.edu if (((vpn & InvMask) == (VPN & InvMask)) && 1316378Sgblack@eecs.umich.edu (pte->G || (asn == pte->asid))) { 1326378Sgblack@eecs.umich.edu // We have a VPN + ASID Match 1335222Sksewell@umich.edu Ind = index; 1345222Sksewell@umich.edu break; 1356378Sgblack@eecs.umich.edu } 1365222Sksewell@umich.edu ++i; 1375222Sksewell@umich.edu } 1385222Sksewell@umich.edu } 1395222Sksewell@umich.edu DPRINTF(MipsPRA,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind); 1405222Sksewell@umich.edu return Ind; 1415222Sksewell@umich.edu} 1426378Sgblack@eecs.umich.edu 1436378Sgblack@eecs.umich.eduinline Fault 1445222Sksewell@umich.eduTLB::checkCacheability(RequestPtr &req) 1455222Sksewell@umich.edu{ 1466378Sgblack@eecs.umich.edu Addr VAddrUncacheable = 0xA0000000; 1476378Sgblack@eecs.umich.edu // In MIPS, cacheability is controlled by certain bits of the virtual 1486378Sgblack@eecs.umich.edu // address or by the TLB entry 1496378Sgblack@eecs.umich.edu if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) { 1506378Sgblack@eecs.umich.edu // mark request as uncacheable 15110824SAndreas.Sandberg@ARM.com req->setFlags(Request::UNCACHEABLE | Request::STRICT_ORDER); 1526378Sgblack@eecs.umich.edu } 1536378Sgblack@eecs.umich.edu return NoFault; 1545222Sksewell@umich.edu} 1556378Sgblack@eecs.umich.edu 1566378Sgblack@eecs.umich.eduvoid 1576378Sgblack@eecs.umich.eduTLB::insertAt(PTE &pte, unsigned Index, int _smallPages) 1585222Sksewell@umich.edu{ 1596378Sgblack@eecs.umich.edu smallPages = _smallPages; 1606378Sgblack@eecs.umich.edu if (Index > size) { 1616378Sgblack@eecs.umich.edu warn("Attempted to write at index (%d) beyond TLB size (%d)", 1626378Sgblack@eecs.umich.edu Index, size); 1636378Sgblack@eecs.umich.edu } else { 1646378Sgblack@eecs.umich.edu // Update TLB 1656378Sgblack@eecs.umich.edu DPRINTF(TLB, "TLB[%d]: %x %x %x %x\n", 1666378Sgblack@eecs.umich.edu Index, pte.Mask << 11, 1676378Sgblack@eecs.umich.edu ((pte.VPN << 11) | pte.asid), 1686378Sgblack@eecs.umich.edu ((pte.PFN0 << 6) | (pte.C0 << 3) | 1696378Sgblack@eecs.umich.edu (pte.D0 << 2) | (pte.V0 <<1) | pte.G), 1706378Sgblack@eecs.umich.edu ((pte.PFN1 <<6) | (pte.C1 << 3) | 1716378Sgblack@eecs.umich.edu (pte.D1 << 2) | (pte.V1 <<1) | pte.G)); 17210231Ssteve.reinhardt@amd.com if (table[Index].V0 || table[Index].V1) { 1736378Sgblack@eecs.umich.edu // Previous entry is valid 1746378Sgblack@eecs.umich.edu PageTable::iterator i = lookupTable.find(table[Index].VPN); 1756378Sgblack@eecs.umich.edu lookupTable.erase(i); 1766378Sgblack@eecs.umich.edu } 1776378Sgblack@eecs.umich.edu table[Index]=pte; 1786378Sgblack@eecs.umich.edu // Update fast lookup table 1796378Sgblack@eecs.umich.edu lookupTable.insert(make_pair(table[Index].VPN, Index)); 1805222Sksewell@umich.edu } 1815222Sksewell@umich.edu} 1825222Sksewell@umich.edu 1835222Sksewell@umich.edu// insert a new TLB entry 1845222Sksewell@umich.eduvoid 1856378Sgblack@eecs.umich.eduTLB::insert(Addr addr, PTE &pte) 1865222Sksewell@umich.edu{ 1876378Sgblack@eecs.umich.edu fatal("TLB Insert not yet implemented\n"); 1885222Sksewell@umich.edu} 1895222Sksewell@umich.edu 1905222Sksewell@umich.eduvoid 1915222Sksewell@umich.eduTLB::flushAll() 1925222Sksewell@umich.edu{ 1935222Sksewell@umich.edu DPRINTF(TLB, "flushAll\n"); 1946378Sgblack@eecs.umich.edu memset(table, 0, sizeof(PTE[size])); 1955222Sksewell@umich.edu lookupTable.clear(); 1965222Sksewell@umich.edu nlu = 0; 1975222Sksewell@umich.edu} 1985222Sksewell@umich.edu 1995222Sksewell@umich.eduvoid 20010905Sandreas.sandberg@arm.comTLB::serialize(CheckpointOut &cp) const 2015222Sksewell@umich.edu{ 2025222Sksewell@umich.edu SERIALIZE_SCALAR(size); 2035222Sksewell@umich.edu SERIALIZE_SCALAR(nlu); 2045222Sksewell@umich.edu 2055222Sksewell@umich.edu for (int i = 0; i < size; i++) { 20610905Sandreas.sandberg@arm.com ScopedCheckpointSection sec(cp, csprintf("PTE%d", i)); 20710905Sandreas.sandberg@arm.com table[i].serialize(cp); 2085222Sksewell@umich.edu } 2095222Sksewell@umich.edu} 2105222Sksewell@umich.edu 2115222Sksewell@umich.eduvoid 21210905Sandreas.sandberg@arm.comTLB::unserialize(CheckpointIn &cp) 2135222Sksewell@umich.edu{ 2145222Sksewell@umich.edu UNSERIALIZE_SCALAR(size); 2155222Sksewell@umich.edu UNSERIALIZE_SCALAR(nlu); 2165222Sksewell@umich.edu 2175222Sksewell@umich.edu for (int i = 0; i < size; i++) { 21810905Sandreas.sandberg@arm.com ScopedCheckpointSection sec(cp, csprintf("PTE%d", i)); 21910905Sandreas.sandberg@arm.com table[i].unserialize(cp); 2205222Sksewell@umich.edu if (table[i].V0 || table[i].V1) { 2215222Sksewell@umich.edu lookupTable.insert(make_pair(table[i].VPN, i)); 2225222Sksewell@umich.edu } 2235222Sksewell@umich.edu } 2245222Sksewell@umich.edu} 2255222Sksewell@umich.edu 2265222Sksewell@umich.eduvoid 2275222Sksewell@umich.eduTLB::regStats() 2285222Sksewell@umich.edu{ 22911523Sdavid.guillen@arm.com BaseTLB::regStats(); 23011523Sdavid.guillen@arm.com 2315222Sksewell@umich.edu read_hits 2325222Sksewell@umich.edu .name(name() + ".read_hits") 2335222Sksewell@umich.edu .desc("DTB read hits") 2345222Sksewell@umich.edu ; 2355222Sksewell@umich.edu 2365222Sksewell@umich.edu read_misses 2375222Sksewell@umich.edu .name(name() + ".read_misses") 2385222Sksewell@umich.edu .desc("DTB read misses") 2395222Sksewell@umich.edu ; 2405222Sksewell@umich.edu 2415222Sksewell@umich.edu 2425222Sksewell@umich.edu read_accesses 2435222Sksewell@umich.edu .name(name() + ".read_accesses") 2445222Sksewell@umich.edu .desc("DTB read accesses") 2455222Sksewell@umich.edu ; 2465222Sksewell@umich.edu 2475222Sksewell@umich.edu write_hits 2485222Sksewell@umich.edu .name(name() + ".write_hits") 2495222Sksewell@umich.edu .desc("DTB write hits") 2505222Sksewell@umich.edu ; 2515222Sksewell@umich.edu 2525222Sksewell@umich.edu write_misses 2535222Sksewell@umich.edu .name(name() + ".write_misses") 2545222Sksewell@umich.edu .desc("DTB write misses") 2555222Sksewell@umich.edu ; 2565222Sksewell@umich.edu 2575222Sksewell@umich.edu 2585222Sksewell@umich.edu write_accesses 2595222Sksewell@umich.edu .name(name() + ".write_accesses") 2605222Sksewell@umich.edu .desc("DTB write accesses") 2615222Sksewell@umich.edu ; 2625222Sksewell@umich.edu 2635222Sksewell@umich.edu hits 2645222Sksewell@umich.edu .name(name() + ".hits") 2655222Sksewell@umich.edu .desc("DTB hits") 2665222Sksewell@umich.edu ; 2675222Sksewell@umich.edu 2685222Sksewell@umich.edu misses 2695222Sksewell@umich.edu .name(name() + ".misses") 2705222Sksewell@umich.edu .desc("DTB misses") 2715222Sksewell@umich.edu ; 2725222Sksewell@umich.edu 2735222Sksewell@umich.edu accesses 2745222Sksewell@umich.edu .name(name() + ".accesses") 2755222Sksewell@umich.edu .desc("DTB accesses") 2765222Sksewell@umich.edu ; 2775222Sksewell@umich.edu 2785222Sksewell@umich.edu hits = read_hits + write_hits; 2795222Sksewell@umich.edu misses = read_misses + write_misses; 2805222Sksewell@umich.edu accesses = read_accesses + write_accesses; 2815222Sksewell@umich.edu} 2825222Sksewell@umich.edu 2835222Sksewell@umich.eduFault 2846022Sgblack@eecs.umich.eduTLB::translateInst(RequestPtr req, ThreadContext *tc) 2855222Sksewell@umich.edu{ 2868806Sgblack@eecs.umich.edu if (FullSystem) 2878806Sgblack@eecs.umich.edu panic("translateInst not implemented in MIPS.\n"); 2885224Sksewell@umich.edu 2898806Sgblack@eecs.umich.edu Process * p = tc->getProcessPtr(); 2905224Sksewell@umich.edu 2918806Sgblack@eecs.umich.edu Fault fault = p->pTable->translate(req); 2928806Sgblack@eecs.umich.edu if (fault != NoFault) 2938806Sgblack@eecs.umich.edu return fault; 2948806Sgblack@eecs.umich.edu 2958806Sgblack@eecs.umich.edu return NoFault; 2965222Sksewell@umich.edu} 2975222Sksewell@umich.edu 2985222Sksewell@umich.eduFault 2996022Sgblack@eecs.umich.eduTLB::translateData(RequestPtr req, ThreadContext *tc, bool write) 3005222Sksewell@umich.edu{ 3018806Sgblack@eecs.umich.edu if (FullSystem) 3028806Sgblack@eecs.umich.edu panic("translateData not implemented in MIPS.\n"); 3038767Sgblack@eecs.umich.edu 3048806Sgblack@eecs.umich.edu Process * p = tc->getProcessPtr(); 3058767Sgblack@eecs.umich.edu 3068806Sgblack@eecs.umich.edu Fault fault = p->pTable->translate(req); 3078806Sgblack@eecs.umich.edu if (fault != NoFault) 3088806Sgblack@eecs.umich.edu return fault; 3098806Sgblack@eecs.umich.edu 3108806Sgblack@eecs.umich.edu return NoFault; 3115222Sksewell@umich.edu} 3125222Sksewell@umich.edu 3136022Sgblack@eecs.umich.eduFault 3146023Snate@binkert.orgTLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) 3156022Sgblack@eecs.umich.edu{ 3166023Snate@binkert.org if (mode == Execute) 3176022Sgblack@eecs.umich.edu return translateInst(req, tc); 3186022Sgblack@eecs.umich.edu else 3196023Snate@binkert.org return translateData(req, tc, mode == Write); 3206022Sgblack@eecs.umich.edu} 3216022Sgblack@eecs.umich.edu 3225894Sgblack@eecs.umich.eduvoid 3236022Sgblack@eecs.umich.eduTLB::translateTiming(RequestPtr req, ThreadContext *tc, 3246023Snate@binkert.org Translation *translation, Mode mode) 3255894Sgblack@eecs.umich.edu{ 3265894Sgblack@eecs.umich.edu assert(translation); 3276023Snate@binkert.org translation->finish(translateAtomic(req, tc, mode), req, tc, mode); 3285894Sgblack@eecs.umich.edu} 3295894Sgblack@eecs.umich.edu 3308888Sgeoffrey.blake@arm.comFault 3318888Sgeoffrey.blake@arm.comTLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode) 3328888Sgeoffrey.blake@arm.com{ 3338888Sgeoffrey.blake@arm.com panic("Not implemented\n"); 3348888Sgeoffrey.blake@arm.com return NoFault; 3358888Sgeoffrey.blake@arm.com} 3368888Sgeoffrey.blake@arm.com 3379738Sandreas@sandberg.pp.seFault 3389738Sandreas@sandberg.pp.seTLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const 3399738Sandreas@sandberg.pp.se{ 3409738Sandreas@sandberg.pp.se return NoFault; 3419738Sandreas@sandberg.pp.se} 3429738Sandreas@sandberg.pp.se 3435222Sksewell@umich.edu 3445222Sksewell@umich.eduMipsISA::PTE & 3455222Sksewell@umich.eduTLB::index(bool advance) 3465222Sksewell@umich.edu{ 3476378Sgblack@eecs.umich.edu PTE *pte = &table[nlu]; 3485222Sksewell@umich.edu 3495222Sksewell@umich.edu if (advance) 3505222Sksewell@umich.edu nextnlu(); 3515222Sksewell@umich.edu 3525222Sksewell@umich.edu return *pte; 3535222Sksewell@umich.edu} 3544997Sgblack@eecs.umich.edu 3556022Sgblack@eecs.umich.eduMipsISA::TLB * 3566022Sgblack@eecs.umich.eduMipsTLBParams::create() 3574997Sgblack@eecs.umich.edu{ 3586378Sgblack@eecs.umich.edu return new TLB(this); 3594997Sgblack@eecs.umich.edu} 360