tlb.cc revision 679
14997Sgblack@eecs.umich.edu/* 25417Sgblack@eecs.umich.edu * Copyright (c) 2003 The Regents of The University of Michigan 34997Sgblack@eecs.umich.edu * All rights reserved. 44997Sgblack@eecs.umich.edu * 54997Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 64997Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 74997Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 84997Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 94997Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 104997Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 114997Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 124997Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 134997Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 144997Sgblack@eecs.umich.edu * this software without specific prior written permission. 154997Sgblack@eecs.umich.edu * 164997Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 174997Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 184997Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194997Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 204997Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 214997Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 224997Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234997Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244997Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254997Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 264997Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274997Sgblack@eecs.umich.edu */ 284997Sgblack@eecs.umich.edu 294997Sgblack@eecs.umich.edu#include <sstream> 304997Sgblack@eecs.umich.edu#include <string> 314997Sgblack@eecs.umich.edu#include <vector> 324997Sgblack@eecs.umich.edu 334997Sgblack@eecs.umich.edu#include "base/inifile.hh" 344997Sgblack@eecs.umich.edu#include "base/str.hh" 354997Sgblack@eecs.umich.edu#include "base/trace.hh" 364997Sgblack@eecs.umich.edu#include "cpu/exec_context.hh" 374997Sgblack@eecs.umich.edu#include "sim/builder.hh" 384997Sgblack@eecs.umich.edu#include "targetarch/alpha_memory.hh" 394997Sgblack@eecs.umich.edu#include "targetarch/ev5.hh" 404997Sgblack@eecs.umich.edu 414997Sgblack@eecs.umich.eduusing namespace std; 424997Sgblack@eecs.umich.edu 434997Sgblack@eecs.umich.edu/////////////////////////////////////////////////////////////////////// 444997Sgblack@eecs.umich.edu// 454997Sgblack@eecs.umich.edu// Alpha TLB 464997Sgblack@eecs.umich.edu// 474997Sgblack@eecs.umich.eduAlphaTLB::AlphaTLB(const string &name, int s) 484997Sgblack@eecs.umich.edu : SimObject(name), size(s), nlu(0) 494997Sgblack@eecs.umich.edu{ 504997Sgblack@eecs.umich.edu table = new AlphaISA::PTE[size]; 514997Sgblack@eecs.umich.edu memset(table, 0, sizeof(AlphaISA::PTE[size])); 524997Sgblack@eecs.umich.edu} 534997Sgblack@eecs.umich.edu 544997Sgblack@eecs.umich.eduAlphaTLB::~AlphaTLB() 554997Sgblack@eecs.umich.edu{ 564997Sgblack@eecs.umich.edu if (table) 574997Sgblack@eecs.umich.edu delete [] table; 584997Sgblack@eecs.umich.edu} 594997Sgblack@eecs.umich.edu 605086Sgblack@eecs.umich.edu// look up an entry in the TLB 615086Sgblack@eecs.umich.eduAlphaISA::PTE * 625912Sgblack@eecs.umich.eduAlphaTLB::lookup(Addr vpn, uint8_t asn) const 636313Sgblack@eecs.umich.edu{ 645124Sgblack@eecs.umich.edu DPRINTF(TLB, "lookup %#x\n", vpn); 655086Sgblack@eecs.umich.edu 665149Sgblack@eecs.umich.edu PageTable::const_iterator i = lookupTable.find(vpn); 675086Sgblack@eecs.umich.edu if (i == lookupTable.end()) 685086Sgblack@eecs.umich.edu return NULL; 695237Sgblack@eecs.umich.edu 705086Sgblack@eecs.umich.edu while (i->first == vpn) { 715086Sgblack@eecs.umich.edu int index = i->second; 725086Sgblack@eecs.umich.edu AlphaISA::PTE *pte = &table[index]; 735086Sgblack@eecs.umich.edu assert(pte->valid); 745245Sgblack@eecs.umich.edu if (vpn == pte->tag && (pte->asma || pte->asn == asn)) 755245Sgblack@eecs.umich.edu return pte; 765245Sgblack@eecs.umich.edu 775895Sgblack@eecs.umich.edu ++i; 785895Sgblack@eecs.umich.edu } 795895Sgblack@eecs.umich.edu 805245Sgblack@eecs.umich.edu // not found... 815086Sgblack@eecs.umich.edu return NULL; 825086Sgblack@eecs.umich.edu} 835086Sgblack@eecs.umich.edu 845358Sgblack@eecs.umich.edu 855124Sgblack@eecs.umich.eduvoid 865124Sgblack@eecs.umich.eduAlphaTLB::checkCacheability(MemReqPtr &req) 875124Sgblack@eecs.umich.edu{ 885124Sgblack@eecs.umich.edu // in Alpha, cacheability is controlled by upper-level bits of the 895124Sgblack@eecs.umich.edu // physical address 905124Sgblack@eecs.umich.edu if (req->paddr & PA_UNCACHED_BIT) { 915124Sgblack@eecs.umich.edu if (PA_IPR_SPACE(req->paddr)) { 925237Sgblack@eecs.umich.edu // IPR memory space not implemented 935245Sgblack@eecs.umich.edu if (!req->xc->misspeculating()) { 945245Sgblack@eecs.umich.edu switch (req->paddr) { 955245Sgblack@eecs.umich.edu case ULL(0xFFFFF00188): 965236Sgblack@eecs.umich.edu req->data = 0; 975236Sgblack@eecs.umich.edu break; 985895Sgblack@eecs.umich.edu 995124Sgblack@eecs.umich.edu default: 1005124Sgblack@eecs.umich.edu panic("IPR memory space not implemented! PA=%x\n", 1015124Sgblack@eecs.umich.edu req->paddr); 1025124Sgblack@eecs.umich.edu } 1035124Sgblack@eecs.umich.edu } 1045124Sgblack@eecs.umich.edu } else { 1055124Sgblack@eecs.umich.edu // mark request as uncacheable 1065124Sgblack@eecs.umich.edu req->flags |= UNCACHEABLE; 1075124Sgblack@eecs.umich.edu } 1085124Sgblack@eecs.umich.edu } 1095124Sgblack@eecs.umich.edu} 1105124Sgblack@eecs.umich.edu 1115124Sgblack@eecs.umich.edu 1125124Sgblack@eecs.umich.edu// insert a new TLB entry 1135124Sgblack@eecs.umich.eduvoid 1145895Sgblack@eecs.umich.eduAlphaTLB::insert(Addr vaddr, AlphaISA::PTE &pte) 1155124Sgblack@eecs.umich.edu{ 1165124Sgblack@eecs.umich.edu if (table[nlu].valid) { 1175360Sgblack@eecs.umich.edu Addr oldvpn = table[nlu].tag; 1185360Sgblack@eecs.umich.edu PageTable::iterator i = lookupTable.find(oldvpn); 1195124Sgblack@eecs.umich.edu 1205124Sgblack@eecs.umich.edu if (i == lookupTable.end()) 1215124Sgblack@eecs.umich.edu panic("TLB entry not found in lookupTable"); 1225124Sgblack@eecs.umich.edu 1235124Sgblack@eecs.umich.edu int index; 1245124Sgblack@eecs.umich.edu while ((index = i->second) != nlu) { 1255124Sgblack@eecs.umich.edu if (table[index].tag != oldvpn) 1265124Sgblack@eecs.umich.edu panic("TLB entry not found in lookupTable"); 1275360Sgblack@eecs.umich.edu 1285124Sgblack@eecs.umich.edu ++i; 1295360Sgblack@eecs.umich.edu } 1305124Sgblack@eecs.umich.edu 1315360Sgblack@eecs.umich.edu DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); 1325124Sgblack@eecs.umich.edu 1335124Sgblack@eecs.umich.edu lookupTable.erase(i); 1345360Sgblack@eecs.umich.edu } 1355360Sgblack@eecs.umich.edu 1365360Sgblack@eecs.umich.edu Addr vpn = VA_VPN(vaddr); 1375360Sgblack@eecs.umich.edu DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vpn, pte.ppn); 1385360Sgblack@eecs.umich.edu 1395360Sgblack@eecs.umich.edu table[nlu] = pte; 1405360Sgblack@eecs.umich.edu table[nlu].tag = vpn; 1415360Sgblack@eecs.umich.edu table[nlu].valid = true; 1425360Sgblack@eecs.umich.edu 1435360Sgblack@eecs.umich.edu lookupTable.insert(make_pair(vpn, nlu)); 1445360Sgblack@eecs.umich.edu nextnlu(); 1455124Sgblack@eecs.umich.edu} 1465124Sgblack@eecs.umich.edu 1475124Sgblack@eecs.umich.eduvoid 1485124Sgblack@eecs.umich.eduAlphaTLB::flushAll() 1495124Sgblack@eecs.umich.edu{ 1505242Sgblack@eecs.umich.edu memset(table, 0, sizeof(AlphaISA::PTE[size])); 1515242Sgblack@eecs.umich.edu lookupTable.clear(); 1525242Sgblack@eecs.umich.edu nlu = 0; 1535242Sgblack@eecs.umich.edu} 1545242Sgblack@eecs.umich.edu 1555242Sgblack@eecs.umich.eduvoid 1565124Sgblack@eecs.umich.eduAlphaTLB::flushProcesses() 1575124Sgblack@eecs.umich.edu{ 1585124Sgblack@eecs.umich.edu PageTable::iterator i = lookupTable.begin(); 1595357Sgblack@eecs.umich.edu PageTable::iterator end = lookupTable.end(); 1605357Sgblack@eecs.umich.edu while (i != end) { 1615357Sgblack@eecs.umich.edu int index = i->second; 1625357Sgblack@eecs.umich.edu AlphaISA::PTE *pte = &table[index]; 1635357Sgblack@eecs.umich.edu assert(pte->valid); 1645357Sgblack@eecs.umich.edu 1655124Sgblack@eecs.umich.edu if (!pte->asma) { 1665124Sgblack@eecs.umich.edu DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); 1675242Sgblack@eecs.umich.edu pte->valid = false; 1685242Sgblack@eecs.umich.edu lookupTable.erase(i); 1695242Sgblack@eecs.umich.edu } 1705242Sgblack@eecs.umich.edu 1715242Sgblack@eecs.umich.edu ++i; 1725242Sgblack@eecs.umich.edu } 1735242Sgblack@eecs.umich.edu} 1745242Sgblack@eecs.umich.edu 1755242Sgblack@eecs.umich.eduvoid 1765242Sgblack@eecs.umich.eduAlphaTLB::flushAddr(Addr vaddr, uint8_t asn) 1775124Sgblack@eecs.umich.edu{ 1785124Sgblack@eecs.umich.edu Addr vpn = VA_VPN(vaddr); 1795124Sgblack@eecs.umich.edu 1805358Sgblack@eecs.umich.edu PageTable::iterator i = lookupTable.find(vpn); 1815086Sgblack@eecs.umich.edu if (i == lookupTable.end()) 1825359Sgblack@eecs.umich.edu return; 1835359Sgblack@eecs.umich.edu 1845359Sgblack@eecs.umich.edu while (i->first == vpn) { 1855359Sgblack@eecs.umich.edu int index = i->second; 1865359Sgblack@eecs.umich.edu AlphaISA::PTE *pte = &table[index]; 1875086Sgblack@eecs.umich.edu assert(pte->valid); 1885086Sgblack@eecs.umich.edu 1895086Sgblack@eecs.umich.edu if (vpn == pte->tag && (pte->asma || pte->asn == asn)) { 1906141Sgblack@eecs.umich.edu DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vpn, pte->ppn); 1916141Sgblack@eecs.umich.edu 1926141Sgblack@eecs.umich.edu // invalidate this entry 1936141Sgblack@eecs.umich.edu pte->valid = false; 1946141Sgblack@eecs.umich.edu 1956141Sgblack@eecs.umich.edu lookupTable.erase(i); 1966141Sgblack@eecs.umich.edu } 1976141Sgblack@eecs.umich.edu 1986141Sgblack@eecs.umich.edu ++i; 1996141Sgblack@eecs.umich.edu } 2006141Sgblack@eecs.umich.edu} 2016141Sgblack@eecs.umich.edu 2026141Sgblack@eecs.umich.edu 2036141Sgblack@eecs.umich.eduvoid 2046141Sgblack@eecs.umich.eduAlphaTLB::serialize(ostream &os) 2056141Sgblack@eecs.umich.edu{ 2066141Sgblack@eecs.umich.edu SERIALIZE_SCALAR(size); 2076141Sgblack@eecs.umich.edu SERIALIZE_SCALAR(nlu); 2086141Sgblack@eecs.umich.edu 2096141Sgblack@eecs.umich.edu for (int i = 0; i < size; i++) { 2106141Sgblack@eecs.umich.edu nameOut(os, csprintf("%s.PTE%d", name(), i)); 2116141Sgblack@eecs.umich.edu table[i].serialize(os); 2126141Sgblack@eecs.umich.edu } 2136141Sgblack@eecs.umich.edu} 2146141Sgblack@eecs.umich.edu 2156141Sgblack@eecs.umich.eduvoid 2166141Sgblack@eecs.umich.eduAlphaTLB::unserialize(Checkpoint *cp, const string §ion) 2176141Sgblack@eecs.umich.edu{ 2186141Sgblack@eecs.umich.edu UNSERIALIZE_SCALAR(size); 2196141Sgblack@eecs.umich.edu UNSERIALIZE_SCALAR(nlu); 2206141Sgblack@eecs.umich.edu 2216141Sgblack@eecs.umich.edu for (int i = 0; i < size; i++) { 2226141Sgblack@eecs.umich.edu table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); 2236141Sgblack@eecs.umich.edu if (table[i].valid) { 2246141Sgblack@eecs.umich.edu lookupTable.insert(make_pair(table[i].tag, i)); 2256141Sgblack@eecs.umich.edu } 2266141Sgblack@eecs.umich.edu } 2276141Sgblack@eecs.umich.edu} 2286141Sgblack@eecs.umich.edu 2296141Sgblack@eecs.umich.edu 2306141Sgblack@eecs.umich.edu/////////////////////////////////////////////////////////////////////// 2316141Sgblack@eecs.umich.edu// 2326141Sgblack@eecs.umich.edu// Alpha ITB 2336141Sgblack@eecs.umich.edu// 2346141Sgblack@eecs.umich.eduAlphaITB::AlphaITB(const std::string &name, int size) 2356141Sgblack@eecs.umich.edu : AlphaTLB(name, size) 2366141Sgblack@eecs.umich.edu{} 2376141Sgblack@eecs.umich.edu 2386141Sgblack@eecs.umich.edu 2396141Sgblack@eecs.umich.eduvoid 2406141Sgblack@eecs.umich.eduAlphaITB::regStats() 2416141Sgblack@eecs.umich.edu{ 2426141Sgblack@eecs.umich.edu hits 2436141Sgblack@eecs.umich.edu .name(name() + ".hits") 2446141Sgblack@eecs.umich.edu .desc("ITB hits"); 2456141Sgblack@eecs.umich.edu misses 2466141Sgblack@eecs.umich.edu .name(name() + ".misses") 2476141Sgblack@eecs.umich.edu .desc("ITB misses"); 2486141Sgblack@eecs.umich.edu acv 2496141Sgblack@eecs.umich.edu .name(name() + ".acv") 2506141Sgblack@eecs.umich.edu .desc("ITB acv"); 2516141Sgblack@eecs.umich.edu accesses 2526141Sgblack@eecs.umich.edu .name(name() + ".accesses") 2536141Sgblack@eecs.umich.edu .desc("ITB accesses"); 2546141Sgblack@eecs.umich.edu 2556141Sgblack@eecs.umich.edu accesses = hits + misses; 2566141Sgblack@eecs.umich.edu} 2576141Sgblack@eecs.umich.edu 2586141Sgblack@eecs.umich.eduvoid 2596141Sgblack@eecs.umich.eduAlphaITB::fault(Addr pc, ExecContext *xc) const 2606141Sgblack@eecs.umich.edu{ 2616141Sgblack@eecs.umich.edu uint64_t *ipr = xc->regs.ipr; 2626141Sgblack@eecs.umich.edu 2636141Sgblack@eecs.umich.edu if (!xc->misspeculating()) { 2646141Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_ITB_TAG] = pc; 2656141Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_IFAULT_VA_FORM] = 2666141Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_IVPTBR] | (VA_VPN(pc) << 3); 2676141Sgblack@eecs.umich.edu } 2686141Sgblack@eecs.umich.edu} 2696141Sgblack@eecs.umich.edu 2706141Sgblack@eecs.umich.edu 2716141Sgblack@eecs.umich.eduFault 2726141Sgblack@eecs.umich.eduAlphaITB::translate(MemReqPtr &req) const 2736141Sgblack@eecs.umich.edu{ 2746141Sgblack@eecs.umich.edu InternalProcReg *ipr = req->xc->regs.ipr; 2756141Sgblack@eecs.umich.edu 2766141Sgblack@eecs.umich.edu if (PC_PAL(req->vaddr)) { 2776141Sgblack@eecs.umich.edu // strip off PAL PC marker (lsb is 1) 2786141Sgblack@eecs.umich.edu req->paddr = (req->vaddr & ~3) & PA_IMPL_MASK; 2796141Sgblack@eecs.umich.edu hits++; 2806141Sgblack@eecs.umich.edu return No_Fault; 2816141Sgblack@eecs.umich.edu } 2826141Sgblack@eecs.umich.edu 2836141Sgblack@eecs.umich.edu if (req->flags & PHYSICAL) { 2846141Sgblack@eecs.umich.edu req->paddr = req->vaddr; 2856141Sgblack@eecs.umich.edu } else { 2866141Sgblack@eecs.umich.edu // verify that this is a good virtual address 2876141Sgblack@eecs.umich.edu if (!validVirtualAddress(req->vaddr)) { 2886141Sgblack@eecs.umich.edu fault(req->vaddr, req->xc); 2896141Sgblack@eecs.umich.edu acv++; 2906141Sgblack@eecs.umich.edu return ITB_Acv_Fault; 2916141Sgblack@eecs.umich.edu } 2926141Sgblack@eecs.umich.edu 2936141Sgblack@eecs.umich.edu // Check for "superpage" mapping: when SP<1> is set, and 2946141Sgblack@eecs.umich.edu // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. 2956141Sgblack@eecs.umich.edu if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && 2966141Sgblack@eecs.umich.edu VA_SPACE(req->vaddr) == 2) { 2976141Sgblack@eecs.umich.edu 2986141Sgblack@eecs.umich.edu // only valid in kernel mode 2996141Sgblack@eecs.umich.edu if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) { 3006141Sgblack@eecs.umich.edu fault(req->vaddr, req->xc); 3016141Sgblack@eecs.umich.edu acv++; 3026141Sgblack@eecs.umich.edu return ITB_Acv_Fault; 3036141Sgblack@eecs.umich.edu } 3046141Sgblack@eecs.umich.edu 3056141Sgblack@eecs.umich.edu req->paddr = req->vaddr & PA_IMPL_MASK; 3066141Sgblack@eecs.umich.edu } else { 3076141Sgblack@eecs.umich.edu // not a physical address: need to look up pte 3086141Sgblack@eecs.umich.edu AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), 3096141Sgblack@eecs.umich.edu DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 3106141Sgblack@eecs.umich.edu 3116141Sgblack@eecs.umich.edu if (!pte) { 3126141Sgblack@eecs.umich.edu fault(req->vaddr, req->xc); 3136141Sgblack@eecs.umich.edu misses++; 3146141Sgblack@eecs.umich.edu return ITB_Fault_Fault; 3156141Sgblack@eecs.umich.edu } 3166141Sgblack@eecs.umich.edu 3176141Sgblack@eecs.umich.edu req->paddr = PA_PFN2PA(pte->ppn) + VA_POFS(req->vaddr & ~3); 3186141Sgblack@eecs.umich.edu 3196141Sgblack@eecs.umich.edu // check permissions for this access 3206141Sgblack@eecs.umich.edu if (!(pte->xre & (1 << ICM_CM(ipr[AlphaISA::IPR_ICM])))) { 3216141Sgblack@eecs.umich.edu // instruction access fault 3226141Sgblack@eecs.umich.edu fault(req->vaddr, req->xc); 3236141Sgblack@eecs.umich.edu acv++; 3246141Sgblack@eecs.umich.edu return ITB_Acv_Fault; 3256141Sgblack@eecs.umich.edu } 3266141Sgblack@eecs.umich.edu 3276141Sgblack@eecs.umich.edu hits++; 3286141Sgblack@eecs.umich.edu } 3296141Sgblack@eecs.umich.edu } 3306141Sgblack@eecs.umich.edu 3316141Sgblack@eecs.umich.edu // check that the physical address is ok (catch bad physical addresses) 3326141Sgblack@eecs.umich.edu if (req->paddr & ~PA_IMPL_MASK) 3336141Sgblack@eecs.umich.edu return Machine_Check_Fault; 3346141Sgblack@eecs.umich.edu 3356141Sgblack@eecs.umich.edu checkCacheability(req); 3366141Sgblack@eecs.umich.edu 3376141Sgblack@eecs.umich.edu return No_Fault; 3386141Sgblack@eecs.umich.edu} 3396141Sgblack@eecs.umich.edu 3406141Sgblack@eecs.umich.edu/////////////////////////////////////////////////////////////////////// 3416141Sgblack@eecs.umich.edu// 3426141Sgblack@eecs.umich.edu// Alpha DTB 3436141Sgblack@eecs.umich.edu// 3446141Sgblack@eecs.umich.eduAlphaDTB::AlphaDTB(const std::string &name, int size) 3456141Sgblack@eecs.umich.edu : AlphaTLB(name, size) 3466141Sgblack@eecs.umich.edu{} 3476141Sgblack@eecs.umich.edu 3486141Sgblack@eecs.umich.eduvoid 3496141Sgblack@eecs.umich.eduAlphaDTB::regStats() 3506141Sgblack@eecs.umich.edu{ 3516141Sgblack@eecs.umich.edu read_hits 3526141Sgblack@eecs.umich.edu .name(name() + ".read_hits") 3536141Sgblack@eecs.umich.edu .desc("DTB read hits") 3546141Sgblack@eecs.umich.edu ; 3556141Sgblack@eecs.umich.edu 3566141Sgblack@eecs.umich.edu read_misses 3576141Sgblack@eecs.umich.edu .name(name() + ".read_misses") 3586141Sgblack@eecs.umich.edu .desc("DTB read misses") 3596141Sgblack@eecs.umich.edu ; 3606141Sgblack@eecs.umich.edu 3616141Sgblack@eecs.umich.edu read_acv 3626141Sgblack@eecs.umich.edu .name(name() + ".read_acv") 3636141Sgblack@eecs.umich.edu .desc("DTB read access violations") 3646141Sgblack@eecs.umich.edu ; 3656141Sgblack@eecs.umich.edu 3666141Sgblack@eecs.umich.edu read_accesses 3676141Sgblack@eecs.umich.edu .name(name() + ".read_accesses") 3686141Sgblack@eecs.umich.edu .desc("DTB read accesses") 3696141Sgblack@eecs.umich.edu ; 3706141Sgblack@eecs.umich.edu 3716141Sgblack@eecs.umich.edu write_hits 3726141Sgblack@eecs.umich.edu .name(name() + ".write_hits") 3736141Sgblack@eecs.umich.edu .desc("DTB write hits") 3746141Sgblack@eecs.umich.edu ; 3756141Sgblack@eecs.umich.edu 3766141Sgblack@eecs.umich.edu write_misses 3776141Sgblack@eecs.umich.edu .name(name() + ".write_misses") 3786141Sgblack@eecs.umich.edu .desc("DTB write misses") 3796141Sgblack@eecs.umich.edu ; 3806141Sgblack@eecs.umich.edu 3816141Sgblack@eecs.umich.edu write_acv 3826141Sgblack@eecs.umich.edu .name(name() + ".write_acv") 3836141Sgblack@eecs.umich.edu .desc("DTB write access violations") 3846141Sgblack@eecs.umich.edu ; 3856141Sgblack@eecs.umich.edu 3866141Sgblack@eecs.umich.edu write_accesses 3876141Sgblack@eecs.umich.edu .name(name() + ".write_accesses") 3886141Sgblack@eecs.umich.edu .desc("DTB write accesses") 3896141Sgblack@eecs.umich.edu ; 3906141Sgblack@eecs.umich.edu 3916141Sgblack@eecs.umich.edu hits 3926141Sgblack@eecs.umich.edu .name(name() + ".hits") 3936141Sgblack@eecs.umich.edu .desc("DTB hits") 3946141Sgblack@eecs.umich.edu ; 3956141Sgblack@eecs.umich.edu 3966141Sgblack@eecs.umich.edu misses 3976141Sgblack@eecs.umich.edu .name(name() + ".misses") 3986141Sgblack@eecs.umich.edu .desc("DTB misses") 3996141Sgblack@eecs.umich.edu ; 4006141Sgblack@eecs.umich.edu 4016141Sgblack@eecs.umich.edu acv 4026141Sgblack@eecs.umich.edu .name(name() + ".acv") 4036141Sgblack@eecs.umich.edu .desc("DTB access violations") 4046141Sgblack@eecs.umich.edu ; 4056141Sgblack@eecs.umich.edu 4066141Sgblack@eecs.umich.edu accesses 4076141Sgblack@eecs.umich.edu .name(name() + ".accesses") 4086141Sgblack@eecs.umich.edu .desc("DTB accesses") 4096141Sgblack@eecs.umich.edu ; 4106141Sgblack@eecs.umich.edu 4116141Sgblack@eecs.umich.edu hits = read_hits + write_hits; 4126141Sgblack@eecs.umich.edu misses = read_misses + write_misses; 4136141Sgblack@eecs.umich.edu acv = read_acv + write_acv; 4146141Sgblack@eecs.umich.edu accesses = read_accesses + write_accesses; 4156141Sgblack@eecs.umich.edu} 4166141Sgblack@eecs.umich.edu 4176141Sgblack@eecs.umich.eduvoid 4186141Sgblack@eecs.umich.eduAlphaDTB::fault(Addr vaddr, uint64_t flags, ExecContext *xc) const 4196141Sgblack@eecs.umich.edu{ 4206141Sgblack@eecs.umich.edu uint64_t *ipr = xc->regs.ipr; 4216141Sgblack@eecs.umich.edu 4226141Sgblack@eecs.umich.edu // set fault address and flags 4236141Sgblack@eecs.umich.edu if (!xc->misspeculating() && !xc->regs.intrlock) { 4246141Sgblack@eecs.umich.edu // set VA register with faulting address 4256141Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_VA] = vaddr; 4266141Sgblack@eecs.umich.edu 4276141Sgblack@eecs.umich.edu // set MM_STAT register flags 4286141Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_MM_STAT] = (((xc->regs.opcode & 0x3f) << 11) 4296141Sgblack@eecs.umich.edu | ((xc->regs.ra & 0x1f) << 6) 4306141Sgblack@eecs.umich.edu | (flags & 0x3f)); 4316141Sgblack@eecs.umich.edu 4326141Sgblack@eecs.umich.edu // set VA_FORM register with faulting formatted address 4336141Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_VA_FORM] = 4346141Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_MVPTBR] | (VA_VPN(vaddr) << 3); 4356141Sgblack@eecs.umich.edu 4366141Sgblack@eecs.umich.edu // lock these registers until the VA register is read 4376141Sgblack@eecs.umich.edu xc->regs.intrlock = true; 4386141Sgblack@eecs.umich.edu } 4396141Sgblack@eecs.umich.edu} 4406141Sgblack@eecs.umich.edu 4416141Sgblack@eecs.umich.eduFault 4426141Sgblack@eecs.umich.eduAlphaDTB::translate(MemReqPtr &req, bool write) const 4436141Sgblack@eecs.umich.edu{ 4446141Sgblack@eecs.umich.edu RegFile *regs = &req->xc->regs; 4456141Sgblack@eecs.umich.edu Addr pc = regs->pc; 4466141Sgblack@eecs.umich.edu InternalProcReg *ipr = regs->ipr; 4476141Sgblack@eecs.umich.edu 4486141Sgblack@eecs.umich.edu AlphaISA::mode_type mode = 4496141Sgblack@eecs.umich.edu (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]); 4506141Sgblack@eecs.umich.edu 4516141Sgblack@eecs.umich.edu if (PC_PAL(pc)) { 4526141Sgblack@eecs.umich.edu mode = (req->flags & ALTMODE) ? 4536141Sgblack@eecs.umich.edu (AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE]) 4546141Sgblack@eecs.umich.edu : AlphaISA::mode_kernel; 4556141Sgblack@eecs.umich.edu } 4566141Sgblack@eecs.umich.edu 4576141Sgblack@eecs.umich.edu if (req->flags & PHYSICAL) { 4586141Sgblack@eecs.umich.edu req->paddr = req->vaddr; 4596141Sgblack@eecs.umich.edu } else { 4606141Sgblack@eecs.umich.edu // verify that this is a good virtual address 4616141Sgblack@eecs.umich.edu if (!validVirtualAddress(req->vaddr)) { 4626141Sgblack@eecs.umich.edu fault(req->vaddr, 4636141Sgblack@eecs.umich.edu ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | 4646141Sgblack@eecs.umich.edu MM_STAT_ACV_MASK), 4656141Sgblack@eecs.umich.edu req->xc); 4666141Sgblack@eecs.umich.edu 4676141Sgblack@eecs.umich.edu if (write) { write_acv++; } else { read_acv++; } 4686141Sgblack@eecs.umich.edu return DTB_Fault_Fault; 4696141Sgblack@eecs.umich.edu } 4706141Sgblack@eecs.umich.edu 4716141Sgblack@eecs.umich.edu // Check for "superpage" mapping: when SP<1> is set, and 4726141Sgblack@eecs.umich.edu // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. 4736141Sgblack@eecs.umich.edu if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && 4746141Sgblack@eecs.umich.edu VA_SPACE(req->vaddr) == 2) { 4756141Sgblack@eecs.umich.edu 4766141Sgblack@eecs.umich.edu // only valid in kernel mode 4776141Sgblack@eecs.umich.edu if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != 4786141Sgblack@eecs.umich.edu AlphaISA::mode_kernel) { 4796141Sgblack@eecs.umich.edu fault(req->vaddr, 4806141Sgblack@eecs.umich.edu ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK), 4816141Sgblack@eecs.umich.edu req->xc); 4826141Sgblack@eecs.umich.edu if (write) { write_acv++; } else { read_acv++; } 4836141Sgblack@eecs.umich.edu return DTB_Acv_Fault; 4846141Sgblack@eecs.umich.edu } 4856141Sgblack@eecs.umich.edu 4866141Sgblack@eecs.umich.edu req->paddr = req->vaddr & PA_IMPL_MASK; 4876141Sgblack@eecs.umich.edu } else { 4886141Sgblack@eecs.umich.edu if (write) 4896141Sgblack@eecs.umich.edu write_accesses++; 4906141Sgblack@eecs.umich.edu else 4916141Sgblack@eecs.umich.edu read_accesses++; 4926141Sgblack@eecs.umich.edu 4936141Sgblack@eecs.umich.edu // not a physical address: need to look up pte 4946141Sgblack@eecs.umich.edu AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), 4956141Sgblack@eecs.umich.edu DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 4966141Sgblack@eecs.umich.edu 4976141Sgblack@eecs.umich.edu if (!pte) { 4986141Sgblack@eecs.umich.edu // page fault 4996141Sgblack@eecs.umich.edu fault(req->vaddr, 5006141Sgblack@eecs.umich.edu ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK), 5016141Sgblack@eecs.umich.edu req->xc); 5026141Sgblack@eecs.umich.edu if (write) { write_misses++; } else { read_misses++; } 5036141Sgblack@eecs.umich.edu return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault; 5046141Sgblack@eecs.umich.edu } 5056141Sgblack@eecs.umich.edu 5066141Sgblack@eecs.umich.edu req->paddr = PA_PFN2PA(pte->ppn) | VA_POFS(req->vaddr); 5076141Sgblack@eecs.umich.edu 5086141Sgblack@eecs.umich.edu if (write) { 5096141Sgblack@eecs.umich.edu if (!(pte->xwe & MODE2MASK(mode))) { 5106141Sgblack@eecs.umich.edu // declare the instruction access fault 5116141Sgblack@eecs.umich.edu fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_ACV_MASK | 5126141Sgblack@eecs.umich.edu (pte->fonw ? MM_STAT_FONW_MASK : 0), 5136141Sgblack@eecs.umich.edu req->xc); 5146141Sgblack@eecs.umich.edu write_acv++; 5156141Sgblack@eecs.umich.edu return DTB_Fault_Fault; 5166141Sgblack@eecs.umich.edu } 5176141Sgblack@eecs.umich.edu if (pte->fonw) { 5186141Sgblack@eecs.umich.edu fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_FONW_MASK, 5196141Sgblack@eecs.umich.edu req->xc); 5206141Sgblack@eecs.umich.edu write_acv++; 5216141Sgblack@eecs.umich.edu return DTB_Fault_Fault; 5226141Sgblack@eecs.umich.edu } 5236141Sgblack@eecs.umich.edu } else { 5246141Sgblack@eecs.umich.edu if (!(pte->xre & MODE2MASK(mode))) { 5256141Sgblack@eecs.umich.edu fault(req->vaddr, 5266141Sgblack@eecs.umich.edu MM_STAT_ACV_MASK | 5276141Sgblack@eecs.umich.edu (pte->fonr ? MM_STAT_FONR_MASK : 0), 5286141Sgblack@eecs.umich.edu req->xc); 5296141Sgblack@eecs.umich.edu read_acv++; 5306141Sgblack@eecs.umich.edu return DTB_Acv_Fault; 5316141Sgblack@eecs.umich.edu } 5326141Sgblack@eecs.umich.edu if (pte->fonr) { 5336141Sgblack@eecs.umich.edu fault(req->vaddr, MM_STAT_FONR_MASK, req->xc); 5346141Sgblack@eecs.umich.edu read_acv++; 5356141Sgblack@eecs.umich.edu return DTB_Fault_Fault; 5366141Sgblack@eecs.umich.edu } 5376141Sgblack@eecs.umich.edu } 5386141Sgblack@eecs.umich.edu } 5396141Sgblack@eecs.umich.edu 5406141Sgblack@eecs.umich.edu if (write) 5416141Sgblack@eecs.umich.edu write_hits++; 5426141Sgblack@eecs.umich.edu else 5436141Sgblack@eecs.umich.edu read_hits++; 5446141Sgblack@eecs.umich.edu } 5456141Sgblack@eecs.umich.edu 5466141Sgblack@eecs.umich.edu // check that the physical address is ok (catch bad physical addresses) 5476141Sgblack@eecs.umich.edu if (req->paddr & ~PA_IMPL_MASK) 5486141Sgblack@eecs.umich.edu return Machine_Check_Fault; 5496023Snate@binkert.org 5506023Snate@binkert.org checkCacheability(req); 5515086Sgblack@eecs.umich.edu 5526141Sgblack@eecs.umich.edu return No_Fault; 5536141Sgblack@eecs.umich.edu} 5546141Sgblack@eecs.umich.edu 5556141Sgblack@eecs.umich.eduAlphaISA::PTE & 5566141Sgblack@eecs.umich.eduAlphaTLB::index(bool advance) 5576141Sgblack@eecs.umich.edu{ 5586141Sgblack@eecs.umich.edu AlphaISA::PTE *pte = &table[nlu]; 5596141Sgblack@eecs.umich.edu 5606141Sgblack@eecs.umich.edu if (advance) 5616141Sgblack@eecs.umich.edu nextnlu(); 5625895Sgblack@eecs.umich.edu 5635124Sgblack@eecs.umich.edu return *pte; 5645140Sgblack@eecs.umich.edu} 5655140Sgblack@eecs.umich.edu 5666141Sgblack@eecs.umich.eduDEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", AlphaTLB) 5675140Sgblack@eecs.umich.edu 5685140Sgblack@eecs.umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaITB) 5696141Sgblack@eecs.umich.edu 5705237Sgblack@eecs.umich.edu Param<int> size; 5715140Sgblack@eecs.umich.edu 5726141Sgblack@eecs.umich.eduEND_DECLARE_SIM_OBJECT_PARAMS(AlphaITB) 5735237Sgblack@eecs.umich.edu 5745431Sgblack@eecs.umich.eduBEGIN_INIT_SIM_OBJECT_PARAMS(AlphaITB) 5756059Sgblack@eecs.umich.edu 5766141Sgblack@eecs.umich.edu INIT_PARAM_DFLT(size, "TLB size", 48) 5776059Sgblack@eecs.umich.edu 5785431Sgblack@eecs.umich.eduEND_INIT_SIM_OBJECT_PARAMS(AlphaITB) 5795433Sgblack@eecs.umich.edu 5805965Sgblack@eecs.umich.edu 5815433Sgblack@eecs.umich.eduCREATE_SIM_OBJECT(AlphaITB) 5826099Sgblack@eecs.umich.edu{ 5835433Sgblack@eecs.umich.edu return new AlphaITB(getInstanceName(), size); 5846023Snate@binkert.org} 5855433Sgblack@eecs.umich.edu 5865433Sgblack@eecs.umich.eduREGISTER_SIM_OBJECT("AlphaITB", AlphaITB) 5875965Sgblack@eecs.umich.edu 5885433Sgblack@eecs.umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB) 5895140Sgblack@eecs.umich.edu 5905140Sgblack@eecs.umich.edu Param<int> size; 5915965Sgblack@eecs.umich.edu 5925965Sgblack@eecs.umich.eduEND_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB) 5935965Sgblack@eecs.umich.edu 5945965Sgblack@eecs.umich.eduBEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDTB) 5956141Sgblack@eecs.umich.edu 5965980Snate@binkert.org INIT_PARAM_DFLT(size, "TLB size", 64) 5975980Snate@binkert.org 5985965Sgblack@eecs.umich.eduEND_INIT_SIM_OBJECT_PARAMS(AlphaDTB) 5995965Sgblack@eecs.umich.edu 6005965Sgblack@eecs.umich.edu 6015433Sgblack@eecs.umich.eduCREATE_SIM_OBJECT(AlphaDTB) 6025237Sgblack@eecs.umich.edu{ 6035965Sgblack@eecs.umich.edu return new AlphaDTB(getInstanceName(), size); 6045965Sgblack@eecs.umich.edu} 6055965Sgblack@eecs.umich.edu 6065140Sgblack@eecs.umich.eduREGISTER_SIM_OBJECT("AlphaDTB", AlphaDTB) 6075965Sgblack@eecs.umich.edu 6085965Sgblack@eecs.umich.edu