tlb.cc revision 2984:797622d7b311
18706Sandreas.hansson@arm.com/* 27586SAli.Saidi@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 37586SAli.Saidi@arm.com * All rights reserved. 47586SAli.Saidi@arm.com * 57586SAli.Saidi@arm.com * Redistribution and use in source and binary forms, with or without 67586SAli.Saidi@arm.com * modification, are permitted provided that the following conditions are 77586SAli.Saidi@arm.com * met: redistributions of source code must retain the above copyright 87586SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer; 97586SAli.Saidi@arm.com * redistributions in binary form must reproduce the above copyright 107586SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer in the 117586SAli.Saidi@arm.com * documentation and/or other materials provided with the distribution; 127586SAli.Saidi@arm.com * neither the name of the copyright holders nor the names of its 137905SBrad.Beckmann@amd.com * contributors may be used to endorse or promote products derived from 145323Sgblack@eecs.umich.edu * this software without specific prior written permission. 152934Sktlim@umich.edu * 162934Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172934Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182934Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192934Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202934Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212934Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222934Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232934Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242934Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252934Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262934Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272934Sktlim@umich.edu * 282934Sktlim@umich.edu * Authors: Nathan Binkert 292934Sktlim@umich.edu * Steve Reinhardt 302934Sktlim@umich.edu * Andrew Schultz 312934Sktlim@umich.edu */ 322934Sktlim@umich.edu 332934Sktlim@umich.edu#include <string> 342934Sktlim@umich.edu#include <vector> 352934Sktlim@umich.edu 362934Sktlim@umich.edu#include "arch/alpha/pagetable.hh" 372934Sktlim@umich.edu#include "arch/alpha/tlb.hh" 382934Sktlim@umich.edu#include "arch/alpha/faults.hh" 392934Sktlim@umich.edu#include "base/inifile.hh" 402934Sktlim@umich.edu#include "base/str.hh" 412934Sktlim@umich.edu#include "base/trace.hh" 422934Sktlim@umich.edu#include "config/alpha_tlaser.hh" 432995Ssaidi@eecs.umich.edu#include "cpu/thread_context.hh" 4410046Snilay@cs.wisc.edu#include "sim/builder.hh" 452934Sktlim@umich.edu 462934Sktlim@umich.eduusing namespace std; 472934Sktlim@umich.eduusing namespace EV5; 482934Sktlim@umich.edu 492934Sktlim@umich.edu/////////////////////////////////////////////////////////////////////// 502934Sktlim@umich.edu// 512934Sktlim@umich.edu// Alpha TLB 522934Sktlim@umich.edu// 5310720Sandreas.hansson@arm.com#ifdef DEBUG 546122SSteve.Reinhardt@amd.combool uncacheBit39 = false; 556122SSteve.Reinhardt@amd.combool uncacheBit40 = false; 566122SSteve.Reinhardt@amd.com#endif 576122SSteve.Reinhardt@amd.com 5810594Sgabeblack@google.com#define MODE2MASK(X) (1 << (X)) 5910594Sgabeblack@google.com 6010697SCurtis.Dunham@arm.comAlphaTLB::AlphaTLB(const string &name, int s) 6110594Sgabeblack@google.com : SimObject(name), size(s), nlu(0) 6210594Sgabeblack@google.com{ 6310594Sgabeblack@google.com table = new AlphaISA::PTE[size]; 6410594Sgabeblack@google.com memset(table, 0, sizeof(AlphaISA::PTE[size])); 6510594Sgabeblack@google.com} 6610118Snilay@cs.wisc.edu 674520Ssaidi@eecs.umich.eduAlphaTLB::~AlphaTLB() 684982Ssaidi@eecs.umich.edu{ 694520Ssaidi@eecs.umich.edu if (table) 704520Ssaidi@eecs.umich.edu delete [] table; 712934Sktlim@umich.edu} 722934Sktlim@umich.edu 733005Sstever@eecs.umich.edu// look up an entry in the TLB 743005Sstever@eecs.umich.eduAlphaISA::PTE * 753304Sstever@eecs.umich.eduAlphaTLB::lookup(Addr vpn, uint8_t asn) const 762995Ssaidi@eecs.umich.edu{ 7710118Snilay@cs.wisc.edu // assume not found... 7810118Snilay@cs.wisc.edu AlphaISA::PTE *retval = NULL; 7910118Snilay@cs.wisc.edu 8010118Snilay@cs.wisc.edu PageTable::const_iterator i = lookupTable.find(vpn); 8110720Sandreas.hansson@arm.com if (i != lookupTable.end()) { 8210118Snilay@cs.wisc.edu while (i->first == vpn) { 8310118Snilay@cs.wisc.edu int index = i->second; 8410118Snilay@cs.wisc.edu AlphaISA::PTE *pte = &table[index]; 8510118Snilay@cs.wisc.edu assert(pte->valid); 8610118Snilay@cs.wisc.edu if (vpn == pte->tag && (pte->asma || pte->asn == asn)) { 8710118Snilay@cs.wisc.edu retval = pte; 8810118Snilay@cs.wisc.edu break; 8910118Snilay@cs.wisc.edu } 9010118Snilay@cs.wisc.edu 9110118Snilay@cs.wisc.edu ++i; 9210118Snilay@cs.wisc.edu } 9310118Snilay@cs.wisc.edu } 9410118Snilay@cs.wisc.edu 9510118Snilay@cs.wisc.edu DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, 9610118Snilay@cs.wisc.edu retval ? "hit" : "miss", retval ? retval->ppn : 0); 9710118Snilay@cs.wisc.edu return retval; 9810118Snilay@cs.wisc.edu} 9910118Snilay@cs.wisc.edu 10010118Snilay@cs.wisc.edu 1018713Sandreas.hansson@arm.comFault 10210118Snilay@cs.wisc.eduAlphaTLB::checkCacheability(RequestPtr &req) 10310118Snilay@cs.wisc.edu{ 10410118Snilay@cs.wisc.edu // in Alpha, cacheability is controlled by upper-level bits of the 10510118Snilay@cs.wisc.edu // physical address 10610118Snilay@cs.wisc.edu 10710118Snilay@cs.wisc.edu /* 10810118Snilay@cs.wisc.edu * We support having the uncacheable bit in either bit 39 or bit 40. 10910118Snilay@cs.wisc.edu * The Turbolaser platform (and EV5) support having the bit in 39, but 1109826Sandreas.hansson@arm.com * Tsunami (which Linux assumes uses an EV6) generates accesses with 1112934Sktlim@umich.edu * the bit in 40. So we must check for both, but we have debug flags 1122934Sktlim@umich.edu * to catch a weird case where both are used, which shouldn't happen. 1132995Ssaidi@eecs.umich.edu */ 1142934Sktlim@umich.edu 1156765SBrad.Beckmann@amd.com 1166765SBrad.Beckmann@amd.com#if ALPHA_TLASER 1176765SBrad.Beckmann@amd.com if (req->getPaddr() & PAddrUncachedBit39) { 1186765SBrad.Beckmann@amd.com#else 1196765SBrad.Beckmann@amd.com if (req->getPaddr() & PAddrUncachedBit43) { 1206765SBrad.Beckmann@amd.com#endif 1216765SBrad.Beckmann@amd.com // IPR memory space not implemented 1226765SBrad.Beckmann@amd.com if (PAddrIprSpace(req->getPaddr())) { 12310594Sgabeblack@google.com return new UnimpFault("IPR memory space not implemented!"); 12410594Sgabeblack@google.com } else { 12510594Sgabeblack@google.com // mark request as uncacheable 1266765SBrad.Beckmann@amd.com req->setFlags(req->getFlags() | UNCACHEABLE); 1276765SBrad.Beckmann@amd.com 1286765SBrad.Beckmann@amd.com#if !ALPHA_TLASER 12910588Sgabeblack@google.com // Clear bits 42:35 of the physical address (10-2 in Tsunami manual) 1308713Sandreas.hansson@arm.com req->setPaddr(req->getPaddr() & PAddrUncachedMask); 1318713Sandreas.hansson@arm.com#endif 1328713Sandreas.hansson@arm.com } 1338713Sandreas.hansson@arm.com } 1344486Sbinkertn@umich.edu return NoFault; 1354486Sbinkertn@umich.edu} 1364486Sbinkertn@umich.edu 1374486Sbinkertn@umich.edu 1384486Sbinkertn@umich.edu// insert a new TLB entry 1394486Sbinkertn@umich.eduvoid 1404486Sbinkertn@umich.eduAlphaTLB::insert(Addr addr, AlphaISA::PTE &pte) 1413584Ssaidi@eecs.umich.edu{ 1423584Ssaidi@eecs.umich.edu AlphaISA::VAddr vaddr = addr; 1433584Ssaidi@eecs.umich.edu if (table[nlu].valid) { 1443584Ssaidi@eecs.umich.edu Addr oldvpn = table[nlu].tag; 1453584Ssaidi@eecs.umich.edu PageTable::iterator i = lookupTable.find(oldvpn); 14610720Sandreas.hansson@arm.com 1479036Sandreas.hansson@arm.com if (i == lookupTable.end()) 1489164Sandreas.hansson@arm.com panic("TLB entry not found in lookupTable"); 1493743Sgblack@eecs.umich.edu 1504104Ssaidi@eecs.umich.edu int index; 1513743Sgblack@eecs.umich.edu while ((index = i->second) != nlu) { 1529826Sandreas.hansson@arm.com if (table[index].tag != oldvpn) 1539826Sandreas.hansson@arm.com panic("TLB entry not found in lookupTable"); 1548839Sandreas.hansson@arm.com 1558839Sandreas.hansson@arm.com ++i; 1568839Sandreas.hansson@arm.com } 1578839Sandreas.hansson@arm.com 1588839Sandreas.hansson@arm.com DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); 1598839Sandreas.hansson@arm.com 1603584Ssaidi@eecs.umich.edu lookupTable.erase(i); 1613898Ssaidi@eecs.umich.edu } 1623898Ssaidi@eecs.umich.edu 1638839Sandreas.hansson@arm.com DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn); 1648713Sandreas.hansson@arm.com 1658713Sandreas.hansson@arm.com table[nlu] = pte; 1668713Sandreas.hansson@arm.com table[nlu].tag = vaddr.vpn(); 1678713Sandreas.hansson@arm.com table[nlu].valid = true; 1688713Sandreas.hansson@arm.com 1698713Sandreas.hansson@arm.com lookupTable.insert(make_pair(vaddr.vpn(), nlu)); 1708713Sandreas.hansson@arm.com nextnlu(); 1718713Sandreas.hansson@arm.com} 1728713Sandreas.hansson@arm.com 1738713Sandreas.hansson@arm.comvoid 1748713Sandreas.hansson@arm.comAlphaTLB::flushAll() 1758713Sandreas.hansson@arm.com{ 1768713Sandreas.hansson@arm.com DPRINTF(TLB, "flushAll\n"); 1778713Sandreas.hansson@arm.com memset(table, 0, sizeof(AlphaISA::PTE[size])); 1788713Sandreas.hansson@arm.com lookupTable.clear(); 1798713Sandreas.hansson@arm.com nlu = 0; 1808713Sandreas.hansson@arm.com} 1818713Sandreas.hansson@arm.com 1828713Sandreas.hansson@arm.comvoid 1834103Ssaidi@eecs.umich.eduAlphaTLB::flushProcesses() 1844103Ssaidi@eecs.umich.edu{ 1854103Ssaidi@eecs.umich.edu PageTable::iterator i = lookupTable.begin(); 1863745Sgblack@eecs.umich.edu PageTable::iterator end = lookupTable.end(); 1873745Sgblack@eecs.umich.edu while (i != end) { 1883745Sgblack@eecs.umich.edu int index = i->second; 1893584Ssaidi@eecs.umich.edu AlphaISA::PTE *pte = &table[index]; 1908839Sandreas.hansson@arm.com assert(pte->valid); 1918706Sandreas.hansson@arm.com 1923584Ssaidi@eecs.umich.edu // we can't increment i after we erase it, so save a copy and 1933584Ssaidi@eecs.umich.edu // increment it to get the next entry now 19410588Sgabeblack@google.com PageTable::iterator cur = i; 19510594Sgabeblack@google.com ++i; 1968061SAli.Saidi@ARM.com 1978061SAli.Saidi@ARM.com if (!pte->asma) { 1987586SAli.Saidi@arm.com DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); 1997586SAli.Saidi@arm.com pte->valid = false; 2007586SAli.Saidi@arm.com lookupTable.erase(cur); 2017586SAli.Saidi@arm.com } 2027586SAli.Saidi@arm.com } 2037586SAli.Saidi@arm.com} 2047586SAli.Saidi@arm.com 2057586SAli.Saidi@arm.comvoid 2067586SAli.Saidi@arm.comAlphaTLB::flushAddr(Addr addr, uint8_t asn) 2077586SAli.Saidi@arm.com{ 20810720Sandreas.hansson@arm.com AlphaISA::VAddr vaddr = addr; 2099036Sandreas.hansson@arm.com 2107586SAli.Saidi@arm.com PageTable::iterator i = lookupTable.find(vaddr.vpn()); 2119164Sandreas.hansson@arm.com if (i == lookupTable.end()) 2128839Sandreas.hansson@arm.com return; 2138839Sandreas.hansson@arm.com 2147586SAli.Saidi@arm.com while (i->first == vaddr.vpn()) { 2157586SAli.Saidi@arm.com int index = i->second; 2167586SAli.Saidi@arm.com AlphaISA::PTE *pte = &table[index]; 2177586SAli.Saidi@arm.com assert(pte->valid); 2187586SAli.Saidi@arm.com 2197586SAli.Saidi@arm.com if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) { 2207586SAli.Saidi@arm.com DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(), 2218870SAli.Saidi@ARM.com pte->ppn); 2228870SAli.Saidi@ARM.com 22310512SAli.Saidi@ARM.com // invalidate this entry 22410512SAli.Saidi@ARM.com pte->valid = false; 22510037SARM gem5 Developers 22610037SARM gem5 Developers lookupTable.erase(i); 22710512SAli.Saidi@ARM.com } 22810512SAli.Saidi@ARM.com 22910512SAli.Saidi@ARM.com ++i; 23010512SAli.Saidi@ARM.com } 23110512SAli.Saidi@ARM.com} 2327586SAli.Saidi@arm.com 2337586SAli.Saidi@arm.com 2347586SAli.Saidi@arm.comvoid 2357586SAli.Saidi@arm.comAlphaTLB::serialize(ostream &os) 2368528SAli.Saidi@ARM.com{ 2378528SAli.Saidi@ARM.com SERIALIZE_SCALAR(size); 23810353SGeoffrey.Blake@arm.com SERIALIZE_SCALAR(nlu); 23910353SGeoffrey.Blake@arm.com 24010353SGeoffrey.Blake@arm.com for (int i = 0; i < size; i++) { 2418528SAli.Saidi@ARM.com nameOut(os, csprintf("%s.PTE%d", name(), i)); 24210357SAli.Saidi@ARM.com table[i].serialize(os); 24310357SAli.Saidi@ARM.com } 24410357SAli.Saidi@ARM.com} 2458528SAli.Saidi@ARM.com 2468528SAli.Saidi@ARM.comvoid 24710507SAli.Saidi@ARM.comAlphaTLB::unserialize(Checkpoint *cp, const string §ion) 24810507SAli.Saidi@ARM.com{ 24910507SAli.Saidi@ARM.com UNSERIALIZE_SCALAR(size); 25010507SAli.Saidi@ARM.com UNSERIALIZE_SCALAR(nlu); 25110507SAli.Saidi@ARM.com 25210507SAli.Saidi@ARM.com for (int i = 0; i < size; i++) { 25310507SAli.Saidi@ARM.com table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); 25410507SAli.Saidi@ARM.com if (table[i].valid) { 25510507SAli.Saidi@ARM.com lookupTable.insert(make_pair(table[i].tag, i)); 25610507SAli.Saidi@ARM.com } 25710507SAli.Saidi@ARM.com } 25810507SAli.Saidi@ARM.com} 25910507SAli.Saidi@ARM.com 26010507SAli.Saidi@ARM.com 26110507SAli.Saidi@ARM.com/////////////////////////////////////////////////////////////////////// 26210507SAli.Saidi@ARM.com// 26310507SAli.Saidi@ARM.com// Alpha ITB 26410507SAli.Saidi@ARM.com// 2658061SAli.Saidi@ARM.comAlphaITB::AlphaITB(const std::string &name, int size) 2668061SAli.Saidi@ARM.com : AlphaTLB(name, size) 2678061SAli.Saidi@ARM.com{} 2688061SAli.Saidi@ARM.com 26910161Satgutier@umich.edu 27010512SAli.Saidi@ARM.comvoid 27110161Satgutier@umich.eduAlphaITB::regStats() 27210512SAli.Saidi@ARM.com{ 27310161Satgutier@umich.edu hits 27410161Satgutier@umich.edu .name(name() + ".hits") 27510161Satgutier@umich.edu .desc("ITB hits"); 2769929SAli.Saidi@ARM.com misses 2779929SAli.Saidi@ARM.com .name(name() + ".misses") 2787586SAli.Saidi@arm.com .desc("ITB misses"); 27910071Satgutier@umich.edu acv 28010594Sgabeblack@google.com .name(name() + ".acv") 28110594Sgabeblack@google.com .desc("ITB acv"); 28210594Sgabeblack@google.com accesses 28310697SCurtis.Dunham@arm.com .name(name() + ".accesses") 28410071Satgutier@umich.edu .desc("ITB accesses"); 2858870SAli.Saidi@ARM.com 2868528SAli.Saidi@ARM.com accesses = hits + misses; 2878528SAli.Saidi@ARM.com} 2888287SAli.Saidi@ARM.com 28910735Srb639@drexel.edu 29010735Srb639@drexel.eduFault 29110735Srb639@drexel.eduAlphaITB::translate(RequestPtr &req, ThreadContext *tc) const 29210667Smalek.musleh@gmail.com{ 29310594Sgabeblack@google.com if (AlphaISA::PcPAL(req->getVaddr())) { 2948713Sandreas.hansson@arm.com // strip off PAL PC marker (lsb is 1) 2957586SAli.Saidi@arm.com req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask); 2967586SAli.Saidi@arm.com hits++; 2977586SAli.Saidi@arm.com return NoFault; 2987949SAli.Saidi@ARM.com } 2997586SAli.Saidi@arm.com 3008839Sandreas.hansson@arm.com if (req->getFlags() & PHYSICAL) { 3018706Sandreas.hansson@arm.com req->setPaddr(req->getVaddr()); 3027586SAli.Saidi@arm.com } else { 3037586SAli.Saidi@arm.com // verify that this is a good virtual address 3047586SAli.Saidi@arm.com if (!validVirtualAddress(req->getVaddr())) { 30510594Sgabeblack@google.com acv++; 3065222Sksewell@umich.edu return new ItbAcvFault(req->getVaddr()); 3075222Sksewell@umich.edu } 3085222Sksewell@umich.edu 3095222Sksewell@umich.edu 3105222Sksewell@umich.edu // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5 3115222Sksewell@umich.edu // VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6 3125222Sksewell@umich.edu#if ALPHA_TLASER 3135222Sksewell@umich.edu if ((MCSR_SP(tc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && 3145222Sksewell@umich.edu VAddrSpaceEV5(req->getVaddr()) == 2) { 3155222Sksewell@umich.edu#else 31610720Sandreas.hansson@arm.com if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) { 3179036Sandreas.hansson@arm.com#endif 3189164Sandreas.hansson@arm.com // only valid in kernel mode 3199826Sandreas.hansson@arm.com if (ICM_CM(tc->readMiscReg(AlphaISA::IPR_ICM)) != 3208839Sandreas.hansson@arm.com AlphaISA::mode_kernel) { 3218839Sandreas.hansson@arm.com acv++; 3225222Sksewell@umich.edu return new ItbAcvFault(req->getVaddr()); 3235222Sksewell@umich.edu } 3245222Sksewell@umich.edu 3255222Sksewell@umich.edu req->setPaddr(req->getVaddr() & PAddrImplMask); 3265222Sksewell@umich.edu 3275222Sksewell@umich.edu#if !ALPHA_TLASER 3288839Sandreas.hansson@arm.com // sign extend the physical address properly 3298839Sandreas.hansson@arm.com if (req->getPaddr() & PAddrUncachedBit40) 3308839Sandreas.hansson@arm.com req->setPaddr(req->getPaddr() | ULL(0xf0000000000)); 3318839Sandreas.hansson@arm.com else 3328839Sandreas.hansson@arm.com req->setPaddr(req->getPaddr() & ULL(0xffffffffff)); 3338839Sandreas.hansson@arm.com#endif 3345222Sksewell@umich.edu 3355222Sksewell@umich.edu } else { 3365222Sksewell@umich.edu // not a physical address: need to look up pte 3375222Sksewell@umich.edu int asn = DTB_ASN_ASN(tc->readMiscReg(AlphaISA::IPR_DTB_ASN)); 3385478Snate@binkert.org AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(), 3395222Sksewell@umich.edu asn); 3405222Sksewell@umich.edu 34110594Sgabeblack@google.com if (!pte) { 34210594Sgabeblack@google.com misses++; 34310594Sgabeblack@google.com return new ItbPageFault(req->getVaddr()); 3445222Sksewell@umich.edu } 3458839Sandreas.hansson@arm.com 3468706Sandreas.hansson@arm.com req->setPaddr((pte->ppn << AlphaISA::PageShift) + 3475222Sksewell@umich.edu (AlphaISA::VAddr(req->getVaddr()).offset() 3485222Sksewell@umich.edu & ~3)); 3495323Sgblack@eecs.umich.edu 3505357Sgblack@eecs.umich.edu // check permissions for this access 3518323Ssteve.reinhardt@amd.com if (!(pte->xre & 3525323Sgblack@eecs.umich.edu (1 << ICM_CM(tc->readMiscReg(AlphaISA::IPR_ICM))))) { 3538858Sgblack@eecs.umich.edu // instruction access fault 3548713Sandreas.hansson@arm.com acv++; 3558713Sandreas.hansson@arm.com return new ItbAcvFault(req->getVaddr()); 3568713Sandreas.hansson@arm.com } 3578713Sandreas.hansson@arm.com 3588713Sandreas.hansson@arm.com hits++; 3598713Sandreas.hansson@arm.com } 3609036Sandreas.hansson@arm.com } 3617905SBrad.Beckmann@amd.com 3627905SBrad.Beckmann@amd.com // check that the physical address is ok (catch bad physical addresses) 36310720Sandreas.hansson@arm.com if (req->getPaddr() & ~PAddrImplMask) 3649164Sandreas.hansson@arm.com return genMachineCheckFault(); 3658839Sandreas.hansson@arm.com 3668839Sandreas.hansson@arm.com return checkCacheability(req); 36710438Smajiuyue@ncic.ac.cn 36810438Smajiuyue@ncic.ac.cn} 36910438Smajiuyue@ncic.ac.cn 37010438Smajiuyue@ncic.ac.cn/////////////////////////////////////////////////////////////////////// 37110438Smajiuyue@ncic.ac.cn// 37210438Smajiuyue@ncic.ac.cn// Alpha DTB 3738713Sandreas.hansson@arm.com// 3748713Sandreas.hansson@arm.comAlphaDTB::AlphaDTB(const std::string &name, int size) 37510438Smajiuyue@ncic.ac.cn : AlphaTLB(name, size) 3768713Sandreas.hansson@arm.com{} 3778713Sandreas.hansson@arm.com 3788713Sandreas.hansson@arm.comvoid 3798713Sandreas.hansson@arm.comAlphaDTB::regStats() 3808713Sandreas.hansson@arm.com{ 3818713Sandreas.hansson@arm.com read_hits 3828713Sandreas.hansson@arm.com .name(name() + ".read_hits") 3838713Sandreas.hansson@arm.com .desc("DTB read hits") 3849164Sandreas.hansson@arm.com ; 3858839Sandreas.hansson@arm.com 3868839Sandreas.hansson@arm.com read_misses 3878815Sgblack@eecs.umich.edu .name(name() + ".read_misses") 3888815Sgblack@eecs.umich.edu .desc("DTB read misses") 3898858Sgblack@eecs.umich.edu ; 3908858Sgblack@eecs.umich.edu 3917905SBrad.Beckmann@amd.com read_acv 3927905SBrad.Beckmann@amd.com .name(name() + ".read_acv") 3937905SBrad.Beckmann@amd.com .desc("DTB read access violations") 3947905SBrad.Beckmann@amd.com ; 3958839Sandreas.hansson@arm.com 3968706Sandreas.hansson@arm.com read_accesses 3977905SBrad.Beckmann@amd.com .name(name() + ".read_accesses") 3987905SBrad.Beckmann@amd.com .desc("DTB read accesses") 39910720Sandreas.hansson@arm.com ; 4007905SBrad.Beckmann@amd.com 4018929Snilay@cs.wisc.edu write_hits 4028929Snilay@cs.wisc.edu .name(name() + ".write_hits") 4038929Snilay@cs.wisc.edu .desc("DTB write hits") 40410118Snilay@cs.wisc.edu ; 4057905SBrad.Beckmann@amd.com 4067905SBrad.Beckmann@amd.com write_misses 40710588Sgabeblack@google.com .name(name() + ".write_misses") 4085613Sgblack@eecs.umich.edu .desc("DTB write misses") 4095613Sgblack@eecs.umich.edu ; 4105613Sgblack@eecs.umich.edu 4115133Sgblack@eecs.umich.edu write_acv 4125133Sgblack@eecs.umich.edu .name(name() + ".write_acv") 4135133Sgblack@eecs.umich.edu .desc("DTB write access violations") 4145133Sgblack@eecs.umich.edu ; 4155133Sgblack@eecs.umich.edu 4166802Sgblack@eecs.umich.edu write_accesses 4176802Sgblack@eecs.umich.edu .name(name() + ".write_accesses") 4185133Sgblack@eecs.umich.edu .desc("DTB write accesses") 41910041Snilay@cs.wisc.edu ; 42010041Snilay@cs.wisc.edu 42110041Snilay@cs.wisc.edu hits 42210041Snilay@cs.wisc.edu .name(name() + ".hits") 42310041Snilay@cs.wisc.edu .desc("DTB hits") 42410041Snilay@cs.wisc.edu ; 42510041Snilay@cs.wisc.edu 42610041Snilay@cs.wisc.edu misses 42710046Snilay@cs.wisc.edu .name(name() + ".misses") 42810046Snilay@cs.wisc.edu .desc("DTB misses") 42910046Snilay@cs.wisc.edu ; 43010046Snilay@cs.wisc.edu 43110041Snilay@cs.wisc.edu acv 43210041Snilay@cs.wisc.edu .name(name() + ".acv") 4335613Sgblack@eecs.umich.edu .desc("DTB access violations") 4345613Sgblack@eecs.umich.edu ; 4355638Sgblack@eecs.umich.edu 4367905SBrad.Beckmann@amd.com accesses 4377905SBrad.Beckmann@amd.com .name(name() + ".accesses") 4387905SBrad.Beckmann@amd.com .desc("DTB accesses") 4397905SBrad.Beckmann@amd.com ; 4407905SBrad.Beckmann@amd.com 4418858Sgblack@eecs.umich.edu hits = read_hits + write_hits; 4425613Sgblack@eecs.umich.edu misses = read_misses + write_misses; 4435613Sgblack@eecs.umich.edu acv = read_acv + write_acv; 4445613Sgblack@eecs.umich.edu accesses = read_accesses + write_accesses; 4455841Sgblack@eecs.umich.edu} 4465841Sgblack@eecs.umich.edu 4475841Sgblack@eecs.umich.eduFault 4485841Sgblack@eecs.umich.eduAlphaDTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const 4495841Sgblack@eecs.umich.edu{ 4505841Sgblack@eecs.umich.edu Addr pc = tc->readPC(); 4515841Sgblack@eecs.umich.edu 4525615Sgblack@eecs.umich.edu AlphaISA::mode_type mode = 4535615Sgblack@eecs.umich.edu (AlphaISA::mode_type)DTB_CM_CM(tc->readMiscReg(AlphaISA::IPR_DTB_CM)); 4545615Sgblack@eecs.umich.edu 4555615Sgblack@eecs.umich.edu 4565641Sgblack@eecs.umich.edu /** 4578323Ssteve.reinhardt@amd.com * Check for alignment faults 4588323Ssteve.reinhardt@amd.com */ 4596135Sgblack@eecs.umich.edu if (req->getVaddr() & (req->getSize() - 1)) { 4606135Sgblack@eecs.umich.edu DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(), 4616135Sgblack@eecs.umich.edu req->getSize()); 4626135Sgblack@eecs.umich.edu uint64_t flags = write ? MM_STAT_WR_MASK : 0; 4636135Sgblack@eecs.umich.edu return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags); 4646135Sgblack@eecs.umich.edu } 4658323Ssteve.reinhardt@amd.com 4665644Sgblack@eecs.umich.edu if (pc & 0x1) { 4676135Sgblack@eecs.umich.edu mode = (req->getFlags() & ALTMODE) ? 4685644Sgblack@eecs.umich.edu (AlphaISA::mode_type)ALT_MODE_AM( 4695644Sgblack@eecs.umich.edu tc->readMiscReg(AlphaISA::IPR_ALT_MODE)) 4705644Sgblack@eecs.umich.edu : AlphaISA::mode_kernel; 4716135Sgblack@eecs.umich.edu } 4728323Ssteve.reinhardt@amd.com 47310437Smajiuyue@ncic.ac.cn if (req->getFlags() & PHYSICAL) { 47410437Smajiuyue@ncic.ac.cn req->setPaddr(req->getVaddr()); 47510437Smajiuyue@ncic.ac.cn } else { 47610437Smajiuyue@ncic.ac.cn // verify that this is a good virtual address 47710437Smajiuyue@ncic.ac.cn if (!validVirtualAddress(req->getVaddr())) { 47810437Smajiuyue@ncic.ac.cn if (write) { write_acv++; } else { read_acv++; } 4798323Ssteve.reinhardt@amd.com uint64_t flags = (write ? MM_STAT_WR_MASK : 0) | 48010437Smajiuyue@ncic.ac.cn MM_STAT_BAD_VA_MASK | 48110437Smajiuyue@ncic.ac.cn MM_STAT_ACV_MASK; 4828323Ssteve.reinhardt@amd.com return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); 4835843Sgblack@eecs.umich.edu } 4845843Sgblack@eecs.umich.edu 4855843Sgblack@eecs.umich.edu // Check for "superpage" mapping 4865843Sgblack@eecs.umich.edu#if ALPHA_TLASER 48710437Smajiuyue@ncic.ac.cn if ((MCSR_SP(tc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && 4885843Sgblack@eecs.umich.edu VAddrSpaceEV5(req->getVaddr()) == 2) { 4896044Sgblack@eecs.umich.edu#else 4905843Sgblack@eecs.umich.edu if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) { 4918323Ssteve.reinhardt@amd.com#endif 4926135Sgblack@eecs.umich.edu 4936135Sgblack@eecs.umich.edu // only valid in kernel mode 4946135Sgblack@eecs.umich.edu if (DTB_CM_CM(tc->readMiscReg(AlphaISA::IPR_DTB_CM)) != 4956135Sgblack@eecs.umich.edu AlphaISA::mode_kernel) { 4966135Sgblack@eecs.umich.edu if (write) { write_acv++; } else { read_acv++; } 49710437Smajiuyue@ncic.ac.cn uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) | 4986135Sgblack@eecs.umich.edu MM_STAT_ACV_MASK); 4996135Sgblack@eecs.umich.edu return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); 5006135Sgblack@eecs.umich.edu } 5018323Ssteve.reinhardt@amd.com 5026135Sgblack@eecs.umich.edu req->setPaddr(req->getVaddr() & PAddrImplMask); 5036135Sgblack@eecs.umich.edu 5046135Sgblack@eecs.umich.edu#if !ALPHA_TLASER 5056135Sgblack@eecs.umich.edu // sign extend the physical address properly 50610437Smajiuyue@ncic.ac.cn if (req->getPaddr() & PAddrUncachedBit40) 5076135Sgblack@eecs.umich.edu req->setPaddr(req->getPaddr() | ULL(0xf0000000000)); 5086135Sgblack@eecs.umich.edu else 5096135Sgblack@eecs.umich.edu req->setPaddr(req->getPaddr() & ULL(0xffffffffff)); 5108323Ssteve.reinhardt@amd.com#endif 5116135Sgblack@eecs.umich.edu 5126135Sgblack@eecs.umich.edu } else { 5136135Sgblack@eecs.umich.edu if (write) 5146135Sgblack@eecs.umich.edu write_accesses++; 5158323Ssteve.reinhardt@amd.com else 5168323Ssteve.reinhardt@amd.com read_accesses++; 5175641Sgblack@eecs.umich.edu 51810594Sgabeblack@google.com int asn = DTB_ASN_ASN(tc->readMiscReg(AlphaISA::IPR_DTB_ASN)); 51910594Sgabeblack@google.com 5205613Sgblack@eecs.umich.edu // not a physical address: need to look up pte 5215613Sgblack@eecs.umich.edu AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(), 5227905SBrad.Beckmann@amd.com asn); 5239826Sandreas.hansson@arm.com 5245613Sgblack@eecs.umich.edu if (!pte) { 5255450Sgblack@eecs.umich.edu // page fault 5265450Sgblack@eecs.umich.edu if (write) { write_misses++; } else { read_misses++; } 5279826Sandreas.hansson@arm.com uint64_t flags = (write ? MM_STAT_WR_MASK : 0) | 5289232Sandreas.hansson@arm.com MM_STAT_DTB_MISS_MASK; 52910041Snilay@cs.wisc.edu return (req->getFlags() & VPTE) ? 5305450Sgblack@eecs.umich.edu (Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(), 53110041Snilay@cs.wisc.edu flags)) : 5328323Ssteve.reinhardt@amd.com (Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(), 5338323Ssteve.reinhardt@amd.com flags)); 5349622Snilay@cs.wisc.edu } 5359622Snilay@cs.wisc.edu 53610041Snilay@cs.wisc.edu req->setPaddr((pte->ppn << AlphaISA::PageShift) + 5378323Ssteve.reinhardt@amd.com AlphaISA::VAddr(req->getVaddr()).offset()); 53810041Snilay@cs.wisc.edu 5399898Sandreas@sandberg.pp.se if (write) { 5408323Ssteve.reinhardt@amd.com if (!(pte->xwe & MODE2MASK(mode))) { 5415450Sgblack@eecs.umich.edu // declare the instruction access fault 54210438Smajiuyue@ncic.ac.cn write_acv++; 54310438Smajiuyue@ncic.ac.cn uint64_t flags = MM_STAT_WR_MASK | 54410438Smajiuyue@ncic.ac.cn MM_STAT_ACV_MASK | 54510438Smajiuyue@ncic.ac.cn (pte->fonw ? MM_STAT_FONW_MASK : 0); 54610438Smajiuyue@ncic.ac.cn return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); 54710438Smajiuyue@ncic.ac.cn } 54810438Smajiuyue@ncic.ac.cn if (pte->fonw) { 54910438Smajiuyue@ncic.ac.cn write_acv++; 55010438Smajiuyue@ncic.ac.cn uint64_t flags = MM_STAT_WR_MASK | 55110438Smajiuyue@ncic.ac.cn MM_STAT_FONW_MASK; 55210438Smajiuyue@ncic.ac.cn return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); 55310041Snilay@cs.wisc.edu } 55410041Snilay@cs.wisc.edu } else { 55510041Snilay@cs.wisc.edu if (!(pte->xre & MODE2MASK(mode))) { 55610041Snilay@cs.wisc.edu read_acv++; 55710041Snilay@cs.wisc.edu uint64_t flags = MM_STAT_ACV_MASK | 55810041Snilay@cs.wisc.edu (pte->fonr ? MM_STAT_FONR_MASK : 0); 55910041Snilay@cs.wisc.edu return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); 56010041Snilay@cs.wisc.edu } 56110041Snilay@cs.wisc.edu if (pte->fonr) { 56210041Snilay@cs.wisc.edu read_acv++; 5635330Sgblack@eecs.umich.edu uint64_t flags = MM_STAT_FONR_MASK; 56410594Sgabeblack@google.com return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); 56510594Sgabeblack@google.com } 56610594Sgabeblack@google.com } 56710003Ssteve.reinhardt@amd.com } 5685133Sgblack@eecs.umich.edu 5695133Sgblack@eecs.umich.edu if (write) 5703584Ssaidi@eecs.umich.edu write_hits++; 5718801Sgblack@eecs.umich.edu else 5728801Sgblack@eecs.umich.edu read_hits++; 5732995Ssaidi@eecs.umich.edu } 5742995Ssaidi@eecs.umich.edu 5754981Ssaidi@eecs.umich.edu // check that the physical address is ok (catch bad physical addresses) 5764981Ssaidi@eecs.umich.edu if (req->getPaddr() & ~PAddrImplMask) 5778661SAli.Saidi@ARM.com return genMachineCheckFault(); 5788661SAli.Saidi@ARM.com 5798661SAli.Saidi@ARM.com return checkCacheability(req); 5808661SAli.Saidi@ARM.com} 5818661SAli.Saidi@ARM.com 5828661SAli.Saidi@ARM.comAlphaISA::PTE & 5838661SAli.Saidi@ARM.comAlphaTLB::index(bool advance) 5848661SAli.Saidi@ARM.com{ 5858661SAli.Saidi@ARM.com AlphaISA::PTE *pte = &table[nlu]; 5863025Ssaidi@eecs.umich.edu 5873025Ssaidi@eecs.umich.edu if (advance) 5883025Ssaidi@eecs.umich.edu nextnlu(); 5892934Sktlim@umich.edu 5902934Sktlim@umich.edu return *pte; 591} 592 593DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", AlphaTLB) 594 595BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaITB) 596 597 Param<int> size; 598 599END_DECLARE_SIM_OBJECT_PARAMS(AlphaITB) 600 601BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaITB) 602 603 INIT_PARAM_DFLT(size, "TLB size", 48) 604 605END_INIT_SIM_OBJECT_PARAMS(AlphaITB) 606 607 608CREATE_SIM_OBJECT(AlphaITB) 609{ 610 return new AlphaITB(getInstanceName(), size); 611} 612 613REGISTER_SIM_OBJECT("AlphaITB", AlphaITB) 614 615BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB) 616 617 Param<int> size; 618 619END_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB) 620 621BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDTB) 622 623 INIT_PARAM_DFLT(size, "TLB size", 64) 624 625END_INIT_SIM_OBJECT_PARAMS(AlphaDTB) 626 627 628CREATE_SIM_OBJECT(AlphaDTB) 629{ 630 return new AlphaDTB(getInstanceName(), size); 631} 632 633REGISTER_SIM_OBJECT("AlphaDTB", AlphaDTB) 634 635