tlb.cc revision 8232
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 378229Snate@binkert.org#include "arch/mips/faults.hh" 388229Snate@binkert.org#include "arch/mips/pagetable.hh" 395222Sksewell@umich.edu#include "arch/mips/pra_constants.hh" 404997Sgblack@eecs.umich.edu#include "arch/mips/tlb.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" 468232Snate@binkert.org#include "debug/MipsPRA.hh" 478232Snate@binkert.org#include "debug/TLB.hh" 485224Sksewell@umich.edu#include "mem/page_table.hh" 495222Sksewell@umich.edu#include "params/MipsTLB.hh" 508229Snate@binkert.org#include "sim/process.hh" 514997Sgblack@eecs.umich.edu 525222Sksewell@umich.eduusing namespace std; 535222Sksewell@umich.eduusing namespace MipsISA; 545019Sgblack@eecs.umich.edu 555222Sksewell@umich.edu/////////////////////////////////////////////////////////////////////// 565222Sksewell@umich.edu// 575222Sksewell@umich.edu// MIPS TLB 585222Sksewell@umich.edu// 595019Sgblack@eecs.umich.edu 606329Sgblack@eecs.umich.edustatic inline mode_type 616329Sgblack@eecs.umich.edugetOperatingMode(MiscReg Stat) 626329Sgblack@eecs.umich.edu{ 636378Sgblack@eecs.umich.edu if ((Stat & 0x10000006) != 0 || (Stat & 0x18) ==0) { 646329Sgblack@eecs.umich.edu return mode_kernel; 656378Sgblack@eecs.umich.edu } else if ((Stat & 0x18) == 0x8) { 666329Sgblack@eecs.umich.edu return mode_supervisor; 676378Sgblack@eecs.umich.edu } else if ((Stat & 0x18) == 0x10) { 686329Sgblack@eecs.umich.edu return mode_user; 696329Sgblack@eecs.umich.edu } else { 706329Sgblack@eecs.umich.edu return mode_number; 716329Sgblack@eecs.umich.edu } 726329Sgblack@eecs.umich.edu} 736329Sgblack@eecs.umich.edu 746329Sgblack@eecs.umich.edu 755222Sksewell@umich.eduTLB::TLB(const Params *p) 765358Sgblack@eecs.umich.edu : BaseTLB(p), size(p->size), nlu(0) 775222Sksewell@umich.edu{ 786378Sgblack@eecs.umich.edu table = new PTE[size]; 796378Sgblack@eecs.umich.edu memset(table, 0, sizeof(PTE[size])); 806378Sgblack@eecs.umich.edu smallPages = 0; 815222Sksewell@umich.edu} 825222Sksewell@umich.edu 835222Sksewell@umich.eduTLB::~TLB() 845222Sksewell@umich.edu{ 855222Sksewell@umich.edu if (table) 865222Sksewell@umich.edu delete [] table; 875222Sksewell@umich.edu} 885222Sksewell@umich.edu 895222Sksewell@umich.edu// look up an entry in the TLB 905222Sksewell@umich.eduMipsISA::PTE * 915222Sksewell@umich.eduTLB::lookup(Addr vpn, uint8_t asn) const 925222Sksewell@umich.edu{ 935222Sksewell@umich.edu // assume not found... 946378Sgblack@eecs.umich.edu PTE *retval = NULL; 955222Sksewell@umich.edu PageTable::const_iterator i = lookupTable.find(vpn); 965222Sksewell@umich.edu if (i != lookupTable.end()) { 975222Sksewell@umich.edu while (i->first == vpn) { 985222Sksewell@umich.edu int index = i->second; 996378Sgblack@eecs.umich.edu PTE *pte = &table[index]; 1005222Sksewell@umich.edu 1015222Sksewell@umich.edu /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 1025222Sksewell@umich.edu Addr Mask = pte->Mask; 1035222Sksewell@umich.edu Addr InvMask = ~Mask; 1045222Sksewell@umich.edu Addr VPN = pte->VPN; 1056378Sgblack@eecs.umich.edu if (((vpn & InvMask) == (VPN & InvMask)) && 1066378Sgblack@eecs.umich.edu (pte->G || (asn == pte->asid))) { 1076378Sgblack@eecs.umich.edu // We have a VPN + ASID Match 1085222Sksewell@umich.edu retval = pte; 1095222Sksewell@umich.edu break; 1106378Sgblack@eecs.umich.edu } 1115222Sksewell@umich.edu ++i; 1125222Sksewell@umich.edu } 1135019Sgblack@eecs.umich.edu } 1145019Sgblack@eecs.umich.edu 1155222Sksewell@umich.edu DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, 1165222Sksewell@umich.edu retval ? "hit" : "miss", retval ? retval->PFN1 : 0); 1175222Sksewell@umich.edu return retval; 1185222Sksewell@umich.edu} 1195222Sksewell@umich.edu 1206378Sgblack@eecs.umich.eduMipsISA::PTE* 1216378Sgblack@eecs.umich.eduTLB::getEntry(unsigned Index) const 1225222Sksewell@umich.edu{ 1235222Sksewell@umich.edu // Make sure that Index is valid 1245222Sksewell@umich.edu assert(Index<size); 1255222Sksewell@umich.edu return &table[Index]; 1265222Sksewell@umich.edu} 1275222Sksewell@umich.edu 1286378Sgblack@eecs.umich.eduint 1296378Sgblack@eecs.umich.eduTLB::probeEntry(Addr vpn, uint8_t asn) const 1305222Sksewell@umich.edu{ 1315222Sksewell@umich.edu // assume not found... 1326378Sgblack@eecs.umich.edu PTE *retval = NULL; 1336378Sgblack@eecs.umich.edu int Ind = -1; 1345222Sksewell@umich.edu PageTable::const_iterator i = lookupTable.find(vpn); 1355222Sksewell@umich.edu if (i != lookupTable.end()) { 1365222Sksewell@umich.edu while (i->first == vpn) { 1375222Sksewell@umich.edu int index = i->second; 1386378Sgblack@eecs.umich.edu PTE *pte = &table[index]; 1395222Sksewell@umich.edu 1405222Sksewell@umich.edu /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 1415222Sksewell@umich.edu Addr Mask = pte->Mask; 1425222Sksewell@umich.edu Addr InvMask = ~Mask; 1436378Sgblack@eecs.umich.edu Addr VPN = pte->VPN; 1446378Sgblack@eecs.umich.edu if (((vpn & InvMask) == (VPN & InvMask)) && 1456378Sgblack@eecs.umich.edu (pte->G || (asn == pte->asid))) { 1466378Sgblack@eecs.umich.edu // We have a VPN + ASID Match 1475222Sksewell@umich.edu retval = pte; 1485222Sksewell@umich.edu Ind = index; 1495222Sksewell@umich.edu break; 1506378Sgblack@eecs.umich.edu } 1515222Sksewell@umich.edu ++i; 1525222Sksewell@umich.edu } 1535222Sksewell@umich.edu } 1545222Sksewell@umich.edu DPRINTF(MipsPRA,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind); 1555222Sksewell@umich.edu return Ind; 1565222Sksewell@umich.edu} 1576378Sgblack@eecs.umich.edu 1586378Sgblack@eecs.umich.eduinline Fault 1595222Sksewell@umich.eduTLB::checkCacheability(RequestPtr &req) 1605222Sksewell@umich.edu{ 1616378Sgblack@eecs.umich.edu Addr VAddrUncacheable = 0xA0000000; 1626378Sgblack@eecs.umich.edu // In MIPS, cacheability is controlled by certain bits of the virtual 1636378Sgblack@eecs.umich.edu // address or by the TLB entry 1646378Sgblack@eecs.umich.edu if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) { 1656378Sgblack@eecs.umich.edu // mark request as uncacheable 1666378Sgblack@eecs.umich.edu req->setFlags(Request::UNCACHEABLE); 1676378Sgblack@eecs.umich.edu } 1686378Sgblack@eecs.umich.edu return NoFault; 1695222Sksewell@umich.edu} 1706378Sgblack@eecs.umich.edu 1716378Sgblack@eecs.umich.eduvoid 1726378Sgblack@eecs.umich.eduTLB::insertAt(PTE &pte, unsigned Index, int _smallPages) 1735222Sksewell@umich.edu{ 1746378Sgblack@eecs.umich.edu smallPages = _smallPages; 1756378Sgblack@eecs.umich.edu if (Index > size) { 1766378Sgblack@eecs.umich.edu warn("Attempted to write at index (%d) beyond TLB size (%d)", 1776378Sgblack@eecs.umich.edu Index, size); 1786378Sgblack@eecs.umich.edu } else { 1796378Sgblack@eecs.umich.edu // Update TLB 1806378Sgblack@eecs.umich.edu DPRINTF(TLB, "TLB[%d]: %x %x %x %x\n", 1816378Sgblack@eecs.umich.edu Index, pte.Mask << 11, 1826378Sgblack@eecs.umich.edu ((pte.VPN << 11) | pte.asid), 1836378Sgblack@eecs.umich.edu ((pte.PFN0 << 6) | (pte.C0 << 3) | 1846378Sgblack@eecs.umich.edu (pte.D0 << 2) | (pte.V0 <<1) | pte.G), 1856378Sgblack@eecs.umich.edu ((pte.PFN1 <<6) | (pte.C1 << 3) | 1866378Sgblack@eecs.umich.edu (pte.D1 << 2) | (pte.V1 <<1) | pte.G)); 1876378Sgblack@eecs.umich.edu if (table[Index].V0 == true || table[Index].V1 == true) { 1886378Sgblack@eecs.umich.edu // Previous entry is valid 1896378Sgblack@eecs.umich.edu PageTable::iterator i = lookupTable.find(table[Index].VPN); 1906378Sgblack@eecs.umich.edu lookupTable.erase(i); 1916378Sgblack@eecs.umich.edu } 1926378Sgblack@eecs.umich.edu table[Index]=pte; 1936378Sgblack@eecs.umich.edu // Update fast lookup table 1946378Sgblack@eecs.umich.edu lookupTable.insert(make_pair(table[Index].VPN, Index)); 1955222Sksewell@umich.edu } 1965222Sksewell@umich.edu} 1975222Sksewell@umich.edu 1985222Sksewell@umich.edu// insert a new TLB entry 1995222Sksewell@umich.eduvoid 2006378Sgblack@eecs.umich.eduTLB::insert(Addr addr, PTE &pte) 2015222Sksewell@umich.edu{ 2026378Sgblack@eecs.umich.edu fatal("TLB Insert not yet implemented\n"); 2035222Sksewell@umich.edu} 2045222Sksewell@umich.edu 2055222Sksewell@umich.eduvoid 2065222Sksewell@umich.eduTLB::flushAll() 2075222Sksewell@umich.edu{ 2085222Sksewell@umich.edu DPRINTF(TLB, "flushAll\n"); 2096378Sgblack@eecs.umich.edu memset(table, 0, sizeof(PTE[size])); 2105222Sksewell@umich.edu lookupTable.clear(); 2115222Sksewell@umich.edu nlu = 0; 2125222Sksewell@umich.edu} 2135222Sksewell@umich.edu 2145222Sksewell@umich.eduvoid 2155222Sksewell@umich.eduTLB::serialize(ostream &os) 2165222Sksewell@umich.edu{ 2175222Sksewell@umich.edu SERIALIZE_SCALAR(size); 2185222Sksewell@umich.edu SERIALIZE_SCALAR(nlu); 2195222Sksewell@umich.edu 2205222Sksewell@umich.edu for (int i = 0; i < size; i++) { 2215222Sksewell@umich.edu nameOut(os, csprintf("%s.PTE%d", name(), i)); 2225222Sksewell@umich.edu table[i].serialize(os); 2235222Sksewell@umich.edu } 2245222Sksewell@umich.edu} 2255222Sksewell@umich.edu 2265222Sksewell@umich.eduvoid 2275222Sksewell@umich.eduTLB::unserialize(Checkpoint *cp, const string §ion) 2285222Sksewell@umich.edu{ 2295222Sksewell@umich.edu UNSERIALIZE_SCALAR(size); 2305222Sksewell@umich.edu UNSERIALIZE_SCALAR(nlu); 2315222Sksewell@umich.edu 2325222Sksewell@umich.edu for (int i = 0; i < size; i++) { 2335222Sksewell@umich.edu table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); 2345222Sksewell@umich.edu if (table[i].V0 || table[i].V1) { 2355222Sksewell@umich.edu lookupTable.insert(make_pair(table[i].VPN, i)); 2365222Sksewell@umich.edu } 2375222Sksewell@umich.edu } 2385222Sksewell@umich.edu} 2395222Sksewell@umich.edu 2405222Sksewell@umich.eduvoid 2415222Sksewell@umich.eduTLB::regStats() 2425222Sksewell@umich.edu{ 2435222Sksewell@umich.edu read_hits 2445222Sksewell@umich.edu .name(name() + ".read_hits") 2455222Sksewell@umich.edu .desc("DTB read hits") 2465222Sksewell@umich.edu ; 2475222Sksewell@umich.edu 2485222Sksewell@umich.edu read_misses 2495222Sksewell@umich.edu .name(name() + ".read_misses") 2505222Sksewell@umich.edu .desc("DTB read misses") 2515222Sksewell@umich.edu ; 2525222Sksewell@umich.edu 2535222Sksewell@umich.edu 2545222Sksewell@umich.edu read_accesses 2555222Sksewell@umich.edu .name(name() + ".read_accesses") 2565222Sksewell@umich.edu .desc("DTB read accesses") 2575222Sksewell@umich.edu ; 2585222Sksewell@umich.edu 2595222Sksewell@umich.edu write_hits 2605222Sksewell@umich.edu .name(name() + ".write_hits") 2615222Sksewell@umich.edu .desc("DTB write hits") 2625222Sksewell@umich.edu ; 2635222Sksewell@umich.edu 2645222Sksewell@umich.edu write_misses 2655222Sksewell@umich.edu .name(name() + ".write_misses") 2665222Sksewell@umich.edu .desc("DTB write misses") 2675222Sksewell@umich.edu ; 2685222Sksewell@umich.edu 2695222Sksewell@umich.edu 2705222Sksewell@umich.edu write_accesses 2715222Sksewell@umich.edu .name(name() + ".write_accesses") 2725222Sksewell@umich.edu .desc("DTB write accesses") 2735222Sksewell@umich.edu ; 2745222Sksewell@umich.edu 2755222Sksewell@umich.edu hits 2765222Sksewell@umich.edu .name(name() + ".hits") 2775222Sksewell@umich.edu .desc("DTB hits") 2785222Sksewell@umich.edu ; 2795222Sksewell@umich.edu 2805222Sksewell@umich.edu misses 2815222Sksewell@umich.edu .name(name() + ".misses") 2825222Sksewell@umich.edu .desc("DTB misses") 2835222Sksewell@umich.edu ; 2845222Sksewell@umich.edu 2855222Sksewell@umich.edu accesses 2865222Sksewell@umich.edu .name(name() + ".accesses") 2875222Sksewell@umich.edu .desc("DTB accesses") 2885222Sksewell@umich.edu ; 2895222Sksewell@umich.edu 2905222Sksewell@umich.edu hits = read_hits + write_hits; 2915222Sksewell@umich.edu misses = read_misses + write_misses; 2925222Sksewell@umich.edu accesses = read_accesses + write_accesses; 2935222Sksewell@umich.edu} 2945222Sksewell@umich.edu 2955222Sksewell@umich.eduFault 2966022Sgblack@eecs.umich.eduTLB::translateInst(RequestPtr req, ThreadContext *tc) 2975222Sksewell@umich.edu{ 2985224Sksewell@umich.edu#if !FULL_SYSTEM 2995224Sksewell@umich.edu Process * p = tc->getProcessPtr(); 3005224Sksewell@umich.edu 3015224Sksewell@umich.edu Fault fault = p->pTable->translate(req); 3026378Sgblack@eecs.umich.edu if (fault != NoFault) 3035224Sksewell@umich.edu return fault; 3045224Sksewell@umich.edu 3055224Sksewell@umich.edu return NoFault; 3065224Sksewell@umich.edu#else 3077708Sgblack@eecs.umich.edu Addr vaddr = req->getVaddr(); 3087708Sgblack@eecs.umich.edu 3097708Sgblack@eecs.umich.edu bool misaligned = (req->getSize() - 1) & vaddr; 3107708Sgblack@eecs.umich.edu 3117708Sgblack@eecs.umich.edu if (IsKSeg0(vaddr)) { 3126378Sgblack@eecs.umich.edu // Address will not be translated through TLB, set response, and go! 3137708Sgblack@eecs.umich.edu req->setPaddr(KSeg02Phys(vaddr)); 3146383Sgblack@eecs.umich.edu if (getOperatingMode(tc->readMiscReg(MISCREG_STATUS)) != mode_kernel || 3157708Sgblack@eecs.umich.edu misaligned) { 3166378Sgblack@eecs.umich.edu AddressErrorFault *Flt = new AddressErrorFault(); 3176378Sgblack@eecs.umich.edu /* BadVAddr must be set */ 3187708Sgblack@eecs.umich.edu Flt->badVAddr = vaddr; 3196378Sgblack@eecs.umich.edu return Flt; 3206378Sgblack@eecs.umich.edu } 3217708Sgblack@eecs.umich.edu } else if(IsKSeg1(vaddr)) { 3226378Sgblack@eecs.umich.edu // Address will not be translated through TLB, set response, and go! 3237708Sgblack@eecs.umich.edu req->setPaddr(KSeg02Phys(vaddr)); 3246378Sgblack@eecs.umich.edu } else { 3256378Sgblack@eecs.umich.edu /* 3266378Sgblack@eecs.umich.edu * This is an optimization - smallPages is updated every time a TLB 3276378Sgblack@eecs.umich.edu * operation is performed. That way, we don't need to look at 3286378Sgblack@eecs.umich.edu * Config3 _ SP and PageGrain _ ESP every time we do a TLB lookup 3296378Sgblack@eecs.umich.edu */ 3306378Sgblack@eecs.umich.edu Addr VPN; 3316378Sgblack@eecs.umich.edu if (smallPages == 1) { 3327708Sgblack@eecs.umich.edu VPN = (vaddr >> 11); 3336378Sgblack@eecs.umich.edu } else { 3347708Sgblack@eecs.umich.edu VPN = ((vaddr >> 11) & 0xFFFFFFFC); 3356378Sgblack@eecs.umich.edu } 3366378Sgblack@eecs.umich.edu uint8_t Asid = req->getAsid(); 3377708Sgblack@eecs.umich.edu if (misaligned) { 3386378Sgblack@eecs.umich.edu // Unaligned address! 3395222Sksewell@umich.edu AddressErrorFault *Flt = new AddressErrorFault(); 3405222Sksewell@umich.edu /* BadVAddr must be set */ 3417708Sgblack@eecs.umich.edu Flt->badVAddr = vaddr; 3425222Sksewell@umich.edu return Flt; 3435222Sksewell@umich.edu } 3446378Sgblack@eecs.umich.edu PTE *pte = lookup(VPN,Asid); 3456378Sgblack@eecs.umich.edu if (pte != NULL) { 3466378Sgblack@eecs.umich.edu // Ok, found something 3475222Sksewell@umich.edu /* Check for valid bits */ 3485222Sksewell@umich.edu int EvenOdd; 3495222Sksewell@umich.edu bool Valid; 3507708Sgblack@eecs.umich.edu if ((((vaddr) >> pte->AddrShiftAmount) & 1) == 0) { 3516378Sgblack@eecs.umich.edu // Check even bits 3526378Sgblack@eecs.umich.edu Valid = pte->V0; 3536378Sgblack@eecs.umich.edu EvenOdd = 0; 3545222Sksewell@umich.edu } else { 3556378Sgblack@eecs.umich.edu // Check odd bits 3566378Sgblack@eecs.umich.edu Valid = pte->V1; 3576378Sgblack@eecs.umich.edu EvenOdd = 1; 3585222Sksewell@umich.edu } 3595222Sksewell@umich.edu 3606378Sgblack@eecs.umich.edu if (Valid == false) { 3616378Sgblack@eecs.umich.edu //Invalid entry 3625222Sksewell@umich.edu ItbInvalidFault *Flt = new ItbInvalidFault(); 3635222Sksewell@umich.edu /* EntryHi VPN, ASID fields must be set */ 3646379Sgblack@eecs.umich.edu Flt->entryHiAsid = Asid; 3656379Sgblack@eecs.umich.edu Flt->entryHiVPN2 = (VPN >> 2); 3666379Sgblack@eecs.umich.edu Flt->entryHiVPN2X = (VPN & 0x3); 3675222Sksewell@umich.edu 3685222Sksewell@umich.edu /* BadVAddr must be set */ 3697708Sgblack@eecs.umich.edu Flt->badVAddr = vaddr; 3705222Sksewell@umich.edu 3715222Sksewell@umich.edu /* Context must be set */ 3726379Sgblack@eecs.umich.edu Flt->contextBadVPN2 = (VPN >> 2); 3735222Sksewell@umich.edu return Flt; 3746378Sgblack@eecs.umich.edu } else { 3756378Sgblack@eecs.umich.edu // Ok, this is really a match, set paddr 3765222Sksewell@umich.edu Addr PAddr; 3776378Sgblack@eecs.umich.edu if (EvenOdd == 0) { 3785222Sksewell@umich.edu PAddr = pte->PFN0; 3796378Sgblack@eecs.umich.edu } else { 3805222Sksewell@umich.edu PAddr = pte->PFN1; 3815222Sksewell@umich.edu } 3826378Sgblack@eecs.umich.edu PAddr >>= (pte->AddrShiftAmount - 12); 3835222Sksewell@umich.edu PAddr <<= pte->AddrShiftAmount; 3847708Sgblack@eecs.umich.edu PAddr |= (vaddr & pte->OffsetMask); 3855222Sksewell@umich.edu req->setPaddr(PAddr); 3866378Sgblack@eecs.umich.edu } 3876378Sgblack@eecs.umich.edu } else { 3886378Sgblack@eecs.umich.edu // Didn't find any match, return a TLB Refill Exception 3896383Sgblack@eecs.umich.edu ItbRefillFault *Flt = new ItbRefillFault(); 3906378Sgblack@eecs.umich.edu /* EntryHi VPN, ASID fields must be set */ 3916379Sgblack@eecs.umich.edu Flt->entryHiAsid = Asid; 3926379Sgblack@eecs.umich.edu Flt->entryHiVPN2 = (VPN >> 2); 3936379Sgblack@eecs.umich.edu Flt->entryHiVPN2X = (VPN & 0x3); 3945222Sksewell@umich.edu 3956378Sgblack@eecs.umich.edu /* BadVAddr must be set */ 3967708Sgblack@eecs.umich.edu Flt->badVAddr = vaddr; 3975222Sksewell@umich.edu 3986378Sgblack@eecs.umich.edu /* Context must be set */ 3996379Sgblack@eecs.umich.edu Flt->contextBadVPN2 = (VPN >> 2); 4006378Sgblack@eecs.umich.edu return Flt; 4015222Sksewell@umich.edu } 4025222Sksewell@umich.edu } 4036378Sgblack@eecs.umich.edu return checkCacheability(req); 4045224Sksewell@umich.edu#endif 4055222Sksewell@umich.edu} 4065222Sksewell@umich.edu 4075222Sksewell@umich.eduFault 4086022Sgblack@eecs.umich.eduTLB::translateData(RequestPtr req, ThreadContext *tc, bool write) 4095222Sksewell@umich.edu{ 4105224Sksewell@umich.edu#if !FULL_SYSTEM 4116038Sksewell@umich.edu //@TODO: This should actually use TLB instead of going directly 4126038Sksewell@umich.edu // to the page table in syscall mode. 4136038Sksewell@umich.edu /** 4146038Sksewell@umich.edu * Check for alignment faults 4156038Sksewell@umich.edu */ 4166038Sksewell@umich.edu if (req->getVaddr() & (req->getSize() - 1)) { 4176038Sksewell@umich.edu DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(), 4186038Sksewell@umich.edu req->getSize()); 4196038Sksewell@umich.edu return new AlignmentFault(); 4206038Sksewell@umich.edu } 4216038Sksewell@umich.edu 4226038Sksewell@umich.edu 4235224Sksewell@umich.edu Process * p = tc->getProcessPtr(); 4245224Sksewell@umich.edu 4255224Sksewell@umich.edu Fault fault = p->pTable->translate(req); 4266378Sgblack@eecs.umich.edu if (fault != NoFault) 4275224Sksewell@umich.edu return fault; 4285224Sksewell@umich.edu 4295224Sksewell@umich.edu return NoFault; 4305224Sksewell@umich.edu#else 4317708Sgblack@eecs.umich.edu Addr vaddr = req->getVaddr(); 4327708Sgblack@eecs.umich.edu 4337708Sgblack@eecs.umich.edu bool misaligned = (req->getSize() - 1) & vaddr; 4347708Sgblack@eecs.umich.edu 4357708Sgblack@eecs.umich.edu if (IsKSeg0(vaddr)) { 4366378Sgblack@eecs.umich.edu // Address will not be translated through TLB, set response, and go! 4377708Sgblack@eecs.umich.edu req->setPaddr(KSeg02Phys(vaddr)); 4386383Sgblack@eecs.umich.edu if (getOperatingMode(tc->readMiscReg(MISCREG_STATUS)) != mode_kernel || 4397708Sgblack@eecs.umich.edu misaligned) { 4406378Sgblack@eecs.umich.edu StoreAddressErrorFault *Flt = new StoreAddressErrorFault(); 4416378Sgblack@eecs.umich.edu /* BadVAddr must be set */ 4427708Sgblack@eecs.umich.edu Flt->badVAddr = vaddr; 4436378Sgblack@eecs.umich.edu 4446378Sgblack@eecs.umich.edu return Flt; 4456378Sgblack@eecs.umich.edu } 4467708Sgblack@eecs.umich.edu } else if(IsKSeg1(vaddr)) { 4475222Sksewell@umich.edu // Address will not be translated through TLB, set response, and go! 4487708Sgblack@eecs.umich.edu req->setPaddr(KSeg02Phys(vaddr)); 4496378Sgblack@eecs.umich.edu } else { 4506378Sgblack@eecs.umich.edu /* 4516378Sgblack@eecs.umich.edu * This is an optimization - smallPages is updated every time a TLB 4526378Sgblack@eecs.umich.edu * operation is performed. That way, we don't need to look at 4536378Sgblack@eecs.umich.edu * Config3 _ SP and PageGrain _ ESP every time we do a TLB lookup 4546378Sgblack@eecs.umich.edu */ 4557708Sgblack@eecs.umich.edu Addr VPN = (vaddr >> 11) & 0xFFFFFFFC; 4566378Sgblack@eecs.umich.edu if (smallPages == 1) { 4577708Sgblack@eecs.umich.edu VPN = vaddr >> 11; 4586378Sgblack@eecs.umich.edu } 4596378Sgblack@eecs.umich.edu uint8_t Asid = req->getAsid(); 4606378Sgblack@eecs.umich.edu PTE *pte = lookup(VPN, Asid); 4617708Sgblack@eecs.umich.edu if (misaligned) { 4626378Sgblack@eecs.umich.edu // Unaligned address! 4636378Sgblack@eecs.umich.edu StoreAddressErrorFault *Flt = new StoreAddressErrorFault(); 4646378Sgblack@eecs.umich.edu /* BadVAddr must be set */ 4657708Sgblack@eecs.umich.edu Flt->badVAddr = vaddr; 4666378Sgblack@eecs.umich.edu return Flt; 4676378Sgblack@eecs.umich.edu } 4686378Sgblack@eecs.umich.edu if (pte != NULL) { 4696378Sgblack@eecs.umich.edu // Ok, found something 4706378Sgblack@eecs.umich.edu /* Check for valid bits */ 4716378Sgblack@eecs.umich.edu int EvenOdd; 4726378Sgblack@eecs.umich.edu bool Valid; 4736378Sgblack@eecs.umich.edu bool Dirty; 4747708Sgblack@eecs.umich.edu if ((((vaddr >> pte->AddrShiftAmount) & 1)) == 0) { 4756378Sgblack@eecs.umich.edu // Check even bits 4766378Sgblack@eecs.umich.edu Valid = pte->V0; 4776378Sgblack@eecs.umich.edu Dirty = pte->D0; 4786378Sgblack@eecs.umich.edu EvenOdd = 0; 4796378Sgblack@eecs.umich.edu } else { 4806378Sgblack@eecs.umich.edu // Check odd bits 4816378Sgblack@eecs.umich.edu Valid = pte->V1; 4826378Sgblack@eecs.umich.edu Dirty = pte->D1; 4836378Sgblack@eecs.umich.edu EvenOdd = 1; 4846378Sgblack@eecs.umich.edu } 4855222Sksewell@umich.edu 4866378Sgblack@eecs.umich.edu if (Valid == false) { 4876378Sgblack@eecs.umich.edu //Invalid entry 4886378Sgblack@eecs.umich.edu DtbInvalidFault *Flt = new DtbInvalidFault(); 4896378Sgblack@eecs.umich.edu /* EntryHi VPN, ASID fields must be set */ 4906379Sgblack@eecs.umich.edu Flt->entryHiAsid = Asid; 4916379Sgblack@eecs.umich.edu Flt->entryHiVPN2 = (VPN>>2); 4926379Sgblack@eecs.umich.edu Flt->entryHiVPN2X = (VPN & 0x3); 4935222Sksewell@umich.edu 4946378Sgblack@eecs.umich.edu /* BadVAddr must be set */ 4957708Sgblack@eecs.umich.edu Flt->badVAddr = vaddr; 4965222Sksewell@umich.edu 4976378Sgblack@eecs.umich.edu /* Context must be set */ 4986379Sgblack@eecs.umich.edu Flt->contextBadVPN2 = (VPN >> 2); 4995222Sksewell@umich.edu 5006378Sgblack@eecs.umich.edu return Flt; 5016378Sgblack@eecs.umich.edu } else { 5026378Sgblack@eecs.umich.edu // Ok, this is really a match, set paddr 5036378Sgblack@eecs.umich.edu if (!Dirty) { 5046378Sgblack@eecs.umich.edu TLBModifiedFault *Flt = new TLBModifiedFault(); 5056378Sgblack@eecs.umich.edu /* EntryHi VPN, ASID fields must be set */ 5066379Sgblack@eecs.umich.edu Flt->entryHiAsid = Asid; 5076379Sgblack@eecs.umich.edu Flt->entryHiVPN2 = (VPN >> 2); 5086379Sgblack@eecs.umich.edu Flt->entryHiVPN2X = (VPN & 0x3); 5095222Sksewell@umich.edu 5106378Sgblack@eecs.umich.edu /* BadVAddr must be set */ 5117708Sgblack@eecs.umich.edu Flt->badVAddr = vaddr; 5125222Sksewell@umich.edu 5136378Sgblack@eecs.umich.edu /* Context must be set */ 5146379Sgblack@eecs.umich.edu Flt->contextBadVPN2 = (VPN >> 2); 5156378Sgblack@eecs.umich.edu return Flt; 5166378Sgblack@eecs.umich.edu } 5176378Sgblack@eecs.umich.edu Addr PAddr; 5186378Sgblack@eecs.umich.edu if (EvenOdd == 0) { 5196378Sgblack@eecs.umich.edu PAddr = pte->PFN0; 5206378Sgblack@eecs.umich.edu } else { 5216378Sgblack@eecs.umich.edu PAddr = pte->PFN1; 5226378Sgblack@eecs.umich.edu } 5236378Sgblack@eecs.umich.edu PAddr >>= (pte->AddrShiftAmount - 12); 5246378Sgblack@eecs.umich.edu PAddr <<= pte->AddrShiftAmount; 5257708Sgblack@eecs.umich.edu PAddr |= (vaddr & pte->OffsetMask); 5266378Sgblack@eecs.umich.edu req->setPaddr(PAddr); 5276378Sgblack@eecs.umich.edu } 5286378Sgblack@eecs.umich.edu } else { 5296378Sgblack@eecs.umich.edu // Didn't find any match, return a TLB Refill Exception 5306378Sgblack@eecs.umich.edu DtbRefillFault *Flt = new DtbRefillFault(); 5316378Sgblack@eecs.umich.edu /* EntryHi VPN, ASID fields must be set */ 5326379Sgblack@eecs.umich.edu Flt->entryHiAsid = Asid; 5336379Sgblack@eecs.umich.edu Flt->entryHiVPN2 = (VPN >> 2); 5346379Sgblack@eecs.umich.edu Flt->entryHiVPN2X = (VPN & 0x3); 5355222Sksewell@umich.edu 5366378Sgblack@eecs.umich.edu /* BadVAddr must be set */ 5377708Sgblack@eecs.umich.edu Flt->badVAddr = vaddr; 5385222Sksewell@umich.edu 5396378Sgblack@eecs.umich.edu /* Context must be set */ 5406379Sgblack@eecs.umich.edu Flt->contextBadVPN2 = (VPN >> 2); 5416378Sgblack@eecs.umich.edu return Flt; 5425222Sksewell@umich.edu } 5435222Sksewell@umich.edu } 5445222Sksewell@umich.edu return checkCacheability(req); 5455224Sksewell@umich.edu#endif 5465222Sksewell@umich.edu} 5475222Sksewell@umich.edu 5486022Sgblack@eecs.umich.eduFault 5496023Snate@binkert.orgTLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) 5506022Sgblack@eecs.umich.edu{ 5516023Snate@binkert.org if (mode == Execute) 5526022Sgblack@eecs.umich.edu return translateInst(req, tc); 5536022Sgblack@eecs.umich.edu else 5546023Snate@binkert.org return translateData(req, tc, mode == Write); 5556022Sgblack@eecs.umich.edu} 5566022Sgblack@eecs.umich.edu 5575894Sgblack@eecs.umich.eduvoid 5586022Sgblack@eecs.umich.eduTLB::translateTiming(RequestPtr req, ThreadContext *tc, 5596023Snate@binkert.org Translation *translation, Mode mode) 5605894Sgblack@eecs.umich.edu{ 5615894Sgblack@eecs.umich.edu assert(translation); 5626023Snate@binkert.org translation->finish(translateAtomic(req, tc, mode), req, tc, mode); 5635894Sgblack@eecs.umich.edu} 5645894Sgblack@eecs.umich.edu 5655222Sksewell@umich.edu 5665222Sksewell@umich.eduMipsISA::PTE & 5675222Sksewell@umich.eduTLB::index(bool advance) 5685222Sksewell@umich.edu{ 5696378Sgblack@eecs.umich.edu PTE *pte = &table[nlu]; 5705222Sksewell@umich.edu 5715222Sksewell@umich.edu if (advance) 5725222Sksewell@umich.edu nextnlu(); 5735222Sksewell@umich.edu 5745222Sksewell@umich.edu return *pte; 5755222Sksewell@umich.edu} 5764997Sgblack@eecs.umich.edu 5776022Sgblack@eecs.umich.eduMipsISA::TLB * 5786022Sgblack@eecs.umich.eduMipsTLBParams::create() 5794997Sgblack@eecs.umich.edu{ 5806378Sgblack@eecs.umich.edu return new TLB(this); 5814997Sgblack@eecs.umich.edu} 582