tlb.cc revision 10280:5b67e1bdf6ad
1955SN/A/* 2955SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan 312230Sgiacomo.travaglini@arm.com * Copyright (c) 2007 MIPS Technologies, Inc. 49812Sandreas.hansson@arm.com * All rights reserved. 59812Sandreas.hansson@arm.com * 69812Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 79812Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 89812Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 99812Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 109812Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 119812Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 129812Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 139812Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 149812Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 157816Ssteve.reinhardt@amd.com * this software without specific prior written permission. 165871Snate@binkert.org * 171762SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28955SN/A * 29955SN/A * Authors: Nathan Binkert 30955SN/A * Steve Reinhardt 31955SN/A * Jaidev Patwardhan 32955SN/A * Zhengxing Li 33955SN/A * Deyuan Guo 34955SN/A */ 35955SN/A 36955SN/A#include <string> 37955SN/A#include <vector> 38955SN/A 39955SN/A#include "arch/mips/faults.hh" 40955SN/A#include "arch/mips/pagetable.hh" 41955SN/A#include "arch/mips/pra_constants.hh" 422665Ssaidi@eecs.umich.edu#include "arch/mips/tlb.hh" 432665Ssaidi@eecs.umich.edu#include "arch/mips/utility.hh" 445863Snate@binkert.org#include "base/inifile.hh" 45955SN/A#include "base/str.hh" 46955SN/A#include "base/trace.hh" 47955SN/A#include "cpu/thread_context.hh" 48955SN/A#include "debug/MipsPRA.hh" 49955SN/A#include "debug/TLB.hh" 508878Ssteve.reinhardt@amd.com#include "mem/page_table.hh" 512632Sstever@eecs.umich.edu#include "params/MipsTLB.hh" 528878Ssteve.reinhardt@amd.com#include "sim/process.hh" 532632Sstever@eecs.umich.edu 54955SN/Ausing namespace std; 558878Ssteve.reinhardt@amd.comusing namespace MipsISA; 562632Sstever@eecs.umich.edu 572761Sstever@eecs.umich.edu/////////////////////////////////////////////////////////////////////// 582632Sstever@eecs.umich.edu// 592632Sstever@eecs.umich.edu// MIPS TLB 602632Sstever@eecs.umich.edu// 612761Sstever@eecs.umich.edu 622761Sstever@eecs.umich.eduTLB::TLB(const Params *p) 632761Sstever@eecs.umich.edu : BaseTLB(p), size(p->size), nlu(0) 648878Ssteve.reinhardt@amd.com{ 658878Ssteve.reinhardt@amd.com table = new PTE[size]; 662761Sstever@eecs.umich.edu memset(table, 0, sizeof(PTE[size])); 672761Sstever@eecs.umich.edu smallPages = 0; 682761Sstever@eecs.umich.edu} 692761Sstever@eecs.umich.edu 702761Sstever@eecs.umich.eduTLB::~TLB() 718878Ssteve.reinhardt@amd.com{ 728878Ssteve.reinhardt@amd.com if (table) 732632Sstever@eecs.umich.edu delete [] table; 742632Sstever@eecs.umich.edu} 758878Ssteve.reinhardt@amd.com 768878Ssteve.reinhardt@amd.com// look up an entry in the TLB 772632Sstever@eecs.umich.eduMipsISA::PTE * 78955SN/ATLB::lookup(Addr vpn, uint8_t asn) const 79955SN/A{ 80955SN/A // assume not found... 8112563Sgabeblack@google.com PTE *retval = NULL; 8212563Sgabeblack@google.com PageTable::const_iterator i = lookupTable.find(vpn); 836654Snate@binkert.org if (i != lookupTable.end()) { 8410196SCurtis.Dunham@arm.com while (i->first == vpn) { 85955SN/A int index = i->second; 865396Ssaidi@eecs.umich.edu PTE *pte = &table[index]; 8711401Sandreas.sandberg@arm.com 885863Snate@binkert.org /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 895863Snate@binkert.org Addr Mask = pte->Mask; 904202Sbinkertn@umich.edu Addr InvMask = ~Mask; 915863Snate@binkert.org Addr VPN = pte->VPN; 925863Snate@binkert.org if (((vpn & InvMask) == (VPN & InvMask)) && 935863Snate@binkert.org (pte->G || (asn == pte->asid))) { 945863Snate@binkert.org // We have a VPN + ASID Match 95955SN/A retval = pte; 966654Snate@binkert.org break; 975273Sstever@gmail.com } 985871Snate@binkert.org ++i; 995273Sstever@gmail.com } 1006654Snate@binkert.org } 1015396Ssaidi@eecs.umich.edu 1028120Sgblack@eecs.umich.edu DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, 1038120Sgblack@eecs.umich.edu retval ? "hit" : "miss", retval ? retval->PFN1 : 0); 1048120Sgblack@eecs.umich.edu return retval; 1058120Sgblack@eecs.umich.edu} 1068120Sgblack@eecs.umich.edu 1078120Sgblack@eecs.umich.eduMipsISA::PTE* 1088120Sgblack@eecs.umich.eduTLB::getEntry(unsigned Index) const 1098120Sgblack@eecs.umich.edu{ 1108879Ssteve.reinhardt@amd.com // Make sure that Index is valid 1118879Ssteve.reinhardt@amd.com assert(Index<size); 1128879Ssteve.reinhardt@amd.com return &table[Index]; 1138879Ssteve.reinhardt@amd.com} 1148879Ssteve.reinhardt@amd.com 1158879Ssteve.reinhardt@amd.comint 1168879Ssteve.reinhardt@amd.comTLB::probeEntry(Addr vpn, uint8_t asn) const 1178879Ssteve.reinhardt@amd.com{ 1188879Ssteve.reinhardt@amd.com // assume not found... 1198879Ssteve.reinhardt@amd.com int Ind = -1; 1208879Ssteve.reinhardt@amd.com PageTable::const_iterator i = lookupTable.find(vpn); 1218879Ssteve.reinhardt@amd.com if (i != lookupTable.end()) { 1228879Ssteve.reinhardt@amd.com while (i->first == vpn) { 1238120Sgblack@eecs.umich.edu int index = i->second; 1248120Sgblack@eecs.umich.edu PTE *pte = &table[index]; 1258120Sgblack@eecs.umich.edu 1268120Sgblack@eecs.umich.edu /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 1278120Sgblack@eecs.umich.edu Addr Mask = pte->Mask; 1288120Sgblack@eecs.umich.edu Addr InvMask = ~Mask; 1298120Sgblack@eecs.umich.edu Addr VPN = pte->VPN; 1308120Sgblack@eecs.umich.edu if (((vpn & InvMask) == (VPN & InvMask)) && 1318120Sgblack@eecs.umich.edu (pte->G || (asn == pte->asid))) { 1328120Sgblack@eecs.umich.edu // We have a VPN + ASID Match 1338120Sgblack@eecs.umich.edu Ind = index; 1348120Sgblack@eecs.umich.edu break; 1358120Sgblack@eecs.umich.edu } 1368120Sgblack@eecs.umich.edu ++i; 1378879Ssteve.reinhardt@amd.com } 1388879Ssteve.reinhardt@amd.com } 1398879Ssteve.reinhardt@amd.com DPRINTF(MipsPRA,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind); 1408879Ssteve.reinhardt@amd.com return Ind; 14110458Sandreas.hansson@arm.com} 14210458Sandreas.hansson@arm.com 14310458Sandreas.hansson@arm.cominline Fault 1448879Ssteve.reinhardt@amd.comTLB::checkCacheability(RequestPtr &req) 1458879Ssteve.reinhardt@amd.com{ 1468879Ssteve.reinhardt@amd.com Addr VAddrUncacheable = 0xA0000000; 1478879Ssteve.reinhardt@amd.com // In MIPS, cacheability is controlled by certain bits of the virtual 1489227Sandreas.hansson@arm.com // address or by the TLB entry 1499227Sandreas.hansson@arm.com if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) { 15012063Sgabeblack@google.com // mark request as uncacheable 15112063Sgabeblack@google.com req->setFlags(Request::UNCACHEABLE); 15212063Sgabeblack@google.com } 1538879Ssteve.reinhardt@amd.com return NoFault; 1548879Ssteve.reinhardt@amd.com} 1558879Ssteve.reinhardt@amd.com 1568879Ssteve.reinhardt@amd.comvoid 15710453SAndrew.Bardsley@arm.comTLB::insertAt(PTE &pte, unsigned Index, int _smallPages) 15810453SAndrew.Bardsley@arm.com{ 15910453SAndrew.Bardsley@arm.com smallPages = _smallPages; 16010456SCurtis.Dunham@arm.com if (Index > size) { 16110456SCurtis.Dunham@arm.com warn("Attempted to write at index (%d) beyond TLB size (%d)", 16210456SCurtis.Dunham@arm.com Index, size); 16310457Sandreas.hansson@arm.com } else { 16410457Sandreas.hansson@arm.com // Update TLB 16511342Sandreas.hansson@arm.com DPRINTF(TLB, "TLB[%d]: %x %x %x %x\n", 16611342Sandreas.hansson@arm.com Index, pte.Mask << 11, 1678120Sgblack@eecs.umich.edu ((pte.VPN << 11) | pte.asid), 16812063Sgabeblack@google.com ((pte.PFN0 << 6) | (pte.C0 << 3) | 16912563Sgabeblack@google.com (pte.D0 << 2) | (pte.V0 <<1) | pte.G), 17012063Sgabeblack@google.com ((pte.PFN1 <<6) | (pte.C1 << 3) | 17112063Sgabeblack@google.com (pte.D1 << 2) | (pte.V1 <<1) | pte.G)); 1725871Snate@binkert.org if (table[Index].V0 || table[Index].V1) { 1735871Snate@binkert.org // Previous entry is valid 1746121Snate@binkert.org PageTable::iterator i = lookupTable.find(table[Index].VPN); 1755871Snate@binkert.org lookupTable.erase(i); 1765871Snate@binkert.org } 1779926Sstan.czerniawski@arm.com table[Index]=pte; 17812243Sgabeblack@google.com // Update fast lookup table 1791533SN/A lookupTable.insert(make_pair(table[Index].VPN, Index)); 18012246Sgabeblack@google.com } 18112246Sgabeblack@google.com} 18212246Sgabeblack@google.com 18312246Sgabeblack@google.com// insert a new TLB entry 1849239Sandreas.hansson@arm.comvoid 1859239Sandreas.hansson@arm.comTLB::insert(Addr addr, PTE &pte) 1869239Sandreas.hansson@arm.com{ 1879239Sandreas.hansson@arm.com fatal("TLB Insert not yet implemented\n"); 18812563Sgabeblack@google.com} 1899239Sandreas.hansson@arm.com 1909239Sandreas.hansson@arm.comvoid 191955SN/ATLB::flushAll() 192955SN/A{ 1932632Sstever@eecs.umich.edu DPRINTF(TLB, "flushAll\n"); 1942632Sstever@eecs.umich.edu memset(table, 0, sizeof(PTE[size])); 195955SN/A lookupTable.clear(); 196955SN/A nlu = 0; 197955SN/A} 198955SN/A 1998878Ssteve.reinhardt@amd.comvoid 200955SN/ATLB::serialize(ostream &os) 2012632Sstever@eecs.umich.edu{ 2022632Sstever@eecs.umich.edu SERIALIZE_SCALAR(size); 2032632Sstever@eecs.umich.edu SERIALIZE_SCALAR(nlu); 2042632Sstever@eecs.umich.edu 2052632Sstever@eecs.umich.edu for (int i = 0; i < size; i++) { 2062632Sstever@eecs.umich.edu nameOut(os, csprintf("%s.PTE%d", name(), i)); 2072632Sstever@eecs.umich.edu table[i].serialize(os); 2088268Ssteve.reinhardt@amd.com } 2098268Ssteve.reinhardt@amd.com} 2108268Ssteve.reinhardt@amd.com 2118268Ssteve.reinhardt@amd.comvoid 2128268Ssteve.reinhardt@amd.comTLB::unserialize(Checkpoint *cp, const string §ion) 2138268Ssteve.reinhardt@amd.com{ 2148268Ssteve.reinhardt@amd.com UNSERIALIZE_SCALAR(size); 2152632Sstever@eecs.umich.edu UNSERIALIZE_SCALAR(nlu); 2162632Sstever@eecs.umich.edu 2172632Sstever@eecs.umich.edu for (int i = 0; i < size; i++) { 2182632Sstever@eecs.umich.edu table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); 2198268Ssteve.reinhardt@amd.com if (table[i].V0 || table[i].V1) { 2202632Sstever@eecs.umich.edu lookupTable.insert(make_pair(table[i].VPN, i)); 2218268Ssteve.reinhardt@amd.com } 2228268Ssteve.reinhardt@amd.com } 2238268Ssteve.reinhardt@amd.com} 2248268Ssteve.reinhardt@amd.com 2253718Sstever@eecs.umich.eduvoid 2262634Sstever@eecs.umich.eduTLB::regStats() 2272634Sstever@eecs.umich.edu{ 2285863Snate@binkert.org read_hits 2292638Sstever@eecs.umich.edu .name(name() + ".read_hits") 2308268Ssteve.reinhardt@amd.com .desc("DTB read hits") 2312632Sstever@eecs.umich.edu ; 2322632Sstever@eecs.umich.edu 2332632Sstever@eecs.umich.edu read_misses 2342632Sstever@eecs.umich.edu .name(name() + ".read_misses") 23512563Sgabeblack@google.com .desc("DTB read misses") 2361858SN/A ; 2373716Sstever@eecs.umich.edu 2382638Sstever@eecs.umich.edu 2392638Sstever@eecs.umich.edu read_accesses 2402638Sstever@eecs.umich.edu .name(name() + ".read_accesses") 2412638Sstever@eecs.umich.edu .desc("DTB read accesses") 24212563Sgabeblack@google.com ; 24312563Sgabeblack@google.com 2442638Sstever@eecs.umich.edu write_hits 2455863Snate@binkert.org .name(name() + ".write_hits") 2465863Snate@binkert.org .desc("DTB write hits") 2475863Snate@binkert.org ; 248955SN/A 2495341Sstever@gmail.com write_misses 2505341Sstever@gmail.com .name(name() + ".write_misses") 2515863Snate@binkert.org .desc("DTB write misses") 2527756SAli.Saidi@ARM.com ; 2535341Sstever@gmail.com 2546121Snate@binkert.org 2554494Ssaidi@eecs.umich.edu write_accesses 2566121Snate@binkert.org .name(name() + ".write_accesses") 2571105SN/A .desc("DTB write accesses") 2582667Sstever@eecs.umich.edu ; 2592667Sstever@eecs.umich.edu 2602667Sstever@eecs.umich.edu hits 2612667Sstever@eecs.umich.edu .name(name() + ".hits") 2626121Snate@binkert.org .desc("DTB hits") 2632667Sstever@eecs.umich.edu ; 2645341Sstever@gmail.com 2655863Snate@binkert.org misses 2665341Sstever@gmail.com .name(name() + ".misses") 2675341Sstever@gmail.com .desc("DTB misses") 2685341Sstever@gmail.com ; 2698120Sgblack@eecs.umich.edu 2705341Sstever@gmail.com accesses 2718120Sgblack@eecs.umich.edu .name(name() + ".accesses") 2725341Sstever@gmail.com .desc("DTB accesses") 2738120Sgblack@eecs.umich.edu ; 2746121Snate@binkert.org 2756121Snate@binkert.org hits = read_hits + write_hits; 2769396Sandreas.hansson@arm.com misses = read_misses + write_misses; 2775397Ssaidi@eecs.umich.edu accesses = read_accesses + write_accesses; 2785397Ssaidi@eecs.umich.edu} 2797727SAli.Saidi@ARM.com 2808268Ssteve.reinhardt@amd.comFault 2816168Snate@binkert.orgTLB::translateInst(RequestPtr req, ThreadContext *tc) 2825341Sstever@gmail.com{ 2838120Sgblack@eecs.umich.edu if (FullSystem) 2848120Sgblack@eecs.umich.edu panic("translateInst not implemented in MIPS.\n"); 2858120Sgblack@eecs.umich.edu 2866814Sgblack@eecs.umich.edu Process * p = tc->getProcessPtr(); 2875863Snate@binkert.org 2888120Sgblack@eecs.umich.edu Fault fault = p->pTable->translate(req); 2895341Sstever@gmail.com if (fault != NoFault) 2905863Snate@binkert.org return fault; 2918268Ssteve.reinhardt@amd.com 2926121Snate@binkert.org return NoFault; 2936121Snate@binkert.org} 2948268Ssteve.reinhardt@amd.com 2955742Snate@binkert.orgFault 2965742Snate@binkert.orgTLB::translateData(RequestPtr req, ThreadContext *tc, bool write) 2975341Sstever@gmail.com{ 2985742Snate@binkert.org if (FullSystem) 2995742Snate@binkert.org panic("translateData not implemented in MIPS.\n"); 3005341Sstever@gmail.com 3016017Snate@binkert.org Process * p = tc->getProcessPtr(); 3026121Snate@binkert.org 3036017Snate@binkert.org Fault fault = p->pTable->translate(req); 30412158Sandreas.sandberg@arm.com if (fault != NoFault) 30512158Sandreas.sandberg@arm.com return fault; 30612158Sandreas.sandberg@arm.com 3078120Sgblack@eecs.umich.edu return NoFault; 3087756SAli.Saidi@ARM.com} 3097756SAli.Saidi@ARM.com 3107756SAli.Saidi@ARM.comFault 3117756SAli.Saidi@ARM.comTLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) 3127816Ssteve.reinhardt@amd.com{ 3137816Ssteve.reinhardt@amd.com if (mode == Execute) 3147816Ssteve.reinhardt@amd.com return translateInst(req, tc); 3157816Ssteve.reinhardt@amd.com else 3167816Ssteve.reinhardt@amd.com return translateData(req, tc, mode == Write); 31711979Sgabeblack@google.com} 3187816Ssteve.reinhardt@amd.com 3197816Ssteve.reinhardt@amd.comvoid 3207816Ssteve.reinhardt@amd.comTLB::translateTiming(RequestPtr req, ThreadContext *tc, 3217816Ssteve.reinhardt@amd.com Translation *translation, Mode mode) 3227756SAli.Saidi@ARM.com{ 3237756SAli.Saidi@ARM.com assert(translation); 3249227Sandreas.hansson@arm.com translation->finish(translateAtomic(req, tc, mode), req, tc, mode); 3259227Sandreas.hansson@arm.com} 3269227Sandreas.hansson@arm.com 3279227Sandreas.hansson@arm.comFault 3289590Sandreas@sandberg.pp.seTLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode) 3299590Sandreas@sandberg.pp.se{ 3309590Sandreas@sandberg.pp.se panic("Not implemented\n"); 3319590Sandreas@sandberg.pp.se return NoFault; 3329590Sandreas@sandberg.pp.se} 3339590Sandreas@sandberg.pp.se 3346654Snate@binkert.orgFault 3356654Snate@binkert.orgTLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const 3365871Snate@binkert.org{ 3376121Snate@binkert.org return NoFault; 3388946Sandreas.hansson@arm.com} 3399419Sandreas.hansson@arm.com 34012563Sgabeblack@google.com 3413918Ssaidi@eecs.umich.eduMipsISA::PTE & 3423918Ssaidi@eecs.umich.eduTLB::index(bool advance) 3431858SN/A{ 3449556Sandreas.hansson@arm.com PTE *pte = &table[nlu]; 3459556Sandreas.hansson@arm.com 3469556Sandreas.hansson@arm.com if (advance) 3479556Sandreas.hansson@arm.com nextnlu(); 34811294Sandreas.hansson@arm.com 34911294Sandreas.hansson@arm.com return *pte; 35011294Sandreas.hansson@arm.com} 35111294Sandreas.hansson@arm.com 35210878Sandreas.hansson@arm.comMipsISA::TLB * 35310878Sandreas.hansson@arm.comMipsTLBParams::create() 35411811Sbaz21@cam.ac.uk{ 35511811Sbaz21@cam.ac.uk return new TLB(this); 35611811Sbaz21@cam.ac.uk} 35711982Sgabeblack@google.com