tlb.cc revision 828
15409Sgblack@eecs.umich.edu/* 24519Sgblack@eecs.umich.edu * Copyright (c) 2003 The Regents of The University of Michigan 34519Sgblack@eecs.umich.edu * All rights reserved. 44519Sgblack@eecs.umich.edu * 54519Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 64519Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 74519Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 84519Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 94519Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 104519Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 114519Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 124519Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 134519Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 144519Sgblack@eecs.umich.edu * this software without specific prior written permission. 154519Sgblack@eecs.umich.edu * 164519Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 174519Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 184519Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194519Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 204519Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 214519Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 224519Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234519Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244519Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254519Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 264519Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274519Sgblack@eecs.umich.edu */ 284519Sgblack@eecs.umich.edu 294519Sgblack@eecs.umich.edu#include <sstream> 304519Sgblack@eecs.umich.edu#include <string> 314519Sgblack@eecs.umich.edu#include <vector> 324519Sgblack@eecs.umich.edu 334519Sgblack@eecs.umich.edu#include "base/inifile.hh" 344519Sgblack@eecs.umich.edu#include "base/str.hh" 354519Sgblack@eecs.umich.edu#include "base/trace.hh" 364519Sgblack@eecs.umich.edu#include "cpu/exec_context.hh" 374519Sgblack@eecs.umich.edu#include "sim/builder.hh" 384519Sgblack@eecs.umich.edu#include "targetarch/alpha_memory.hh" 394519Sgblack@eecs.umich.edu#include "targetarch/ev5.hh" 404519Sgblack@eecs.umich.edu 414519Sgblack@eecs.umich.eduusing namespace std; 424519Sgblack@eecs.umich.edu 434519Sgblack@eecs.umich.edu/////////////////////////////////////////////////////////////////////// 444519Sgblack@eecs.umich.edu// 454519Sgblack@eecs.umich.edu// Alpha TLB 464519Sgblack@eecs.umich.edu// 474519Sgblack@eecs.umich.edu 484519Sgblack@eecs.umich.edu#ifdef DEBUG 494519Sgblack@eecs.umich.edu bool uncacheBit39 = false; 504519Sgblack@eecs.umich.edu bool uncacheBit40 = false; 514519Sgblack@eecs.umich.edu#endif 524519Sgblack@eecs.umich.edu 534519Sgblack@eecs.umich.eduAlphaTlb::AlphaTlb(const string &name, int s) 544519Sgblack@eecs.umich.edu : SimObject(name), size(s), nlu(0) 554519Sgblack@eecs.umich.edu{ 564519Sgblack@eecs.umich.edu table = new AlphaISA::PTE[size]; 574519Sgblack@eecs.umich.edu memset(table, 0, sizeof(AlphaISA::PTE[size])); 584519Sgblack@eecs.umich.edu} 594519Sgblack@eecs.umich.edu 604519Sgblack@eecs.umich.eduAlphaTlb::~AlphaTlb() 614519Sgblack@eecs.umich.edu{ 624519Sgblack@eecs.umich.edu if (table) 634519Sgblack@eecs.umich.edu delete [] table; 644519Sgblack@eecs.umich.edu} 654519Sgblack@eecs.umich.edu 664519Sgblack@eecs.umich.edu// look up an entry in the TLB 674519Sgblack@eecs.umich.eduAlphaISA::PTE * 684809Sgblack@eecs.umich.eduAlphaTlb::lookup(Addr vpn, uint8_t asn) const 694519Sgblack@eecs.umich.edu{ 704519Sgblack@eecs.umich.edu DPRINTF(TLB, "lookup %#x\n", vpn); 714688Sgblack@eecs.umich.edu 724688Sgblack@eecs.umich.edu PageTable::const_iterator i = lookupTable.find(vpn); 734688Sgblack@eecs.umich.edu if (i == lookupTable.end()) 744688Sgblack@eecs.umich.edu return NULL; 754688Sgblack@eecs.umich.edu 764688Sgblack@eecs.umich.edu while (i->first == vpn) { 774708Sgblack@eecs.umich.edu int index = i->second; 784708Sgblack@eecs.umich.edu AlphaISA::PTE *pte = &table[index]; 794708Sgblack@eecs.umich.edu assert(pte->valid); 804708Sgblack@eecs.umich.edu if (vpn == pte->tag && (pte->asma || pte->asn == asn)) 814519Sgblack@eecs.umich.edu return pte; 824519Sgblack@eecs.umich.edu 834519Sgblack@eecs.umich.edu ++i; 844519Sgblack@eecs.umich.edu } 854519Sgblack@eecs.umich.edu 864519Sgblack@eecs.umich.edu // not found... 874519Sgblack@eecs.umich.edu return NULL; 884519Sgblack@eecs.umich.edu} 894519Sgblack@eecs.umich.edu 904519Sgblack@eecs.umich.edu 914519Sgblack@eecs.umich.eduvoid 924951Sgblack@eecs.umich.eduAlphaTlb::checkCacheability(MemReqPtr &req) 934519Sgblack@eecs.umich.edu{ 944519Sgblack@eecs.umich.edu // in Alpha, cacheability is controlled by upper-level bits of the 954519Sgblack@eecs.umich.edu // physical address 964519Sgblack@eecs.umich.edu 974519Sgblack@eecs.umich.edu /* 984519Sgblack@eecs.umich.edu * We support having the uncacheable bit in either bit 39 or bit 40. 994688Sgblack@eecs.umich.edu * The Turbolaser platform (and EV5) support having the bit in 39, but 1004688Sgblack@eecs.umich.edu * Tsunami (which Linux assumes uses an EV6) generates accesses with 1014688Sgblack@eecs.umich.edu * the bit in 40. So we must check for both, but we have debug flags 1024688Sgblack@eecs.umich.edu * to catch a weird case where both are used, which shouldn't happen. 1034688Sgblack@eecs.umich.edu */ 1044688Sgblack@eecs.umich.edu 1054708Sgblack@eecs.umich.edu if (req->paddr & PA_UNCACHED_BIT_40 || 1064708Sgblack@eecs.umich.edu req->paddr & PA_UNCACHED_BIT_39) { 1074708Sgblack@eecs.umich.edu 1084708Sgblack@eecs.umich.edu#ifdef DEBUG 1094519Sgblack@eecs.umich.edu if (req->paddr & PA_UNCACHED_BIT_40) { 1104519Sgblack@eecs.umich.edu if(uncacheBit39) 1114519Sgblack@eecs.umich.edu panic("Bit 40 access follows bit 39 access, PA=%x\n", 1124519Sgblack@eecs.umich.edu req->paddr); 1134519Sgblack@eecs.umich.edu 1144519Sgblack@eecs.umich.edu uncacheBit40 = true; 1154519Sgblack@eecs.umich.edu } else if (req->paddr & PA_UNCACHED_BIT_39) { 1164519Sgblack@eecs.umich.edu if(uncacheBit40) 1174519Sgblack@eecs.umich.edu panic("Bit 39 acceess follows bit 40 access, PA=%x\n", 1184519Sgblack@eecs.umich.edu req->paddr); 1194519Sgblack@eecs.umich.edu 1204519Sgblack@eecs.umich.edu uncacheBit39 = true; 1214519Sgblack@eecs.umich.edu } 1224519Sgblack@eecs.umich.edu#endif 1234519Sgblack@eecs.umich.edu 1244519Sgblack@eecs.umich.edu // IPR memory space not implemented 1254519Sgblack@eecs.umich.edu if (PA_IPR_SPACE(req->paddr)) 1264519Sgblack@eecs.umich.edu if (!req->xc->misspeculating()) 1274519Sgblack@eecs.umich.edu panic("IPR memory space not implemented! PA=%x\n", 1284519Sgblack@eecs.umich.edu req->paddr); 1294519Sgblack@eecs.umich.edu 1304712Sgblack@eecs.umich.edu // mark request as uncacheable 1314519Sgblack@eecs.umich.edu req->flags |= UNCACHEABLE; 1324519Sgblack@eecs.umich.edu } 1334519Sgblack@eecs.umich.edu} 1344519Sgblack@eecs.umich.edu 1354712Sgblack@eecs.umich.edu 1364519Sgblack@eecs.umich.edu// insert a new TLB entry 1374519Sgblack@eecs.umich.eduvoid 1384519Sgblack@eecs.umich.eduAlphaTlb::insert(Addr vaddr, AlphaISA::PTE &pte) 1394519Sgblack@eecs.umich.edu{ 1404519Sgblack@eecs.umich.edu if (table[nlu].valid) { 1414519Sgblack@eecs.umich.edu Addr oldvpn = table[nlu].tag; 1424519Sgblack@eecs.umich.edu PageTable::iterator i = lookupTable.find(oldvpn); 1434951Sgblack@eecs.umich.edu 1444519Sgblack@eecs.umich.edu if (i == lookupTable.end()) 1454519Sgblack@eecs.umich.edu panic("TLB entry not found in lookupTable"); 1464519Sgblack@eecs.umich.edu 1474519Sgblack@eecs.umich.edu int index; 1484519Sgblack@eecs.umich.edu while ((index = i->second) != nlu) { 1494951Sgblack@eecs.umich.edu if (table[index].tag != oldvpn) 1504519Sgblack@eecs.umich.edu panic("TLB entry not found in lookupTable"); 1514519Sgblack@eecs.umich.edu 1524951Sgblack@eecs.umich.edu ++i; 1534712Sgblack@eecs.umich.edu } 1544519Sgblack@eecs.umich.edu 1554951Sgblack@eecs.umich.edu DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); 1564519Sgblack@eecs.umich.edu 1574951Sgblack@eecs.umich.edu lookupTable.erase(i); 1584712Sgblack@eecs.umich.edu } 1594519Sgblack@eecs.umich.edu 1604519Sgblack@eecs.umich.edu Addr vpn = VA_VPN(vaddr); 1614519Sgblack@eecs.umich.edu DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vpn, pte.ppn); 1624519Sgblack@eecs.umich.edu 1634519Sgblack@eecs.umich.edu table[nlu] = pte; 1644519Sgblack@eecs.umich.edu table[nlu].tag = vpn; 1654519Sgblack@eecs.umich.edu table[nlu].valid = true; 1664519Sgblack@eecs.umich.edu 1674519Sgblack@eecs.umich.edu lookupTable.insert(make_pair(vpn, nlu)); 1684519Sgblack@eecs.umich.edu nextnlu(); 1694519Sgblack@eecs.umich.edu} 1704519Sgblack@eecs.umich.edu 1714519Sgblack@eecs.umich.eduvoid 1724519Sgblack@eecs.umich.eduAlphaTlb::flushAll() 1734519Sgblack@eecs.umich.edu{ 1744712Sgblack@eecs.umich.edu memset(table, 0, sizeof(AlphaISA::PTE[size])); 1754519Sgblack@eecs.umich.edu lookupTable.clear(); 1764581Sgblack@eecs.umich.edu nlu = 0; 1774688Sgblack@eecs.umich.edu} 1784581Sgblack@eecs.umich.edu 1794519Sgblack@eecs.umich.eduvoid 1804519Sgblack@eecs.umich.eduAlphaTlb::flushProcesses() 1814519Sgblack@eecs.umich.edu{ 1824519Sgblack@eecs.umich.edu PageTable::iterator i = lookupTable.begin(); 1834519Sgblack@eecs.umich.edu PageTable::iterator end = lookupTable.end(); 1844519Sgblack@eecs.umich.edu while (i != end) { 1854519Sgblack@eecs.umich.edu int index = i->second; 1864519Sgblack@eecs.umich.edu AlphaISA::PTE *pte = &table[index]; 1874712Sgblack@eecs.umich.edu assert(pte->valid); 1884519Sgblack@eecs.umich.edu 1894581Sgblack@eecs.umich.edu if (!pte->asma) { 1904688Sgblack@eecs.umich.edu DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); 1914581Sgblack@eecs.umich.edu pte->valid = false; 1924519Sgblack@eecs.umich.edu lookupTable.erase(i); 1934519Sgblack@eecs.umich.edu } 1944519Sgblack@eecs.umich.edu 1954519Sgblack@eecs.umich.edu ++i; 1964519Sgblack@eecs.umich.edu } 1974519Sgblack@eecs.umich.edu} 1984519Sgblack@eecs.umich.edu 1994951Sgblack@eecs.umich.eduvoid 2004519Sgblack@eecs.umich.eduAlphaTlb::flushAddr(Addr vaddr, uint8_t asn) 2014519Sgblack@eecs.umich.edu{ 2024519Sgblack@eecs.umich.edu Addr vpn = VA_VPN(vaddr); 2034519Sgblack@eecs.umich.edu 2044951Sgblack@eecs.umich.edu PageTable::iterator i = lookupTable.find(vpn); 2054519Sgblack@eecs.umich.edu if (i == lookupTable.end()) 2064951Sgblack@eecs.umich.edu return; 2074712Sgblack@eecs.umich.edu 2084519Sgblack@eecs.umich.edu while (i->first == vpn) { 2094581Sgblack@eecs.umich.edu int index = i->second; 2104688Sgblack@eecs.umich.edu AlphaISA::PTE *pte = &table[index]; 2114581Sgblack@eecs.umich.edu assert(pte->valid); 2124519Sgblack@eecs.umich.edu 2134519Sgblack@eecs.umich.edu if (vpn == pte->tag && (pte->asma || pte->asn == asn)) { 2144519Sgblack@eecs.umich.edu DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vpn, pte->ppn); 2154519Sgblack@eecs.umich.edu 2164951Sgblack@eecs.umich.edu // invalidate this entry 2174519Sgblack@eecs.umich.edu pte->valid = false; 2184519Sgblack@eecs.umich.edu 2194951Sgblack@eecs.umich.edu lookupTable.erase(i); 2204712Sgblack@eecs.umich.edu } 2214519Sgblack@eecs.umich.edu 2224581Sgblack@eecs.umich.edu ++i; 2234688Sgblack@eecs.umich.edu } 2244581Sgblack@eecs.umich.edu} 2254519Sgblack@eecs.umich.edu 2264519Sgblack@eecs.umich.edu 2274519Sgblack@eecs.umich.eduvoid 2284519Sgblack@eecs.umich.eduAlphaTlb::serialize(ostream &os) 2294519Sgblack@eecs.umich.edu{ 2305075Sgblack@eecs.umich.edu SERIALIZE_SCALAR(size); 2315075Sgblack@eecs.umich.edu SERIALIZE_SCALAR(nlu); 2325075Sgblack@eecs.umich.edu 2335075Sgblack@eecs.umich.edu for (int i = 0; i < size; i++) { 2345428Sgblack@eecs.umich.edu nameOut(os, csprintf("%s.PTE%d", name(), i)); 2355428Sgblack@eecs.umich.edu table[i].serialize(os); 2365674Sgblack@eecs.umich.edu } 2375899Sgblack@eecs.umich.edu} 2385936Sgblack@eecs.umich.edu 2395428Sgblack@eecs.umich.eduvoid 2405678Sgblack@eecs.umich.eduAlphaTlb::unserialize(Checkpoint *cp, const string §ion) 2415678Sgblack@eecs.umich.edu{ 2425678Sgblack@eecs.umich.edu UNSERIALIZE_SCALAR(size); 2435678Sgblack@eecs.umich.edu UNSERIALIZE_SCALAR(nlu); 2445678Sgblack@eecs.umich.edu 2455678Sgblack@eecs.umich.edu for (int i = 0; i < size; i++) { 2465678Sgblack@eecs.umich.edu table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); 2475678Sgblack@eecs.umich.edu if (table[i].valid) { 2485678Sgblack@eecs.umich.edu lookupTable.insert(make_pair(table[i].tag, i)); 2495075Sgblack@eecs.umich.edu } 2505075Sgblack@eecs.umich.edu } 2515075Sgblack@eecs.umich.edu} 2525075Sgblack@eecs.umich.edu 2535075Sgblack@eecs.umich.edu 2545075Sgblack@eecs.umich.edu/////////////////////////////////////////////////////////////////////// 2555075Sgblack@eecs.umich.edu// 2565075Sgblack@eecs.umich.edu// Alpha ITB 2575075Sgblack@eecs.umich.edu// 2585075Sgblack@eecs.umich.eduAlphaItb::AlphaItb(const std::string &name, int size) 2595075Sgblack@eecs.umich.edu : AlphaTlb(name, size) 2605075Sgblack@eecs.umich.edu{} 2615075Sgblack@eecs.umich.edu 2625075Sgblack@eecs.umich.edu 2635075Sgblack@eecs.umich.eduvoid 2645075Sgblack@eecs.umich.eduAlphaItb::regStats() 2655075Sgblack@eecs.umich.edu{ 2665075Sgblack@eecs.umich.edu hits 2675075Sgblack@eecs.umich.edu .name(name() + ".hits") 2685075Sgblack@eecs.umich.edu .desc("ITB hits"); 2695075Sgblack@eecs.umich.edu misses 2705075Sgblack@eecs.umich.edu .name(name() + ".misses") 2715075Sgblack@eecs.umich.edu .desc("ITB misses"); 2725075Sgblack@eecs.umich.edu acv 2735075Sgblack@eecs.umich.edu .name(name() + ".acv") 2745075Sgblack@eecs.umich.edu .desc("ITB acv"); 2755075Sgblack@eecs.umich.edu accesses 2765075Sgblack@eecs.umich.edu .name(name() + ".accesses") 2775075Sgblack@eecs.umich.edu .desc("ITB accesses"); 2785075Sgblack@eecs.umich.edu 2795075Sgblack@eecs.umich.edu accesses = hits + misses; 2805075Sgblack@eecs.umich.edu} 2815075Sgblack@eecs.umich.edu 2825075Sgblack@eecs.umich.eduvoid 2835075Sgblack@eecs.umich.eduAlphaItb::fault(Addr pc, ExecContext *xc) const 2844519Sgblack@eecs.umich.edu{ 2855040Sgblack@eecs.umich.edu uint64_t *ipr = xc->regs.ipr; 2865040Sgblack@eecs.umich.edu 2875040Sgblack@eecs.umich.edu if (!xc->misspeculating()) { 2885040Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_ITB_TAG] = pc; 2895040Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_IFAULT_VA_FORM] = 2905040Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_IVPTBR] | (VA_VPN(pc) << 3); 2915040Sgblack@eecs.umich.edu } 2925040Sgblack@eecs.umich.edu} 2935040Sgblack@eecs.umich.edu 2945040Sgblack@eecs.umich.edu 2955040Sgblack@eecs.umich.eduFault 2965040Sgblack@eecs.umich.eduAlphaItb::translate(MemReqPtr &req) const 2975040Sgblack@eecs.umich.edu{ 2985040Sgblack@eecs.umich.edu InternalProcReg *ipr = req->xc->regs.ipr; 2995040Sgblack@eecs.umich.edu 3005040Sgblack@eecs.umich.edu if (PC_PAL(req->vaddr)) { 3015040Sgblack@eecs.umich.edu // strip off PAL PC marker (lsb is 1) 3025040Sgblack@eecs.umich.edu req->paddr = (req->vaddr & ~3) & PA_IMPL_MASK; 3035040Sgblack@eecs.umich.edu hits++; 3045040Sgblack@eecs.umich.edu return No_Fault; 3055040Sgblack@eecs.umich.edu } 3065040Sgblack@eecs.umich.edu 3075040Sgblack@eecs.umich.edu if (req->flags & PHYSICAL) { 3085040Sgblack@eecs.umich.edu req->paddr = req->vaddr; 3095040Sgblack@eecs.umich.edu } else { 3105040Sgblack@eecs.umich.edu // verify that this is a good virtual address 3115040Sgblack@eecs.umich.edu if (!validVirtualAddress(req->vaddr)) { 3125040Sgblack@eecs.umich.edu fault(req->vaddr, req->xc); 3135040Sgblack@eecs.umich.edu acv++; 3145040Sgblack@eecs.umich.edu return Itb_Acv_Fault; 3155062Sgblack@eecs.umich.edu } 3165062Sgblack@eecs.umich.edu 3175062Sgblack@eecs.umich.edu // Check for "superpage" mapping: when SP<1> is set, and 3185062Sgblack@eecs.umich.edu // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. 3195062Sgblack@eecs.umich.edu if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && 3205062Sgblack@eecs.umich.edu VA_SPACE(req->vaddr) == 2) { 3215062Sgblack@eecs.umich.edu 3225040Sgblack@eecs.umich.edu // only valid in kernel mode 3235062Sgblack@eecs.umich.edu if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) { 3245062Sgblack@eecs.umich.edu fault(req->vaddr, req->xc); 3255062Sgblack@eecs.umich.edu acv++; 3265062Sgblack@eecs.umich.edu return Itb_Acv_Fault; 3275040Sgblack@eecs.umich.edu } 3285040Sgblack@eecs.umich.edu 3295040Sgblack@eecs.umich.edu req->paddr = req->vaddr & PA_IMPL_MASK; 3305040Sgblack@eecs.umich.edu 3315040Sgblack@eecs.umich.edu // sign extend the physical address properly 3325040Sgblack@eecs.umich.edu if (req->paddr & PA_UNCACHED_BIT_39 || 3335040Sgblack@eecs.umich.edu req->paddr & PA_UNCACHED_BIT_40) 3345040Sgblack@eecs.umich.edu req->paddr |= 0xf0000000000; 3355040Sgblack@eecs.umich.edu else 3365239Sgblack@eecs.umich.edu req->paddr &= 0xffffffffff; 3375040Sgblack@eecs.umich.edu 3385040Sgblack@eecs.umich.edu } else { 3395040Sgblack@eecs.umich.edu // not a physical address: need to look up pte 3405040Sgblack@eecs.umich.edu AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), 3415040Sgblack@eecs.umich.edu DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 3425040Sgblack@eecs.umich.edu 3435040Sgblack@eecs.umich.edu if (!pte) { 3445040Sgblack@eecs.umich.edu fault(req->vaddr, req->xc); 3455061Sgblack@eecs.umich.edu misses++; 3465040Sgblack@eecs.umich.edu return Itb_Fault_Fault; 3475040Sgblack@eecs.umich.edu } 3485061Sgblack@eecs.umich.edu 3495061Sgblack@eecs.umich.edu req->paddr = PA_PFN2PA(pte->ppn) + VA_POFS(req->vaddr & ~3); 3505061Sgblack@eecs.umich.edu 3515061Sgblack@eecs.umich.edu // check permissions for this access 3525061Sgblack@eecs.umich.edu if (!(pte->xre & (1 << ICM_CM(ipr[AlphaISA::IPR_ICM])))) { 3535061Sgblack@eecs.umich.edu // instruction access fault 3545061Sgblack@eecs.umich.edu fault(req->vaddr, req->xc); 3555061Sgblack@eecs.umich.edu acv++; 3565040Sgblack@eecs.umich.edu return Itb_Acv_Fault; 3575040Sgblack@eecs.umich.edu } 3585040Sgblack@eecs.umich.edu 3595040Sgblack@eecs.umich.edu hits++; 3605040Sgblack@eecs.umich.edu } 3615040Sgblack@eecs.umich.edu } 3625040Sgblack@eecs.umich.edu 3635040Sgblack@eecs.umich.edu // check that the physical address is ok (catch bad physical addresses) 3645040Sgblack@eecs.umich.edu if (req->paddr & ~PA_IMPL_MASK) 3655040Sgblack@eecs.umich.edu return Machine_Check_Fault; 3665040Sgblack@eecs.umich.edu 3675040Sgblack@eecs.umich.edu checkCacheability(req); 3685040Sgblack@eecs.umich.edu 3695040Sgblack@eecs.umich.edu return No_Fault; 3705040Sgblack@eecs.umich.edu} 3715040Sgblack@eecs.umich.edu 3725040Sgblack@eecs.umich.edu/////////////////////////////////////////////////////////////////////// 3735040Sgblack@eecs.umich.edu// 3745040Sgblack@eecs.umich.edu// Alpha DTB 3755040Sgblack@eecs.umich.edu// 3765040Sgblack@eecs.umich.eduAlphaDtb::AlphaDtb(const std::string &name, int size) 3775040Sgblack@eecs.umich.edu : AlphaTlb(name, size) 3785040Sgblack@eecs.umich.edu{} 3795040Sgblack@eecs.umich.edu 3805040Sgblack@eecs.umich.eduvoid 3814688Sgblack@eecs.umich.eduAlphaDtb::regStats() 3825040Sgblack@eecs.umich.edu{ 3834688Sgblack@eecs.umich.edu read_hits 3844688Sgblack@eecs.umich.edu .name(name() + ".read_hits") 3854688Sgblack@eecs.umich.edu .desc("DTB read hits") 3864688Sgblack@eecs.umich.edu ; 3875040Sgblack@eecs.umich.edu 3884688Sgblack@eecs.umich.edu read_misses 3895040Sgblack@eecs.umich.edu .name(name() + ".read_misses") 3905040Sgblack@eecs.umich.edu .desc("DTB read misses") 3915040Sgblack@eecs.umich.edu ; 3925040Sgblack@eecs.umich.edu 3935040Sgblack@eecs.umich.edu read_acv 3945040Sgblack@eecs.umich.edu .name(name() + ".read_acv") 3955040Sgblack@eecs.umich.edu .desc("DTB read access violations") 3965040Sgblack@eecs.umich.edu ; 3975040Sgblack@eecs.umich.edu 3985040Sgblack@eecs.umich.edu read_accesses 3995040Sgblack@eecs.umich.edu .name(name() + ".read_accesses") 4005040Sgblack@eecs.umich.edu .desc("DTB read accesses") 4015040Sgblack@eecs.umich.edu ; 4025040Sgblack@eecs.umich.edu 4035040Sgblack@eecs.umich.edu write_hits 4045040Sgblack@eecs.umich.edu .name(name() + ".write_hits") 4055040Sgblack@eecs.umich.edu .desc("DTB write hits") 4065040Sgblack@eecs.umich.edu ; 4075040Sgblack@eecs.umich.edu 4085040Sgblack@eecs.umich.edu write_misses 4095040Sgblack@eecs.umich.edu .name(name() + ".write_misses") 4105040Sgblack@eecs.umich.edu .desc("DTB write misses") 4114688Sgblack@eecs.umich.edu ; 4124688Sgblack@eecs.umich.edu 4135040Sgblack@eecs.umich.edu write_acv 4145040Sgblack@eecs.umich.edu .name(name() + ".write_acv") 4155040Sgblack@eecs.umich.edu .desc("DTB write access violations") 4165040Sgblack@eecs.umich.edu ; 4174688Sgblack@eecs.umich.edu 4184688Sgblack@eecs.umich.edu write_accesses 4195040Sgblack@eecs.umich.edu .name(name() + ".write_accesses") 4205040Sgblack@eecs.umich.edu .desc("DTB write accesses") 4215040Sgblack@eecs.umich.edu ; 4225040Sgblack@eecs.umich.edu 4235040Sgblack@eecs.umich.edu hits 4245040Sgblack@eecs.umich.edu .name(name() + ".hits") 4254519Sgblack@eecs.umich.edu .desc("DTB hits") 4264519Sgblack@eecs.umich.edu ; 4275040Sgblack@eecs.umich.edu 4284688Sgblack@eecs.umich.edu misses 4294701Sgblack@eecs.umich.edu .name(name() + ".misses") 4304688Sgblack@eecs.umich.edu .desc("DTB misses") 4314688Sgblack@eecs.umich.edu ; 4324688Sgblack@eecs.umich.edu 4334688Sgblack@eecs.umich.edu acv 4344688Sgblack@eecs.umich.edu .name(name() + ".acv") 4354688Sgblack@eecs.umich.edu .desc("DTB access violations") 4364688Sgblack@eecs.umich.edu ; 4374519Sgblack@eecs.umich.edu 4384519Sgblack@eecs.umich.edu accesses 4395040Sgblack@eecs.umich.edu .name(name() + ".accesses") 4405040Sgblack@eecs.umich.edu .desc("DTB accesses") 4415040Sgblack@eecs.umich.edu ; 4425788Sgblack@eecs.umich.edu 4435040Sgblack@eecs.umich.edu hits = read_hits + write_hits; 4444688Sgblack@eecs.umich.edu misses = read_misses + write_misses; 4455040Sgblack@eecs.umich.edu acv = read_acv + write_acv; 4464519Sgblack@eecs.umich.edu accesses = read_accesses + write_accesses; 4475040Sgblack@eecs.umich.edu} 4484519Sgblack@eecs.umich.edu 4494519Sgblack@eecs.umich.eduvoid 4504519Sgblack@eecs.umich.eduAlphaDtb::fault(Addr vaddr, uint64_t flags, ExecContext *xc) const 4514539Sgblack@eecs.umich.edu{ 4524519Sgblack@eecs.umich.edu uint64_t *ipr = xc->regs.ipr; 4535040Sgblack@eecs.umich.edu 4544688Sgblack@eecs.umich.edu // set fault address and flags 4555040Sgblack@eecs.umich.edu if (!xc->misspeculating() && !xc->regs.intrlock) { 4565040Sgblack@eecs.umich.edu // set VA register with faulting address 4575115Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_VA] = vaddr; 4585040Sgblack@eecs.umich.edu 4595040Sgblack@eecs.umich.edu // set MM_STAT register flags 4605040Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_MM_STAT] = (((xc->regs.opcode & 0x3f) << 11) 4615115Sgblack@eecs.umich.edu | ((xc->regs.ra & 0x1f) << 6) 4625040Sgblack@eecs.umich.edu | (flags & 0x3f)); 4635040Sgblack@eecs.umich.edu 4644519Sgblack@eecs.umich.edu // set VA_FORM register with faulting formatted address 4655040Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_VA_FORM] = 4665040Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_MVPTBR] | (VA_VPN(vaddr) << 3); 4675040Sgblack@eecs.umich.edu 4685040Sgblack@eecs.umich.edu // lock these registers until the VA register is read 4694519Sgblack@eecs.umich.edu xc->regs.intrlock = true; 4705040Sgblack@eecs.umich.edu } 4715040Sgblack@eecs.umich.edu} 4725040Sgblack@eecs.umich.edu 4735040Sgblack@eecs.umich.eduFault 4744519Sgblack@eecs.umich.eduAlphaDtb::translate(MemReqPtr &req, bool write) const 4755040Sgblack@eecs.umich.edu{ 4765040Sgblack@eecs.umich.edu RegFile *regs = &req->xc->regs; 4775083Sgblack@eecs.umich.edu Addr pc = regs->pc; 4784519Sgblack@eecs.umich.edu InternalProcReg *ipr = regs->ipr; 4795063Sgblack@eecs.umich.edu 4805063Sgblack@eecs.umich.edu AlphaISA::mode_type mode = 4815063Sgblack@eecs.umich.edu (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]); 4825063Sgblack@eecs.umich.edu 4835063Sgblack@eecs.umich.edu if (PC_PAL(pc)) { 4845063Sgblack@eecs.umich.edu mode = (req->flags & ALTMODE) ? 4855063Sgblack@eecs.umich.edu (AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE]) 4865063Sgblack@eecs.umich.edu : AlphaISA::mode_kernel; 4875063Sgblack@eecs.umich.edu } 4885063Sgblack@eecs.umich.edu 4895063Sgblack@eecs.umich.edu if (req->flags & PHYSICAL) { 4905063Sgblack@eecs.umich.edu req->paddr = req->vaddr; 4915040Sgblack@eecs.umich.edu } else { 4925040Sgblack@eecs.umich.edu // verify that this is a good virtual address 4934595Sgblack@eecs.umich.edu if (!validVirtualAddress(req->vaddr)) { 4945040Sgblack@eecs.umich.edu fault(req->vaddr, 4955040Sgblack@eecs.umich.edu ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | 4964595Sgblack@eecs.umich.edu MM_STAT_ACV_MASK), 4975040Sgblack@eecs.umich.edu req->xc); 4985040Sgblack@eecs.umich.edu 4994732Sgblack@eecs.umich.edu if (write) { write_acv++; } else { read_acv++; } 5005138Sgblack@eecs.umich.edu return Dtb_Fault_Fault; 5015040Sgblack@eecs.umich.edu } 5025040Sgblack@eecs.umich.edu 5035040Sgblack@eecs.umich.edu // Check for "superpage" mapping: when SP<1> is set, and 5045040Sgblack@eecs.umich.edu // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. 5054732Sgblack@eecs.umich.edu if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && 5065138Sgblack@eecs.umich.edu VA_SPACE(req->vaddr) == 2) { 5075040Sgblack@eecs.umich.edu 5085040Sgblack@eecs.umich.edu // only valid in kernel mode 5095040Sgblack@eecs.umich.edu if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != 5105040Sgblack@eecs.umich.edu AlphaISA::mode_kernel) { 5115040Sgblack@eecs.umich.edu fault(req->vaddr, 5125040Sgblack@eecs.umich.edu ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK), 5135040Sgblack@eecs.umich.edu req->xc); 5145040Sgblack@eecs.umich.edu if (write) { write_acv++; } else { read_acv++; } 5155040Sgblack@eecs.umich.edu return Dtb_Acv_Fault; 5165040Sgblack@eecs.umich.edu } 5175040Sgblack@eecs.umich.edu 5185065Sgblack@eecs.umich.edu req->paddr = req->vaddr & PA_IMPL_MASK; 5195065Sgblack@eecs.umich.edu 5205065Sgblack@eecs.umich.edu // sign extend the physical address properly 5215065Sgblack@eecs.umich.edu if (req->paddr & PA_UNCACHED_BIT_39 || 5225065Sgblack@eecs.umich.edu req->paddr & PA_UNCACHED_BIT_40) 5235063Sgblack@eecs.umich.edu req->paddr |= 0xf0000000000; 5245040Sgblack@eecs.umich.edu else 5255063Sgblack@eecs.umich.edu req->paddr &= 0xffffffffff; 5265063Sgblack@eecs.umich.edu 5275063Sgblack@eecs.umich.edu } else { 5285063Sgblack@eecs.umich.edu if (write) 5295063Sgblack@eecs.umich.edu write_accesses++; 5305063Sgblack@eecs.umich.edu else 5315063Sgblack@eecs.umich.edu read_accesses++; 5325063Sgblack@eecs.umich.edu 5335063Sgblack@eecs.umich.edu // not a physical address: need to look up pte 5345040Sgblack@eecs.umich.edu AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), 5355040Sgblack@eecs.umich.edu DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 5365063Sgblack@eecs.umich.edu 5375040Sgblack@eecs.umich.edu if (!pte) { 5385063Sgblack@eecs.umich.edu // page fault 5394809Sgblack@eecs.umich.edu fault(req->vaddr, 5405063Sgblack@eecs.umich.edu ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK), 5415063Sgblack@eecs.umich.edu req->xc); 5425063Sgblack@eecs.umich.edu if (write) { write_misses++; } else { read_misses++; } 5435063Sgblack@eecs.umich.edu return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault; 5445063Sgblack@eecs.umich.edu } 5455063Sgblack@eecs.umich.edu 5465063Sgblack@eecs.umich.edu req->paddr = PA_PFN2PA(pte->ppn) | VA_POFS(req->vaddr); 5475040Sgblack@eecs.umich.edu 5485040Sgblack@eecs.umich.edu if (write) { 5495063Sgblack@eecs.umich.edu if (!(pte->xwe & MODE2MASK(mode))) { 5505063Sgblack@eecs.umich.edu // declare the instruction access fault 5515040Sgblack@eecs.umich.edu fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_ACV_MASK | 5525063Sgblack@eecs.umich.edu (pte->fonw ? MM_STAT_FONW_MASK : 0), 5535063Sgblack@eecs.umich.edu req->xc); 5545063Sgblack@eecs.umich.edu write_acv++; 5555063Sgblack@eecs.umich.edu return Dtb_Fault_Fault; 5565063Sgblack@eecs.umich.edu } 5575063Sgblack@eecs.umich.edu if (pte->fonw) { 5585063Sgblack@eecs.umich.edu fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_FONW_MASK, 5595063Sgblack@eecs.umich.edu req->xc); 5605063Sgblack@eecs.umich.edu write_acv++; 5615063Sgblack@eecs.umich.edu return Dtb_Fault_Fault; 5625063Sgblack@eecs.umich.edu } 5635063Sgblack@eecs.umich.edu } else { 5645062Sgblack@eecs.umich.edu if (!(pte->xre & MODE2MASK(mode))) { 5655075Sgblack@eecs.umich.edu fault(req->vaddr, 5665075Sgblack@eecs.umich.edu MM_STAT_ACV_MASK | 5675040Sgblack@eecs.umich.edu (pte->fonr ? MM_STAT_FONR_MASK : 0), 5685075Sgblack@eecs.umich.edu req->xc); 5695075Sgblack@eecs.umich.edu read_acv++; 5705075Sgblack@eecs.umich.edu return Dtb_Acv_Fault; 5715075Sgblack@eecs.umich.edu } 5725075Sgblack@eecs.umich.edu if (pte->fonr) { 5735075Sgblack@eecs.umich.edu fault(req->vaddr, MM_STAT_FONR_MASK, req->xc); 5745075Sgblack@eecs.umich.edu read_acv++; 5755075Sgblack@eecs.umich.edu return Dtb_Fault_Fault; 5765075Sgblack@eecs.umich.edu } 5775075Sgblack@eecs.umich.edu } 5785075Sgblack@eecs.umich.edu } 5795075Sgblack@eecs.umich.edu 5805075Sgblack@eecs.umich.edu if (write) 5815075Sgblack@eecs.umich.edu write_hits++; 5825075Sgblack@eecs.umich.edu else 5835040Sgblack@eecs.umich.edu read_hits++; 5844823Sgblack@eecs.umich.edu } 5855075Sgblack@eecs.umich.edu 5865075Sgblack@eecs.umich.edu // check that the physical address is ok (catch bad physical addresses) 5875075Sgblack@eecs.umich.edu if (req->paddr & ~PA_IMPL_MASK) 5885075Sgblack@eecs.umich.edu return Machine_Check_Fault; 5895075Sgblack@eecs.umich.edu 5905075Sgblack@eecs.umich.edu checkCacheability(req); 5915075Sgblack@eecs.umich.edu 5925075Sgblack@eecs.umich.edu return No_Fault; 5935075Sgblack@eecs.umich.edu} 5945075Sgblack@eecs.umich.edu 5955075Sgblack@eecs.umich.eduAlphaISA::PTE & 5965075Sgblack@eecs.umich.eduAlphaTlb::index(bool advance) 5975075Sgblack@eecs.umich.edu{ 5985075Sgblack@eecs.umich.edu AlphaISA::PTE *pte = &table[nlu]; 5995075Sgblack@eecs.umich.edu 6005075Sgblack@eecs.umich.edu if (advance) 6015075Sgblack@eecs.umich.edu nextnlu(); 6025075Sgblack@eecs.umich.edu 6035075Sgblack@eecs.umich.edu return *pte; 6045075Sgblack@eecs.umich.edu} 6055075Sgblack@eecs.umich.edu 6065075Sgblack@eecs.umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaItb) 6075075Sgblack@eecs.umich.edu 6085075Sgblack@eecs.umich.edu Param<int> size; 6095075Sgblack@eecs.umich.edu 6105075Sgblack@eecs.umich.eduEND_DECLARE_SIM_OBJECT_PARAMS(AlphaItb) 6115075Sgblack@eecs.umich.edu 6125075Sgblack@eecs.umich.eduBEGIN_INIT_SIM_OBJECT_PARAMS(AlphaItb) 6135075Sgblack@eecs.umich.edu 6145075Sgblack@eecs.umich.edu INIT_PARAM_DFLT(size, "TLB size", 48) 6155075Sgblack@eecs.umich.edu 6165075Sgblack@eecs.umich.eduEND_INIT_SIM_OBJECT_PARAMS(AlphaItb) 6175075Sgblack@eecs.umich.edu 6184732Sgblack@eecs.umich.edu 6195075Sgblack@eecs.umich.eduCREATE_SIM_OBJECT(AlphaItb) 6205075Sgblack@eecs.umich.edu{ 6215075Sgblack@eecs.umich.edu return new AlphaItb(getInstanceName(), size); 6225075Sgblack@eecs.umich.edu} 6235075Sgblack@eecs.umich.edu 6245040Sgblack@eecs.umich.eduREGISTER_SIM_OBJECT("AlphaITB", AlphaItb) 6255040Sgblack@eecs.umich.edu 6265040Sgblack@eecs.umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb) 6275040Sgblack@eecs.umich.edu 6285040Sgblack@eecs.umich.edu Param<int> size; 6294732Sgblack@eecs.umich.edu 6305040Sgblack@eecs.umich.eduEND_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb) 6315076Sgblack@eecs.umich.edu 6325040Sgblack@eecs.umich.eduBEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDtb) 6334756Sgblack@eecs.umich.edu 6344823Sgblack@eecs.umich.edu INIT_PARAM_DFLT(size, "TLB size", 64) 6355040Sgblack@eecs.umich.edu 6365076Sgblack@eecs.umich.eduEND_INIT_SIM_OBJECT_PARAMS(AlphaDtb) 6375076Sgblack@eecs.umich.edu 6385076Sgblack@eecs.umich.edu 6395076Sgblack@eecs.umich.eduCREATE_SIM_OBJECT(AlphaDtb) 6405076Sgblack@eecs.umich.edu{ 6415076Sgblack@eecs.umich.edu return new AlphaDtb(getInstanceName(), size); 6425076Sgblack@eecs.umich.edu} 6435076Sgblack@eecs.umich.edu 6445076Sgblack@eecs.umich.eduREGISTER_SIM_OBJECT("AlphaDTB", AlphaDtb) 6455076Sgblack@eecs.umich.edu 6465076Sgblack@eecs.umich.edu