tlb.cc revision 828
12SN/A/* 28922Swilliam.wang@arm.com * Copyright (c) 2003 The Regents of The University of Michigan 38707Sandreas.hansson@arm.com * All rights reserved. 48707Sandreas.hansson@arm.com * 58707Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68707Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 78707Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 88707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 98707Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 108707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 118707Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 128707Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 138707Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 141762SN/A * this software without specific prior written permission. 157897Shestness@cs.utexas.edu * 169983Sstever@gmail.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179983Sstever@gmail.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272SN/A */ 282SN/A 292SN/A#include <sstream> 302SN/A#include <string> 312SN/A#include <vector> 322SN/A 332SN/A#include "base/inifile.hh" 342SN/A#include "base/str.hh" 352SN/A#include "base/trace.hh" 362SN/A#include "cpu/exec_context.hh" 372SN/A#include "sim/builder.hh" 382SN/A#include "targetarch/alpha_memory.hh" 392SN/A#include "targetarch/ev5.hh" 402SN/A 412SN/Ausing namespace std; 422665Ssaidi@eecs.umich.edu 432665Ssaidi@eecs.umich.edu/////////////////////////////////////////////////////////////////////// 442665Ssaidi@eecs.umich.edu// 457897Shestness@cs.utexas.edu// Alpha TLB 462SN/A// 472SN/A 481388SN/A#ifdef DEBUG 498229Snate@binkert.org bool uncacheBit39 = false; 502SN/A bool uncacheBit40 = false; 512SN/A#endif 527781SAli.Saidi@ARM.com 538229Snate@binkert.orgAlphaTlb::AlphaTlb(const string &name, int s) 541191SN/A : SimObject(name), size(s), nlu(0) 551191SN/A{ 561388SN/A table = new AlphaISA::PTE[size]; 575529Snate@binkert.org memset(table, 0, sizeof(AlphaISA::PTE[size])); 5810529Smorr@cs.wisc.edu} 591717SN/A 602651Ssaidi@eecs.umich.eduAlphaTlb::~AlphaTlb() 618229Snate@binkert.org{ 622680Sktlim@umich.edu if (table) 6310529Smorr@cs.wisc.edu delete [] table; 648232Snate@binkert.org} 6510529Smorr@cs.wisc.edu 665529Snate@binkert.org// look up an entry in the TLB 678779Sgblack@eecs.umich.eduAlphaISA::PTE * 682190SN/AAlphaTlb::lookup(Addr vpn, uint8_t asn) const 6956SN/A{ 708229Snate@binkert.org DPRINTF(TLB, "lookup %#x\n", vpn); 712190SN/A 722SN/A PageTable::const_iterator i = lookupTable.find(vpn); 732359SN/A if (i == lookupTable.end()) 742359SN/A return NULL; 752359SN/A 762SN/A while (i->first == vpn) { 772SN/A int index = i->second; 782SN/A AlphaISA::PTE *pte = &table[index]; 792SN/A assert(pte->valid); 802SN/A if (vpn == pte->tag && (pte->asma || pte->asn == asn)) 812SN/A return pte; 822SN/A 832SN/A ++i; 842SN/A } 855606Snate@binkert.org 866144Sksewell@umich.edu // not found... 876144Sksewell@umich.edu return NULL; 883126Sktlim@umich.edu} 896144Sksewell@umich.edu 907823Ssteve.reinhardt@amd.com 913126Sktlim@umich.eduvoid 923126Sktlim@umich.eduAlphaTlb::checkCacheability(MemReqPtr &req) 932356SN/A{ 942356SN/A // in Alpha, cacheability is controlled by upper-level bits of the 952356SN/A // physical address 968834Satgutier@umich.edu 9710786Smalek.musleh@gmail.com /* 9810786Smalek.musleh@gmail.com * We support having the uncacheable bit in either bit 39 or bit 40. 9910786Smalek.musleh@gmail.com * The Turbolaser platform (and EV5) support having the bit in 39, but 10010786Smalek.musleh@gmail.com * Tsunami (which Linux assumes uses an EV6) generates accesses with 10110786Smalek.musleh@gmail.com * the bit in 40. So we must check for both, but we have debug flags 10210786Smalek.musleh@gmail.com * to catch a weird case where both are used, which shouldn't happen. 10310786Smalek.musleh@gmail.com */ 10410786Smalek.musleh@gmail.com 1052356SN/A if (req->paddr & PA_UNCACHED_BIT_40 || 1069179Sandreas.hansson@arm.com req->paddr & PA_UNCACHED_BIT_39) { 1072367SN/A 1086144Sksewell@umich.edu#ifdef DEBUG 1096144Sksewell@umich.edu if (req->paddr & PA_UNCACHED_BIT_40) { 1106144Sksewell@umich.edu if(uncacheBit39) 1112356SN/A panic("Bit 40 access follows bit 39 access, PA=%x\n", 1122367SN/A req->paddr); 1136144Sksewell@umich.edu 1147823Ssteve.reinhardt@amd.com uncacheBit40 = true; 1156144Sksewell@umich.edu } else if (req->paddr & PA_UNCACHED_BIT_39) { 1162367SN/A if(uncacheBit40) 1172356SN/A panic("Bit 39 acceess follows bit 40 access, PA=%x\n", 1182356SN/A req->paddr); 1192356SN/A 1202356SN/A uncacheBit39 = true; 1215336Shines@cs.fsu.edu } 1222356SN/A#endif 1234873Sstever@eecs.umich.edu 1242356SN/A // IPR memory space not implemented 1252356SN/A if (PA_IPR_SPACE(req->paddr)) 1268876Sandreas.hansson@arm.com if (!req->xc->misspeculating()) 12710190Sakash.bagdia@arm.com panic("IPR memory space not implemented! PA=%x\n", 1288832SAli.Saidi@ARM.com req->paddr); 1298832SAli.Saidi@ARM.com 1309332Sdam.sunwoo@arm.com // mark request as uncacheable 1319814Sandreas.hansson@arm.com req->flags |= UNCACHEABLE; 1329220Shestness@cs.wisc.edu } 13310529Smorr@cs.wisc.edu} 13410537Sandreas.hansson@arm.com 13510537Sandreas.hansson@arm.com 13610529Smorr@cs.wisc.edu// insert a new TLB entry 1372SN/Avoid 1385712Shsul@eecs.umich.eduAlphaTlb::insert(Addr vaddr, AlphaISA::PTE &pte) 1395712Shsul@eecs.umich.edu{ 1405712Shsul@eecs.umich.edu if (table[nlu].valid) { 1415712Shsul@eecs.umich.edu Addr oldvpn = table[nlu].tag; 1425712Shsul@eecs.umich.edu PageTable::iterator i = lookupTable.find(oldvpn); 1432SN/A 1442SN/A if (i == lookupTable.end()) 1452SN/A panic("TLB entry not found in lookupTable"); 14610190Sakash.bagdia@arm.com 14710190Sakash.bagdia@arm.com int index; 1485712Shsul@eecs.umich.edu while ((index = i->second) != nlu) { 1496221Snate@binkert.org if (table[index].tag != oldvpn) 1506221Snate@binkert.org panic("TLB entry not found in lookupTable"); 1512SN/A 1522SN/A ++i; 1536221Snate@binkert.org } 1546221Snate@binkert.org 1556221Snate@binkert.org DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); 1566221Snate@binkert.org 1572SN/A lookupTable.erase(i); 1582SN/A } 1592SN/A 1602SN/A Addr vpn = VA_VPN(vaddr); 1615606Snate@binkert.org DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vpn, pte.ppn); 1625606Snate@binkert.org 1639749Sandreas@sandberg.pp.se table[nlu] = pte; 1649749Sandreas@sandberg.pp.se table[nlu].tag = vpn; 1655606Snate@binkert.org table[nlu].valid = true; 1662SN/A 1679647Sdam.sunwoo@arm.com lookupTable.insert(make_pair(vpn, nlu)); 1689647Sdam.sunwoo@arm.com nextnlu(); 1699647Sdam.sunwoo@arm.com} 1709647Sdam.sunwoo@arm.com 1719647Sdam.sunwoo@arm.comvoid 1729647Sdam.sunwoo@arm.comAlphaTlb::flushAll() 1739749Sandreas@sandberg.pp.se{ 1749749Sandreas@sandberg.pp.se memset(table, 0, sizeof(AlphaISA::PTE[size])); 1759647Sdam.sunwoo@arm.com lookupTable.clear(); 1769647Sdam.sunwoo@arm.com nlu = 0; 1771400SN/A} 1785606Snate@binkert.org 1795606Snate@binkert.orgvoid 1802SN/AAlphaTlb::flushProcesses() 1812SN/A{ 1822SN/A PageTable::iterator i = lookupTable.begin(); 1832SN/A PageTable::iterator end = lookupTable.end(); 1846221Snate@binkert.org while (i != end) { 1856221Snate@binkert.org int index = i->second; 1865606Snate@binkert.org AlphaISA::PTE *pte = &table[index]; 1876670Shsul@eecs.umich.edu assert(pte->valid); 1885606Snate@binkert.org 1892SN/A if (!pte->asma) { 1902SN/A DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); 191124SN/A pte->valid = false; 1926221Snate@binkert.org lookupTable.erase(i); 1936221Snate@binkert.org } 1946221Snate@binkert.org 195124SN/A ++i; 196124SN/A } 197124SN/A} 198124SN/A 1995606Snate@binkert.orgvoid 2005606Snate@binkert.orgAlphaTlb::flushAddr(Addr vaddr, uint8_t asn) 2019749Sandreas@sandberg.pp.se{ 2029749Sandreas@sandberg.pp.se Addr vpn = VA_VPN(vaddr); 2035606Snate@binkert.org 204124SN/A PageTable::iterator i = lookupTable.find(vpn); 2051400SN/A if (i == lookupTable.end()) 2065606Snate@binkert.org return; 207124SN/A 208124SN/A while (i->first == vpn) { 209124SN/A int index = i->second; 210124SN/A AlphaISA::PTE *pte = &table[index]; 2116221Snate@binkert.org assert(pte->valid); 2126221Snate@binkert.org 2135606Snate@binkert.org if (vpn == pte->tag && (pte->asma || pte->asn == asn)) { 2146221Snate@binkert.org DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vpn, pte->ppn); 2155606Snate@binkert.org 216124SN/A // invalidate this entry 217124SN/A pte->valid = false; 2181191SN/A 2195529Snate@binkert.org lookupTable.erase(i); 2208634Schris.emmons@arm.com } 2218634Schris.emmons@arm.com 2228634Schris.emmons@arm.com ++i; 2238634Schris.emmons@arm.com } 2248634Schris.emmons@arm.com} 2251191SN/A 2265529Snate@binkert.org 2271191SN/Avoid 2285529Snate@binkert.orgAlphaTlb::serialize(ostream &os) 2291191SN/A{ 2301191SN/A SERIALIZE_SCALAR(size); 2315606Snate@binkert.org SERIALIZE_SCALAR(nlu); 2325606Snate@binkert.org 2335606Snate@binkert.org for (int i = 0; i < size; i++) { 2341191SN/A nameOut(os, csprintf("%s.PTE%d", name(), i)); 2351191SN/A table[i].serialize(os); 2368876Sandreas.hansson@arm.com } 2378876Sandreas.hansson@arm.com} 2388876Sandreas.hansson@arm.com 2399433SAndreas.Sandberg@ARM.comvoid 2408876Sandreas.hansson@arm.comAlphaTlb::unserialize(Checkpoint *cp, const string §ion) 2418876Sandreas.hansson@arm.com{ 2428876Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(size); 2438876Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(nlu); 2448876Sandreas.hansson@arm.com 2458876Sandreas.hansson@arm.com for (int i = 0; i < size; i++) { 2468876Sandreas.hansson@arm.com table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); 2475810Sgblack@eecs.umich.edu if (table[i].valid) { 2488779Sgblack@eecs.umich.edu lookupTable.insert(make_pair(table[i].tag, i)); 2498779Sgblack@eecs.umich.edu } 2508779Sgblack@eecs.umich.edu } 2518779Sgblack@eecs.umich.edu} 2525529Snate@binkert.org 2539384SAndreas.Sandberg@arm.com 2549384SAndreas.Sandberg@arm.com/////////////////////////////////////////////////////////////////////// 2559384SAndreas.Sandberg@arm.com// 2569384SAndreas.Sandberg@arm.com// Alpha ITB 2579384SAndreas.Sandberg@arm.com// 2581917SN/AAlphaItb::AlphaItb(const std::string &name, int size) 2591191SN/A : AlphaTlb(name, size) 2601191SN/A{} 2611191SN/A 2621191SN/A 2631191SN/Avoid 2641191SN/AAlphaItb::regStats() 2651191SN/A{ 2661191SN/A hits 2671191SN/A .name(name() + ".hits") 2689086Sandreas.hansson@arm.com .desc("ITB hits"); 2699086Sandreas.hansson@arm.com misses 2709086Sandreas.hansson@arm.com .name(name() + ".misses") 2711191SN/A .desc("ITB misses"); 2721191SN/A acv 2731129SN/A .name(name() + ".acv") 27410529Smorr@cs.wisc.edu .desc("ITB acv"); 27510529Smorr@cs.wisc.edu accesses 27610529Smorr@cs.wisc.edu .name(name() + ".accesses") 27710529Smorr@cs.wisc.edu .desc("ITB accesses"); 27810529Smorr@cs.wisc.edu 27910529Smorr@cs.wisc.edu accesses = hits + misses; 28010529Smorr@cs.wisc.edu} 28110529Smorr@cs.wisc.edu 28210529Smorr@cs.wisc.eduvoid 28310529Smorr@cs.wisc.eduAlphaItb::fault(Addr pc, ExecContext *xc) const 28410529Smorr@cs.wisc.edu{ 28510529Smorr@cs.wisc.edu uint64_t *ipr = xc->regs.ipr; 28610529Smorr@cs.wisc.edu 28710529Smorr@cs.wisc.edu if (!xc->misspeculating()) { 28810529Smorr@cs.wisc.edu ipr[AlphaISA::IPR_ITB_TAG] = pc; 28910529Smorr@cs.wisc.edu ipr[AlphaISA::IPR_IFAULT_VA_FORM] = 29010529Smorr@cs.wisc.edu ipr[AlphaISA::IPR_IVPTBR] | (VA_VPN(pc) << 3); 29110529Smorr@cs.wisc.edu } 29210529Smorr@cs.wisc.edu} 29310529Smorr@cs.wisc.edu 29410529Smorr@cs.wisc.edu 29510529Smorr@cs.wisc.eduFault 29610529Smorr@cs.wisc.eduAlphaItb::translate(MemReqPtr &req) const 29710529Smorr@cs.wisc.edu{ 29810529Smorr@cs.wisc.edu InternalProcReg *ipr = req->xc->regs.ipr; 29910529Smorr@cs.wisc.edu 30010529Smorr@cs.wisc.edu if (PC_PAL(req->vaddr)) { 30110529Smorr@cs.wisc.edu // strip off PAL PC marker (lsb is 1) 30210529Smorr@cs.wisc.edu req->paddr = (req->vaddr & ~3) & PA_IMPL_MASK; 30310529Smorr@cs.wisc.edu hits++; 30410529Smorr@cs.wisc.edu return No_Fault; 30510529Smorr@cs.wisc.edu } 30610529Smorr@cs.wisc.edu 30710529Smorr@cs.wisc.edu if (req->flags & PHYSICAL) { 30810529Smorr@cs.wisc.edu req->paddr = req->vaddr; 30910529Smorr@cs.wisc.edu } else { 31010529Smorr@cs.wisc.edu // verify that this is a good virtual address 31110529Smorr@cs.wisc.edu if (!validVirtualAddress(req->vaddr)) { 31210529Smorr@cs.wisc.edu fault(req->vaddr, req->xc); 31310529Smorr@cs.wisc.edu acv++; 31410529Smorr@cs.wisc.edu return Itb_Acv_Fault; 31510529Smorr@cs.wisc.edu } 31610529Smorr@cs.wisc.edu 31710529Smorr@cs.wisc.edu // Check for "superpage" mapping: when SP<1> is set, and 31810529Smorr@cs.wisc.edu // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. 31910529Smorr@cs.wisc.edu if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && 32010529Smorr@cs.wisc.edu VA_SPACE(req->vaddr) == 2) { 32110529Smorr@cs.wisc.edu 32210529Smorr@cs.wisc.edu // only valid in kernel mode 32310529Smorr@cs.wisc.edu if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) { 32410529Smorr@cs.wisc.edu fault(req->vaddr, req->xc); 32510529Smorr@cs.wisc.edu acv++; 32610529Smorr@cs.wisc.edu return Itb_Acv_Fault; 32710529Smorr@cs.wisc.edu } 32810529Smorr@cs.wisc.edu 32910529Smorr@cs.wisc.edu req->paddr = req->vaddr & PA_IMPL_MASK; 33010529Smorr@cs.wisc.edu 3311129SN/A // sign extend the physical address properly 3321129SN/A if (req->paddr & PA_UNCACHED_BIT_39 || 3339523SAndreas.Sandberg@ARM.com req->paddr & PA_UNCACHED_BIT_40) 3342680Sktlim@umich.edu req->paddr |= 0xf0000000000; 3359523SAndreas.Sandberg@ARM.com else 3369523SAndreas.Sandberg@ARM.com req->paddr &= 0xffffffffff; 3379523SAndreas.Sandberg@ARM.com 3381129SN/A } else { 339180SN/A // not a physical address: need to look up pte 3402SN/A AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), 3411917SN/A DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 3421917SN/A 3438779Sgblack@eecs.umich.edu if (!pte) { 3449433SAndreas.Sandberg@ARM.com fault(req->vaddr, req->xc); 3458779Sgblack@eecs.umich.edu misses++; 3468779Sgblack@eecs.umich.edu return Itb_Fault_Fault; 3472356SN/A } 3485529Snate@binkert.org 3499179Sandreas.hansson@arm.com req->paddr = PA_PFN2PA(pte->ppn) + VA_POFS(req->vaddr & ~3); 3502356SN/A 3511917SN/A // check permissions for this access 3521917SN/A if (!(pte->xre & (1 << ICM_CM(ipr[AlphaISA::IPR_ICM])))) { 35310464SAndreas.Sandberg@ARM.com // instruction access fault 35410464SAndreas.Sandberg@ARM.com fault(req->vaddr, req->xc); 35510464SAndreas.Sandberg@ARM.com acv++; 35610464SAndreas.Sandberg@ARM.com return Itb_Acv_Fault; 35710464SAndreas.Sandberg@ARM.com } 35810464SAndreas.Sandberg@ARM.com 35910464SAndreas.Sandberg@ARM.com hits++; 36010464SAndreas.Sandberg@ARM.com } 36110464SAndreas.Sandberg@ARM.com } 36210464SAndreas.Sandberg@ARM.com 36310464SAndreas.Sandberg@ARM.com // check that the physical address is ok (catch bad physical addresses) 36410464SAndreas.Sandberg@ARM.com if (req->paddr & ~PA_IMPL_MASK) 36510464SAndreas.Sandberg@ARM.com return Machine_Check_Fault; 36610464SAndreas.Sandberg@ARM.com 36710464SAndreas.Sandberg@ARM.com checkCacheability(req); 36810464SAndreas.Sandberg@ARM.com 36910464SAndreas.Sandberg@ARM.com return No_Fault; 37010464SAndreas.Sandberg@ARM.com} 37110464SAndreas.Sandberg@ARM.com 37210464SAndreas.Sandberg@ARM.com/////////////////////////////////////////////////////////////////////// 37310464SAndreas.Sandberg@ARM.com// 37410464SAndreas.Sandberg@ARM.com// Alpha DTB 37510464SAndreas.Sandberg@ARM.com// 37610464SAndreas.Sandberg@ARM.comAlphaDtb::AlphaDtb(const std::string &name, int size) 37710464SAndreas.Sandberg@ARM.com : AlphaTlb(name, size) 37810464SAndreas.Sandberg@ARM.com{} 37910464SAndreas.Sandberg@ARM.com 38010464SAndreas.Sandberg@ARM.comvoid 38110464SAndreas.Sandberg@ARM.comAlphaDtb::regStats() 38210464SAndreas.Sandberg@ARM.com{ 38310464SAndreas.Sandberg@ARM.com read_hits 38410643Snikos.nikoleris@gmail.com .name(name() + ".read_hits") 38510464SAndreas.Sandberg@ARM.com .desc("DTB read hits") 38610464SAndreas.Sandberg@ARM.com ; 38710464SAndreas.Sandberg@ARM.com 38810464SAndreas.Sandberg@ARM.com read_misses 3891917SN/A .name(name() + ".read_misses") 3901917SN/A .desc("DTB read misses") 3912SN/A ; 3922SN/A 393729SN/A read_acv 394707SN/A .name(name() + ".read_acv") 395707SN/A .desc("DTB read access violations") 396707SN/A ; 397707SN/A 398707SN/A read_accesses 399707SN/A .name(name() + ".read_accesses") 4007914SBrad.Beckmann@amd.com .desc("DTB read accesses") 4017914SBrad.Beckmann@amd.com ; 4027914SBrad.Beckmann@amd.com 4037914SBrad.Beckmann@amd.com write_hits 4047914SBrad.Beckmann@amd.com .name(name() + ".write_hits") 4057914SBrad.Beckmann@amd.com .desc("DTB write hits") 4067914SBrad.Beckmann@amd.com ; 4077914SBrad.Beckmann@amd.com 4087914SBrad.Beckmann@amd.com write_misses 4097914SBrad.Beckmann@amd.com .name(name() + ".write_misses") 4102680Sktlim@umich.edu .desc("DTB write misses") 4112SN/A ; 4122SN/A 4132SN/A write_acv 4142SN/A .name(name() + ".write_acv") 4152680Sktlim@umich.edu .desc("DTB write access violations") 4162SN/A ; 4172SN/A 4182680Sktlim@umich.edu write_accesses 4192SN/A .name(name() + ".write_accesses") 4202SN/A .desc("DTB write accesses") 4219294Sandreas.hansson@arm.com ; 4229294Sandreas.hansson@arm.com 4238850Sandreas.hansson@arm.com hits 4248850Sandreas.hansson@arm.com .name(name() + ".hits") 4258850Sandreas.hansson@arm.com .desc("DTB hits") 4268850Sandreas.hansson@arm.com ; 4279608Sandreas.hansson@arm.com 4288850Sandreas.hansson@arm.com misses 4298922Swilliam.wang@arm.com .name(name() + ".misses") 4308850Sandreas.hansson@arm.com .desc("DTB misses") 4318922Swilliam.wang@arm.com ; 4328850Sandreas.hansson@arm.com 4338922Swilliam.wang@arm.com acv 4348850Sandreas.hansson@arm.com .name(name() + ".acv") 4358850Sandreas.hansson@arm.com .desc("DTB access violations") 436180SN/A ; 4372680Sktlim@umich.edu 438180SN/A accesses 4396221Snate@binkert.org .name(name() + ".accesses") 4406221Snate@binkert.org .desc("DTB accesses") 4416221Snate@binkert.org ; 4422378SN/A 4435718Shsul@eecs.umich.edu hits = read_hits + write_hits; 4445718Shsul@eecs.umich.edu misses = read_misses + write_misses; 4455718Shsul@eecs.umich.edu acv = read_acv + write_acv; 4465718Shsul@eecs.umich.edu accesses = read_accesses + write_accesses; 4475718Shsul@eecs.umich.edu} 4485718Shsul@eecs.umich.edu 4495718Shsul@eecs.umich.eduvoid 4506221Snate@binkert.orgAlphaDtb::fault(Addr vaddr, uint64_t flags, ExecContext *xc) const 4515718Shsul@eecs.umich.edu{ 4525718Shsul@eecs.umich.edu uint64_t *ipr = xc->regs.ipr; 4535718Shsul@eecs.umich.edu 4548779Sgblack@eecs.umich.edu // set fault address and flags 4558779Sgblack@eecs.umich.edu if (!xc->misspeculating() && !xc->regs.intrlock) { 4568779Sgblack@eecs.umich.edu // set VA register with faulting address 457180SN/A ipr[AlphaISA::IPR_VA] = vaddr; 458180SN/A 459180SN/A // set MM_STAT register flags 460180SN/A ipr[AlphaISA::IPR_MM_STAT] = (((xc->regs.opcode & 0x3f) << 11) 4614000Ssaidi@eecs.umich.edu | ((xc->regs.ra & 0x1f) << 6) 4624000Ssaidi@eecs.umich.edu | (flags & 0x3f)); 4634000Ssaidi@eecs.umich.edu 4646221Snate@binkert.org // set VA_FORM register with faulting formatted address 4656221Snate@binkert.org ipr[AlphaISA::IPR_VA_FORM] = 4666221Snate@binkert.org ipr[AlphaISA::IPR_MVPTBR] | (VA_VPN(vaddr) << 3); 4676221Snate@binkert.org 4684000Ssaidi@eecs.umich.edu // lock these registers until the VA register is read 4694000Ssaidi@eecs.umich.edu xc->regs.intrlock = true; 4704000Ssaidi@eecs.umich.edu } 4714000Ssaidi@eecs.umich.edu} 472180SN/A 4732798Sktlim@umich.eduFault 474180SN/AAlphaDtb::translate(MemReqPtr &req, bool write) const 4759430SAndreas.Sandberg@ARM.com{ 4769430SAndreas.Sandberg@ARM.com RegFile *regs = &req->xc->regs; 4772359SN/A Addr pc = regs->pc; 4785606Snate@binkert.org InternalProcReg *ipr = regs->ipr; 4799446SAndreas.Sandberg@ARM.com 4809446SAndreas.Sandberg@ARM.com AlphaISA::mode_type mode = 4819446SAndreas.Sandberg@ARM.com (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]); 4829446SAndreas.Sandberg@ARM.com 483180SN/A if (PC_PAL(pc)) { 484180SN/A mode = (req->flags & ALTMODE) ? 485180SN/A (AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE]) 4868737Skoansin.tan@gmail.com : AlphaISA::mode_kernel; 487180SN/A } 4882680Sktlim@umich.edu 4899152Satgutier@umich.edu if (req->flags & PHYSICAL) { 4909430SAndreas.Sandberg@ARM.com req->paddr = req->vaddr; 4919430SAndreas.Sandberg@ARM.com } else { 4929332Sdam.sunwoo@arm.com // verify that this is a good virtual address 4939332Sdam.sunwoo@arm.com if (!validVirtualAddress(req->vaddr)) { 4949430SAndreas.Sandberg@ARM.com fault(req->vaddr, 4955712Shsul@eecs.umich.edu ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | 4966221Snate@binkert.org MM_STAT_ACV_MASK), 4976221Snate@binkert.org req->xc); 4982680Sktlim@umich.edu 4992680Sktlim@umich.edu if (write) { write_acv++; } else { read_acv++; } 500180SN/A return Dtb_Fault_Fault; 5012680Sktlim@umich.edu } 5022651Ssaidi@eecs.umich.edu 5032680Sktlim@umich.edu // Check for "superpage" mapping: when SP<1> is set, and 5042651Ssaidi@eecs.umich.edu // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. 5055714Shsul@eecs.umich.edu if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && 5065715Shsul@eecs.umich.edu VA_SPACE(req->vaddr) == 2) { 5075714Shsul@eecs.umich.edu 5082359SN/A // only valid in kernel mode 5095875Ssteve.reinhardt@amd.com if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != 5105875Ssteve.reinhardt@amd.com AlphaISA::mode_kernel) { 5115875Ssteve.reinhardt@amd.com fault(req->vaddr, 5125875Ssteve.reinhardt@amd.com ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK), 5135217Ssaidi@eecs.umich.edu req->xc); 5145875Ssteve.reinhardt@amd.com if (write) { write_acv++; } else { read_acv++; } 5157781SAli.Saidi@ARM.com return Dtb_Acv_Fault; 5169294Sandreas.hansson@arm.com } 5179294Sandreas.hansson@arm.com 5189294Sandreas.hansson@arm.com req->paddr = req->vaddr & PA_IMPL_MASK; 5199294Sandreas.hansson@arm.com 5207781SAli.Saidi@ARM.com // sign extend the physical address properly 5217781SAli.Saidi@ARM.com if (req->paddr & PA_UNCACHED_BIT_39 || 5229178Sandreas.hansson@arm.com req->paddr & PA_UNCACHED_BIT_40) 5239178Sandreas.hansson@arm.com req->paddr |= 0xf0000000000; 5247781SAli.Saidi@ARM.com else 5259178Sandreas.hansson@arm.com req->paddr &= 0xffffffffff; 5269294Sandreas.hansson@arm.com 5279178Sandreas.hansson@arm.com } else { 5288922Swilliam.wang@arm.com if (write) 5297781SAli.Saidi@ARM.com write_accesses++; 5309178Sandreas.hansson@arm.com else 5319178Sandreas.hansson@arm.com read_accesses++; 5327781SAli.Saidi@ARM.com 5339178Sandreas.hansson@arm.com // not a physical address: need to look up pte 5349294Sandreas.hansson@arm.com AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), 5359178Sandreas.hansson@arm.com DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 5368922Swilliam.wang@arm.com 5377781SAli.Saidi@ARM.com if (!pte) { 53810194SGeoffrey.Blake@arm.com // page fault 53910194SGeoffrey.Blake@arm.com fault(req->vaddr, 5408733Sgeoffrey.blake@arm.com ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK), 5418887Sgeoffrey.blake@arm.com req->xc); 5428887Sgeoffrey.blake@arm.com if (write) { write_misses++; } else { read_misses++; } 5438887Sgeoffrey.blake@arm.com return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault; 5448887Sgeoffrey.blake@arm.com } 5458887Sgeoffrey.blake@arm.com 5469294Sandreas.hansson@arm.com req->paddr = PA_PFN2PA(pte->ppn) | VA_POFS(req->vaddr); 5478922Swilliam.wang@arm.com 5489294Sandreas.hansson@arm.com if (write) { 5498922Swilliam.wang@arm.com if (!(pte->xwe & MODE2MASK(mode))) { 5509294Sandreas.hansson@arm.com // declare the instruction access fault 5518922Swilliam.wang@arm.com fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_ACV_MASK | 5529294Sandreas.hansson@arm.com (pte->fonw ? MM_STAT_FONW_MASK : 0), 5538922Swilliam.wang@arm.com req->xc); 5548733Sgeoffrey.blake@arm.com write_acv++; 55510194SGeoffrey.Blake@arm.com return Dtb_Fault_Fault; 55610194SGeoffrey.Blake@arm.com } 55710194SGeoffrey.Blake@arm.com if (pte->fonw) { 5588887Sgeoffrey.blake@arm.com fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_FONW_MASK, 5599178Sandreas.hansson@arm.com req->xc); 5609178Sandreas.hansson@arm.com write_acv++; 5618887Sgeoffrey.blake@arm.com return Dtb_Fault_Fault; 5629178Sandreas.hansson@arm.com } 5639294Sandreas.hansson@arm.com } else { 5649294Sandreas.hansson@arm.com if (!(pte->xre & MODE2MASK(mode))) { 5659178Sandreas.hansson@arm.com fault(req->vaddr, 5668922Swilliam.wang@arm.com MM_STAT_ACV_MASK | 5678887Sgeoffrey.blake@arm.com (pte->fonr ? MM_STAT_FONR_MASK : 0), 5689178Sandreas.hansson@arm.com req->xc); 5699178Sandreas.hansson@arm.com read_acv++; 5708887Sgeoffrey.blake@arm.com return Dtb_Acv_Fault; 5719178Sandreas.hansson@arm.com } 5729294Sandreas.hansson@arm.com if (pte->fonr) { 5739294Sandreas.hansson@arm.com fault(req->vaddr, MM_STAT_FONR_MASK, req->xc); 5749178Sandreas.hansson@arm.com read_acv++; 5758922Swilliam.wang@arm.com return Dtb_Fault_Fault; 5768887Sgeoffrey.blake@arm.com } 5778733Sgeoffrey.blake@arm.com } 578180SN/A } 579605SN/A 5803520Sgblack@eecs.umich.edu if (write) 5815810Sgblack@eecs.umich.edu write_hits++; 5829152Satgutier@umich.edu else 5832254SN/A read_hits++; 5848779Sgblack@eecs.umich.edu } 5858779Sgblack@eecs.umich.edu 5868779Sgblack@eecs.umich.edu // check that the physical address is ok (catch bad physical addresses) 5872254SN/A if (req->paddr & ~PA_IMPL_MASK) 5888779Sgblack@eecs.umich.edu return Machine_Check_Fault; 5898779Sgblack@eecs.umich.edu 5908779Sgblack@eecs.umich.edu checkCacheability(req); 5914192Sktlim@umich.edu 5929178Sandreas.hansson@arm.com return No_Fault; 5939178Sandreas.hansson@arm.com} 5949178Sandreas.hansson@arm.com 5959178Sandreas.hansson@arm.comAlphaISA::PTE & 5969178Sandreas.hansson@arm.comAlphaTlb::index(bool advance) 5979178Sandreas.hansson@arm.com{ 5989294Sandreas.hansson@arm.com AlphaISA::PTE *pte = &table[nlu]; 5999178Sandreas.hansson@arm.com 6009178Sandreas.hansson@arm.com if (advance) 6014192Sktlim@umich.edu nextnlu(); 6029178Sandreas.hansson@arm.com 6039178Sandreas.hansson@arm.com return *pte; 6049294Sandreas.hansson@arm.com} 6059178Sandreas.hansson@arm.com 6069178Sandreas.hansson@arm.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaItb) 607180SN/A 608180SN/A Param<int> size; 6099446SAndreas.Sandberg@ARM.com 6109446SAndreas.Sandberg@ARM.comEND_DECLARE_SIM_OBJECT_PARAMS(AlphaItb) 6119446SAndreas.Sandberg@ARM.com 6129446SAndreas.Sandberg@ARM.comBEGIN_INIT_SIM_OBJECT_PARAMS(AlphaItb) 6139446SAndreas.Sandberg@ARM.com 6149446SAndreas.Sandberg@ARM.com INIT_PARAM_DFLT(size, "TLB size", 48) 6159446SAndreas.Sandberg@ARM.com 6169446SAndreas.Sandberg@ARM.comEND_INIT_SIM_OBJECT_PARAMS(AlphaItb) 6179446SAndreas.Sandberg@ARM.com 6189446SAndreas.Sandberg@ARM.com 6199446SAndreas.Sandberg@ARM.comCREATE_SIM_OBJECT(AlphaItb) 6209446SAndreas.Sandberg@ARM.com{ 6219446SAndreas.Sandberg@ARM.com return new AlphaItb(getInstanceName(), size); 6229446SAndreas.Sandberg@ARM.com} 6239446SAndreas.Sandberg@ARM.com 6249446SAndreas.Sandberg@ARM.comREGISTER_SIM_OBJECT("AlphaITB", AlphaItb) 625180SN/A 6265536Srstrong@hp.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb) 6275606Snate@binkert.org 6281917SN/A Param<int> size; 6291917SN/A 6301917SN/AEND_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb) 6311917SN/A 6321917SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDtb) 6336221Snate@binkert.org 6346221Snate@binkert.org INIT_PARAM_DFLT(size, "TLB size", 64) 6352680Sktlim@umich.edu 6362680Sktlim@umich.eduEND_INIT_SIM_OBJECT_PARAMS(AlphaDtb) 6371917SN/A 6382254SN/A 6397823Ssteve.reinhardt@amd.comCREATE_SIM_OBJECT(AlphaDtb) 6401917SN/A{ 6411917SN/A return new AlphaDtb(getInstanceName(), size); 6422SN/A} 643921SN/A 644921SN/AREGISTER_SIM_OBJECT("AlphaDTB", AlphaDtb) 6454000Ssaidi@eecs.umich.edu 6469332Sdam.sunwoo@arm.com