tlb.cc revision 533
17118Sgblack@eecs.umich.edu/* 27118Sgblack@eecs.umich.edu * Copyright (c) 2003 The Regents of The University of Michigan 37118Sgblack@eecs.umich.edu * All rights reserved. 47118Sgblack@eecs.umich.edu * 57118Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67118Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77118Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87118Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97118Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107118Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117118Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127118Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137118Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 147118Sgblack@eecs.umich.edu * this software without specific prior written permission. 156253Sgblack@eecs.umich.edu * 166253Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176253Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186253Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196253Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206253Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216253Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226253Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236253Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246253Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256253Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266253Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276253Sgblack@eecs.umich.edu */ 286253Sgblack@eecs.umich.edu 296253Sgblack@eecs.umich.edu#include <sstream> 306253Sgblack@eecs.umich.edu#include <string> 316253Sgblack@eecs.umich.edu#include <vector> 326253Sgblack@eecs.umich.edu 336253Sgblack@eecs.umich.edu#include "base/inifile.hh" 346253Sgblack@eecs.umich.edu#include "base/str.hh" 356253Sgblack@eecs.umich.edu#include "base/trace.hh" 366253Sgblack@eecs.umich.edu#include "cpu/exec_context.hh" 376253Sgblack@eecs.umich.edu#include "sim/builder.hh" 386253Sgblack@eecs.umich.edu#include "targetarch/alpha_memory.hh" 396253Sgblack@eecs.umich.edu#include "targetarch/ev5.hh" 406253Sgblack@eecs.umich.edu 416253Sgblack@eecs.umich.eduusing namespace std; 426253Sgblack@eecs.umich.edu 436253Sgblack@eecs.umich.edu/////////////////////////////////////////////////////////////////////// 446253Sgblack@eecs.umich.edu// 456253Sgblack@eecs.umich.edu// Alpha TLB 466253Sgblack@eecs.umich.edu// 476253Sgblack@eecs.umich.eduAlphaTlb::AlphaTlb(const string &name, int s) 486253Sgblack@eecs.umich.edu : SimObject(name), size(s), nlu(0) 497118Sgblack@eecs.umich.edu{ 507118Sgblack@eecs.umich.edu table = new AlphaISA::PTE[size]; 517118Sgblack@eecs.umich.edu memset(table, 0, sizeof(AlphaISA::PTE[size])); 527118Sgblack@eecs.umich.edu} 537118Sgblack@eecs.umich.edu 547118Sgblack@eecs.umich.eduAlphaTlb::~AlphaTlb() 557118Sgblack@eecs.umich.edu{ 567118Sgblack@eecs.umich.edu if (table) 577118Sgblack@eecs.umich.edu delete [] table; 587118Sgblack@eecs.umich.edu} 597118Sgblack@eecs.umich.edu 607118Sgblack@eecs.umich.edu// look up an entry in the TLB 617118Sgblack@eecs.umich.eduAlphaISA::PTE * 627118Sgblack@eecs.umich.eduAlphaTlb::lookup(Addr vpn, uint8_t asn) const 637118Sgblack@eecs.umich.edu{ 647118Sgblack@eecs.umich.edu DPRINTF(TLB, "lookup %#x\n", vpn); 657118Sgblack@eecs.umich.edu 667118Sgblack@eecs.umich.edu PageTable::const_iterator i = lookupTable.find(vpn); 677118Sgblack@eecs.umich.edu if (i == lookupTable.end()) 687118Sgblack@eecs.umich.edu return NULL; 697118Sgblack@eecs.umich.edu 707118Sgblack@eecs.umich.edu while (i->first == vpn) { 717118Sgblack@eecs.umich.edu int index = i->second; 727118Sgblack@eecs.umich.edu AlphaISA::PTE *pte = &table[index]; 737118Sgblack@eecs.umich.edu assert(pte->valid); 747118Sgblack@eecs.umich.edu if (vpn == pte->tag && (pte->asma || pte->asn == asn)) 757118Sgblack@eecs.umich.edu return pte; 767118Sgblack@eecs.umich.edu 777118Sgblack@eecs.umich.edu ++i; 787118Sgblack@eecs.umich.edu } 797118Sgblack@eecs.umich.edu 807118Sgblack@eecs.umich.edu // not found... 817118Sgblack@eecs.umich.edu return NULL; 827118Sgblack@eecs.umich.edu} 837118Sgblack@eecs.umich.edu 847118Sgblack@eecs.umich.edu 857118Sgblack@eecs.umich.eduvoid 867118Sgblack@eecs.umich.eduAlphaTlb::checkCacheability(MemReqPtr &req) 877118Sgblack@eecs.umich.edu{ 887118Sgblack@eecs.umich.edu // in Alpha, cacheability is controlled by upper-level bits of the 897118Sgblack@eecs.umich.edu // physical address 907118Sgblack@eecs.umich.edu if (req->paddr & PA_UNCACHED_BIT) { 917118Sgblack@eecs.umich.edu if (PA_IPR_SPACE(req->paddr)) { 927118Sgblack@eecs.umich.edu // IPR memory space not implemented 937118Sgblack@eecs.umich.edu if (!req->xc->misspeculating()) { 947118Sgblack@eecs.umich.edu switch (req->paddr) { 957118Sgblack@eecs.umich.edu case 0xFFFFF00188: 967118Sgblack@eecs.umich.edu req->data = 0; 977118Sgblack@eecs.umich.edu break; 987118Sgblack@eecs.umich.edu 997118Sgblack@eecs.umich.edu default: 1007118Sgblack@eecs.umich.edu panic("IPR memory space not implemented! PA=%x\n", 1017118Sgblack@eecs.umich.edu req->paddr); 1027118Sgblack@eecs.umich.edu } 1037118Sgblack@eecs.umich.edu } 1047118Sgblack@eecs.umich.edu } else { 1057118Sgblack@eecs.umich.edu // mark request as uncacheable 1067118Sgblack@eecs.umich.edu req->flags |= UNCACHEABLE; 1077118Sgblack@eecs.umich.edu } 1087118Sgblack@eecs.umich.edu } 1097118Sgblack@eecs.umich.edu} 1107118Sgblack@eecs.umich.edu 1117118Sgblack@eecs.umich.edu 1127118Sgblack@eecs.umich.edu// insert a new TLB entry 1137118Sgblack@eecs.umich.eduvoid 1147118Sgblack@eecs.umich.eduAlphaTlb::insert(Addr vaddr, AlphaISA::PTE &pte) 1157118Sgblack@eecs.umich.edu{ 1167118Sgblack@eecs.umich.edu if (table[nlu].valid) { 1177118Sgblack@eecs.umich.edu Addr oldvpn = table[nlu].tag; 1187118Sgblack@eecs.umich.edu PageTable::iterator i = lookupTable.find(oldvpn); 1197118Sgblack@eecs.umich.edu 1207118Sgblack@eecs.umich.edu if (i == lookupTable.end()) 1217118Sgblack@eecs.umich.edu panic("TLB entry not found in lookupTable"); 1227118Sgblack@eecs.umich.edu 1237118Sgblack@eecs.umich.edu int index; 1247118Sgblack@eecs.umich.edu while ((index = i->second) != nlu) { 1257118Sgblack@eecs.umich.edu if (table[index].tag != oldvpn) 1267118Sgblack@eecs.umich.edu panic("TLB entry not found in lookupTable"); 1277118Sgblack@eecs.umich.edu 1287118Sgblack@eecs.umich.edu ++i; 1297118Sgblack@eecs.umich.edu } 1307118Sgblack@eecs.umich.edu 1317118Sgblack@eecs.umich.edu DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); 1327118Sgblack@eecs.umich.edu 1337118Sgblack@eecs.umich.edu lookupTable.erase(i); 1347118Sgblack@eecs.umich.edu } 1357118Sgblack@eecs.umich.edu 1367118Sgblack@eecs.umich.edu Addr vpn = VA_VPN(vaddr); 1377118Sgblack@eecs.umich.edu DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vpn, pte.ppn); 1387118Sgblack@eecs.umich.edu 1397118Sgblack@eecs.umich.edu table[nlu] = pte; 1407118Sgblack@eecs.umich.edu table[nlu].tag = vpn; 1417118Sgblack@eecs.umich.edu table[nlu].valid = true; 1427118Sgblack@eecs.umich.edu 1437118Sgblack@eecs.umich.edu lookupTable.insert(make_pair(vpn, nlu)); 1447118Sgblack@eecs.umich.edu nextnlu(); 1457118Sgblack@eecs.umich.edu} 1467118Sgblack@eecs.umich.edu 1477118Sgblack@eecs.umich.eduvoid 1487118Sgblack@eecs.umich.eduAlphaTlb::flushAll() 1497118Sgblack@eecs.umich.edu{ 1507118Sgblack@eecs.umich.edu memset(table, 0, sizeof(AlphaISA::PTE[size])); 1517118Sgblack@eecs.umich.edu lookupTable.clear(); 1527118Sgblack@eecs.umich.edu nlu = 0; 1537118Sgblack@eecs.umich.edu} 1547118Sgblack@eecs.umich.edu 1557118Sgblack@eecs.umich.eduvoid 1567118Sgblack@eecs.umich.eduAlphaTlb::flushProcesses() 1577118Sgblack@eecs.umich.edu{ 1587118Sgblack@eecs.umich.edu PageTable::iterator i = lookupTable.begin(); 1597118Sgblack@eecs.umich.edu PageTable::iterator end = lookupTable.end(); 1607118Sgblack@eecs.umich.edu while (i != end) { 1617118Sgblack@eecs.umich.edu int index = i->second; 1627118Sgblack@eecs.umich.edu AlphaISA::PTE *pte = &table[index]; 1637118Sgblack@eecs.umich.edu assert(pte->valid); 1647118Sgblack@eecs.umich.edu 1657118Sgblack@eecs.umich.edu if (!pte->asma) { 1667118Sgblack@eecs.umich.edu DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); 1677118Sgblack@eecs.umich.edu pte->valid = false; 1687118Sgblack@eecs.umich.edu lookupTable.erase(i); 1697118Sgblack@eecs.umich.edu } 1707118Sgblack@eecs.umich.edu 1717118Sgblack@eecs.umich.edu ++i; 1727118Sgblack@eecs.umich.edu } 1737118Sgblack@eecs.umich.edu} 1747118Sgblack@eecs.umich.edu 1757118Sgblack@eecs.umich.eduvoid 1767118Sgblack@eecs.umich.eduAlphaTlb::flushAddr(Addr vaddr, uint8_t asn) 1777118Sgblack@eecs.umich.edu{ 1787118Sgblack@eecs.umich.edu Addr vpn = VA_VPN(vaddr); 1797118Sgblack@eecs.umich.edu 1807118Sgblack@eecs.umich.edu PageTable::iterator i = lookupTable.find(vpn); 1817118Sgblack@eecs.umich.edu if (i == lookupTable.end()) 1827118Sgblack@eecs.umich.edu return; 1837118Sgblack@eecs.umich.edu 1847118Sgblack@eecs.umich.edu while (i->first == vpn) { 1857118Sgblack@eecs.umich.edu int index = i->second; 1867118Sgblack@eecs.umich.edu AlphaISA::PTE *pte = &table[index]; 1877118Sgblack@eecs.umich.edu assert(pte->valid); 1887118Sgblack@eecs.umich.edu 1897118Sgblack@eecs.umich.edu if (vpn == pte->tag && (pte->asma || pte->asn == asn)) { 1907118Sgblack@eecs.umich.edu DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vpn, pte->ppn); 1917118Sgblack@eecs.umich.edu 1927118Sgblack@eecs.umich.edu // invalidate this entry 1937118Sgblack@eecs.umich.edu pte->valid = false; 1947118Sgblack@eecs.umich.edu 1957118Sgblack@eecs.umich.edu lookupTable.erase(i); 1967118Sgblack@eecs.umich.edu } 1977118Sgblack@eecs.umich.edu 1987118Sgblack@eecs.umich.edu ++i; 1997118Sgblack@eecs.umich.edu } 2007118Sgblack@eecs.umich.edu} 2017118Sgblack@eecs.umich.edu 2027118Sgblack@eecs.umich.edu 2037118Sgblack@eecs.umich.eduvoid 2047118Sgblack@eecs.umich.eduAlphaTlb::serialize(ostream &os) 2057118Sgblack@eecs.umich.edu{ 2067118Sgblack@eecs.umich.edu SERIALIZE_SCALAR(size); 2077118Sgblack@eecs.umich.edu SERIALIZE_SCALAR(nlu); 2087118Sgblack@eecs.umich.edu 2097118Sgblack@eecs.umich.edu for (int i = 0; i < size; i++) { 2107118Sgblack@eecs.umich.edu nameOut(os, csprintf("%s.PTE%d", name(), i)); 2117118Sgblack@eecs.umich.edu table[i].serialize(os); 2127118Sgblack@eecs.umich.edu } 2137118Sgblack@eecs.umich.edu} 2147118Sgblack@eecs.umich.edu 2157118Sgblack@eecs.umich.eduvoid 2167118Sgblack@eecs.umich.eduAlphaTlb::unserialize(Checkpoint *cp, const string §ion) 2177118Sgblack@eecs.umich.edu{ 2187118Sgblack@eecs.umich.edu UNSERIALIZE_SCALAR(size); 2197118Sgblack@eecs.umich.edu UNSERIALIZE_SCALAR(nlu); 2207118Sgblack@eecs.umich.edu 2217118Sgblack@eecs.umich.edu for (int i = 0; i < size; i++) { 2227118Sgblack@eecs.umich.edu table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); 2237118Sgblack@eecs.umich.edu if (table[i].valid) { 2247118Sgblack@eecs.umich.edu lookupTable.insert(make_pair(table[i].tag, i)); 2257118Sgblack@eecs.umich.edu } 2267118Sgblack@eecs.umich.edu } 2277118Sgblack@eecs.umich.edu} 2287118Sgblack@eecs.umich.edu 2297118Sgblack@eecs.umich.edu 2307118Sgblack@eecs.umich.edu/////////////////////////////////////////////////////////////////////// 2317118Sgblack@eecs.umich.edu// 2327118Sgblack@eecs.umich.edu// Alpha ITB 2336253Sgblack@eecs.umich.edu// 2346253Sgblack@eecs.umich.eduAlphaItb::AlphaItb(const std::string &name, int size) 2356253Sgblack@eecs.umich.edu : AlphaTlb(name, size) 2366253Sgblack@eecs.umich.edu{} 2376253Sgblack@eecs.umich.edu 2386253Sgblack@eecs.umich.edu 2396253Sgblack@eecs.umich.eduvoid 2406253Sgblack@eecs.umich.eduAlphaItb::regStats() 2416253Sgblack@eecs.umich.edu{ 2426253Sgblack@eecs.umich.edu hits 2436253Sgblack@eecs.umich.edu .name(name() + ".hits") 2446253Sgblack@eecs.umich.edu .desc("ITB hits"); 2456253Sgblack@eecs.umich.edu misses 2466253Sgblack@eecs.umich.edu .name(name() + ".misses") 2476253Sgblack@eecs.umich.edu .desc("ITB misses"); 2486253Sgblack@eecs.umich.edu acv 2496253Sgblack@eecs.umich.edu .name(name() + ".acv") 2506253Sgblack@eecs.umich.edu .desc("ITB acv"); 2516253Sgblack@eecs.umich.edu accesses 2526305Sgblack@eecs.umich.edu .name(name() + ".accesses") 2536253Sgblack@eecs.umich.edu .desc("ITB accesses"); 2546253Sgblack@eecs.umich.edu 2556253Sgblack@eecs.umich.edu accesses = hits + misses; 2566253Sgblack@eecs.umich.edu} 2576253Sgblack@eecs.umich.edu 2586253Sgblack@eecs.umich.eduvoid 2596253Sgblack@eecs.umich.eduAlphaItb::fault(Addr pc, ExecContext *xc) const 2606253Sgblack@eecs.umich.edu{ 2616253Sgblack@eecs.umich.edu uint64_t *ipr = xc->regs.ipr; 2626253Sgblack@eecs.umich.edu 2636253Sgblack@eecs.umich.edu if (!xc->misspeculating()) { 2646253Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_ITB_TAG] = pc; 2656307Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_IFAULT_VA_FORM] = 2666307Sgblack@eecs.umich.edu ipr[AlphaISA::IPR_IVPTBR] | (VA_VPN(pc) << 3); 2676307Sgblack@eecs.umich.edu } 2686307Sgblack@eecs.umich.edu} 2696253Sgblack@eecs.umich.edu 2706253Sgblack@eecs.umich.edu 2716307Sgblack@eecs.umich.eduFault 2726253Sgblack@eecs.umich.eduAlphaItb::translate(MemReqPtr &req) const 2736253Sgblack@eecs.umich.edu{ 2746253Sgblack@eecs.umich.edu InternalProcReg *ipr = req->xc->regs.ipr; 2756307Sgblack@eecs.umich.edu 2766305Sgblack@eecs.umich.edu if (PC_PAL(req->vaddr)) { 2776253Sgblack@eecs.umich.edu // strip off PAL PC marker (lsb is 1) 2786253Sgblack@eecs.umich.edu req->paddr = (req->vaddr & ~3) & PA_IMPL_MASK; 2796253Sgblack@eecs.umich.edu hits++; 2806307Sgblack@eecs.umich.edu return No_Fault; 2816307Sgblack@eecs.umich.edu } 2826307Sgblack@eecs.umich.edu 2836307Sgblack@eecs.umich.edu // verify that this is a good virtual address 2846307Sgblack@eecs.umich.edu if (!validVirtualAddress(req->vaddr)) { 2856307Sgblack@eecs.umich.edu fault(req->vaddr, req->xc); 2866307Sgblack@eecs.umich.edu acv++; 2876307Sgblack@eecs.umich.edu return Itb_Acv_Fault; 2886307Sgblack@eecs.umich.edu } 2896307Sgblack@eecs.umich.edu 2906307Sgblack@eecs.umich.edu // Check for "superpage" mapping: when SP<1> is set, and 2916307Sgblack@eecs.umich.edu // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. 2926307Sgblack@eecs.umich.edu if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && 2936307Sgblack@eecs.umich.edu VA_SPACE(req->vaddr) == 2) { 2946307Sgblack@eecs.umich.edu // only valid in kernel mode 2956307Sgblack@eecs.umich.edu if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) { 2966307Sgblack@eecs.umich.edu fault(req->vaddr, req->xc); 2976307Sgblack@eecs.umich.edu acv++; 2986307Sgblack@eecs.umich.edu return Itb_Acv_Fault; 2996307Sgblack@eecs.umich.edu } 3006307Sgblack@eecs.umich.edu 3016307Sgblack@eecs.umich.edu req->flags |= PHYSICAL; 3026307Sgblack@eecs.umich.edu } 3036307Sgblack@eecs.umich.edu 3046307Sgblack@eecs.umich.edu if (req->flags & PHYSICAL) { 3056307Sgblack@eecs.umich.edu req->paddr = req->vaddr & PA_IMPL_MASK; 3066307Sgblack@eecs.umich.edu } else { 3076307Sgblack@eecs.umich.edu // not a physical address: need to look up pte 3086307Sgblack@eecs.umich.edu 3096307Sgblack@eecs.umich.edu AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), 3106307Sgblack@eecs.umich.edu DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 3116307Sgblack@eecs.umich.edu 3126307Sgblack@eecs.umich.edu if (!pte) { 3136307Sgblack@eecs.umich.edu fault(req->vaddr, req->xc); 3146307Sgblack@eecs.umich.edu misses++; 3156307Sgblack@eecs.umich.edu return Itb_Fault_Fault; 3166307Sgblack@eecs.umich.edu } 3176307Sgblack@eecs.umich.edu 3186307Sgblack@eecs.umich.edu req->paddr = PA_PFN2PA(pte->ppn) + VA_POFS(req->vaddr & ~3); 3196307Sgblack@eecs.umich.edu 3206307Sgblack@eecs.umich.edu // check permissions for this access 3216307Sgblack@eecs.umich.edu if (!(pte->xre & (1 << ICM_CM(ipr[AlphaISA::IPR_ICM])))) { 3226307Sgblack@eecs.umich.edu // instruction access fault 3236307Sgblack@eecs.umich.edu fault(req->vaddr, req->xc); 3246307Sgblack@eecs.umich.edu acv++; 3256307Sgblack@eecs.umich.edu return Itb_Acv_Fault; 3266307Sgblack@eecs.umich.edu } 3276307Sgblack@eecs.umich.edu } 3286307Sgblack@eecs.umich.edu 3296307Sgblack@eecs.umich.edu checkCacheability(req); 3306307Sgblack@eecs.umich.edu 3316307Sgblack@eecs.umich.edu hits++; 3326307Sgblack@eecs.umich.edu return No_Fault; 3336307Sgblack@eecs.umich.edu} 3346253Sgblack@eecs.umich.edu 3356253Sgblack@eecs.umich.edu/////////////////////////////////////////////////////////////////////// 3366253Sgblack@eecs.umich.edu// 3376253Sgblack@eecs.umich.edu// Alpha DTB 338// 339AlphaDtb::AlphaDtb(const std::string &name, int size) 340 : AlphaTlb(name, size) 341{} 342 343void 344AlphaDtb::regStats() 345{ 346 read_hits 347 .name(name() + ".read_hits") 348 .desc("DTB read hits") 349 ; 350 351 read_misses 352 .name(name() + ".read_misses") 353 .desc("DTB read misses") 354 ; 355 356 read_acv 357 .name(name() + ".read_acv") 358 .desc("DTB read access violations") 359 ; 360 361 read_accesses 362 .name(name() + ".read_accesses") 363 .desc("DTB read accesses") 364 ; 365 366 write_hits 367 .name(name() + ".write_hits") 368 .desc("DTB write hits") 369 ; 370 371 write_misses 372 .name(name() + ".write_misses") 373 .desc("DTB write misses") 374 ; 375 376 write_acv 377 .name(name() + ".write_acv") 378 .desc("DTB write access violations") 379 ; 380 381 write_accesses 382 .name(name() + ".write_accesses") 383 .desc("DTB write accesses") 384 ; 385 386 hits 387 .name(name() + ".hits") 388 .desc("DTB hits") 389 ; 390 391 misses 392 .name(name() + ".misses") 393 .desc("DTB misses") 394 ; 395 396 acv 397 .name(name() + ".acv") 398 .desc("DTB access violations") 399 ; 400 401 accesses 402 .name(name() + ".accesses") 403 .desc("DTB accesses") 404 ; 405 406 hits = read_hits + write_hits; 407 misses = read_misses + write_misses; 408 acv = read_acv + write_acv; 409 accesses = read_accesses + write_accesses; 410} 411 412void 413AlphaDtb::fault(Addr vaddr, uint64_t flags, ExecContext *xc) const 414{ 415 uint64_t *ipr = xc->regs.ipr; 416 417 // set fault address and flags 418 if (!xc->misspeculating() && !xc->regs.intrlock) { 419 // set VA register with faulting address 420 ipr[AlphaISA::IPR_VA] = vaddr; 421 422 // set MM_STAT register flags 423 ipr[AlphaISA::IPR_MM_STAT] = (((xc->regs.opcode & 0x3f) << 11) 424 | ((xc->regs.ra & 0x1f) << 6) 425 | (flags & 0x3f)); 426 427 // set VA_FORM register with faulting formatted address 428 ipr[AlphaISA::IPR_VA_FORM] = 429 ipr[AlphaISA::IPR_MVPTBR] | (VA_VPN(vaddr) << 3); 430 431 // lock these registers until the VA register is read 432 xc->regs.intrlock = true; 433 } 434} 435 436Fault 437AlphaDtb::translate(MemReqPtr &req, bool write) const 438{ 439 RegFile *regs = &req->xc->regs; 440 Addr pc = regs->pc; 441 InternalProcReg *ipr = regs->ipr; 442 443 if (write) 444 write_accesses++; 445 else 446 read_accesses++; 447 448 AlphaISA::mode_type mode = 449 (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]); 450 451 if (PC_PAL(pc)) { 452 mode = (req->flags & ALTMODE) ? 453 (AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE]) 454 : AlphaISA::mode_kernel; 455 } 456 457 // verify that this is a good virtual address 458 if (!validVirtualAddress(req->vaddr)) { 459 fault(req->vaddr, 460 ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | 461 MM_STAT_ACV_MASK), 462 req->xc); 463 464 if (write) { write_acv++; } else { read_acv++; } 465 return Dtb_Fault_Fault; 466 } 467 468 // Check for "superpage" mapping: when SP<1> is set, and 469 // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. 470 if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && VA_SPACE(req->vaddr) == 2) { 471 // only valid in kernel mode 472 if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != AlphaISA::mode_kernel) { 473 fault(req->vaddr, 474 ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK), 475 req->xc); 476 if (write) { write_acv++; } else { read_acv++; } 477 return Dtb_Acv_Fault; 478 } 479 480 req->flags |= PHYSICAL; 481 } 482 483 if (req->flags & PHYSICAL) { 484 req->paddr = req->vaddr & PA_IMPL_MASK; 485 } else { 486 // not a physical address: need to look up pte 487 488 AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), 489 DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 490 491 if (!pte) { 492 // page fault 493 fault(req->vaddr, 494 ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK), 495 req->xc); 496 if (write) { write_misses++; } else { read_misses++; } 497 return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault; 498 } 499 500 req->paddr = PA_PFN2PA(pte->ppn) | VA_POFS(req->vaddr); 501 502 if (write) { 503 if (!(pte->xwe & MODE2MASK(mode))) { 504 // declare the instruction access fault 505 fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_ACV_MASK | 506 (pte->fonw ? MM_STAT_FONW_MASK : 0), 507 req->xc); 508 write_acv++; 509 return Dtb_Fault_Fault; 510 } 511 if (pte->fonw) { 512 fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_FONW_MASK, 513 req->xc); 514 write_acv++; 515 return Dtb_Fault_Fault; 516 } 517 } else { 518 if (!(pte->xre & MODE2MASK(mode))) { 519 fault(req->vaddr, 520 MM_STAT_ACV_MASK | (pte->fonr ? MM_STAT_FONR_MASK : 0), 521 req->xc); 522 read_acv++; 523 return Dtb_Acv_Fault; 524 } 525 if (pte->fonr) { 526 fault(req->vaddr, MM_STAT_FONR_MASK, req->xc); 527 read_acv++; 528 return Dtb_Fault_Fault; 529 } 530 } 531 } 532 533 checkCacheability(req); 534 535 if (write) 536 write_hits++; 537 else 538 read_hits++; 539 540 return No_Fault; 541} 542 543AlphaISA::PTE & 544AlphaTlb::index() 545{ 546 AlphaISA::PTE *pte = &table[nlu]; 547 nextnlu(); 548 549 return *pte; 550} 551 552BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaItb) 553 554 Param<int> size; 555 556END_DECLARE_SIM_OBJECT_PARAMS(AlphaItb) 557 558BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaItb) 559 560 INIT_PARAM_DFLT(size, "TLB size", 48) 561 562END_INIT_SIM_OBJECT_PARAMS(AlphaItb) 563 564 565CREATE_SIM_OBJECT(AlphaItb) 566{ 567 return new AlphaItb(getInstanceName(), size); 568} 569 570REGISTER_SIM_OBJECT("AlphaITB", AlphaItb) 571 572BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb) 573 574 Param<int> size; 575 576END_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb) 577 578BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDtb) 579 580 INIT_PARAM_DFLT(size, "TLB size", 64) 581 582END_INIT_SIM_OBJECT_PARAMS(AlphaDtb) 583 584 585CREATE_SIM_OBJECT(AlphaDtb) 586{ 587 return new AlphaDtb(getInstanceName(), size); 588} 589 590REGISTER_SIM_OBJECT("AlphaDTB", AlphaDtb) 591 592