tlb.cc revision 533
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/AAlphaTlb::AlphaTlb(const string &name, int s) 481388SN/A : SimObject(name), size(s), nlu(0) 498229Snate@binkert.org{ 502SN/A table = new AlphaISA::PTE[size]; 512SN/A memset(table, 0, sizeof(AlphaISA::PTE[size])); 527781SAli.Saidi@ARM.com} 538229Snate@binkert.org 541191SN/AAlphaTlb::~AlphaTlb() 551191SN/A{ 561388SN/A if (table) 575529Snate@binkert.org delete [] table; 5810529Smorr@cs.wisc.edu} 591717SN/A 602651Ssaidi@eecs.umich.edu// look up an entry in the TLB 618229Snate@binkert.orgAlphaISA::PTE * 622680Sktlim@umich.eduAlphaTlb::lookup(Addr vpn, uint8_t asn) const 6310529Smorr@cs.wisc.edu{ 648232Snate@binkert.org DPRINTF(TLB, "lookup %#x\n", vpn); 6510529Smorr@cs.wisc.edu 665529Snate@binkert.org PageTable::const_iterator i = lookupTable.find(vpn); 678779Sgblack@eecs.umich.edu if (i == lookupTable.end()) 682190SN/A return NULL; 6956SN/A 708229Snate@binkert.org while (i->first == vpn) { 712190SN/A int index = i->second; 722SN/A AlphaISA::PTE *pte = &table[index]; 732359SN/A assert(pte->valid); 742359SN/A if (vpn == pte->tag && (pte->asma || pte->asn == asn)) 752359SN/A return pte; 762SN/A 772SN/A ++i; 782SN/A } 792SN/A 802SN/A // not found... 812SN/A return NULL; 822SN/A} 832SN/A 842SN/A 855606Snate@binkert.orgvoid 866144Sksewell@umich.eduAlphaTlb::checkCacheability(MemReqPtr &req) 876144Sksewell@umich.edu{ 883126Sktlim@umich.edu // in Alpha, cacheability is controlled by upper-level bits of the 896144Sksewell@umich.edu // physical address 907823Ssteve.reinhardt@amd.com if (req->paddr & PA_UNCACHED_BIT) { 913126Sktlim@umich.edu if (PA_IPR_SPACE(req->paddr)) { 923126Sktlim@umich.edu // IPR memory space not implemented 932356SN/A if (!req->xc->misspeculating()) { 942356SN/A switch (req->paddr) { 952356SN/A case 0xFFFFF00188: 968834Satgutier@umich.edu req->data = 0; 9710786Smalek.musleh@gmail.com break; 9810786Smalek.musleh@gmail.com 9910786Smalek.musleh@gmail.com default: 10010786Smalek.musleh@gmail.com panic("IPR memory space not implemented! PA=%x\n", 10110786Smalek.musleh@gmail.com req->paddr); 10210786Smalek.musleh@gmail.com } 10310786Smalek.musleh@gmail.com } 10410786Smalek.musleh@gmail.com } else { 1052356SN/A // mark request as uncacheable 1069179Sandreas.hansson@arm.com req->flags |= UNCACHEABLE; 1072367SN/A } 1086144Sksewell@umich.edu } 1096144Sksewell@umich.edu} 1106144Sksewell@umich.edu 1112356SN/A 1122367SN/A// insert a new TLB entry 1136144Sksewell@umich.eduvoid 1147823Ssteve.reinhardt@amd.comAlphaTlb::insert(Addr vaddr, AlphaISA::PTE &pte) 1156144Sksewell@umich.edu{ 1162367SN/A if (table[nlu].valid) { 1172356SN/A Addr oldvpn = table[nlu].tag; 1182356SN/A PageTable::iterator i = lookupTable.find(oldvpn); 1192356SN/A 1202356SN/A if (i == lookupTable.end()) 1215336Shines@cs.fsu.edu panic("TLB entry not found in lookupTable"); 1222356SN/A 1234873Sstever@eecs.umich.edu int index; 1242356SN/A while ((index = i->second) != nlu) { 1252356SN/A if (table[index].tag != oldvpn) 1268876Sandreas.hansson@arm.com panic("TLB entry not found in lookupTable"); 12710190Sakash.bagdia@arm.com 1288832SAli.Saidi@ARM.com ++i; 1298832SAli.Saidi@ARM.com } 1309332Sdam.sunwoo@arm.com 1319814Sandreas.hansson@arm.com DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); 1329220Shestness@cs.wisc.edu 13310529Smorr@cs.wisc.edu lookupTable.erase(i); 13410537Sandreas.hansson@arm.com } 13510537Sandreas.hansson@arm.com 13610529Smorr@cs.wisc.edu Addr vpn = VA_VPN(vaddr); 1372SN/A DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vpn, pte.ppn); 1385712Shsul@eecs.umich.edu 1395712Shsul@eecs.umich.edu table[nlu] = pte; 1405712Shsul@eecs.umich.edu table[nlu].tag = vpn; 1415712Shsul@eecs.umich.edu table[nlu].valid = true; 1425712Shsul@eecs.umich.edu 1432SN/A lookupTable.insert(make_pair(vpn, nlu)); 1442SN/A nextnlu(); 1452SN/A} 14610190Sakash.bagdia@arm.com 14710190Sakash.bagdia@arm.comvoid 1485712Shsul@eecs.umich.eduAlphaTlb::flushAll() 1496221Snate@binkert.org{ 1506221Snate@binkert.org memset(table, 0, sizeof(AlphaISA::PTE[size])); 1512SN/A lookupTable.clear(); 1522SN/A nlu = 0; 1536221Snate@binkert.org} 1546221Snate@binkert.org 1556221Snate@binkert.orgvoid 1566221Snate@binkert.orgAlphaTlb::flushProcesses() 1572SN/A{ 1582SN/A PageTable::iterator i = lookupTable.begin(); 1592SN/A PageTable::iterator end = lookupTable.end(); 1602SN/A while (i != end) { 1615606Snate@binkert.org int index = i->second; 1625606Snate@binkert.org AlphaISA::PTE *pte = &table[index]; 1639749Sandreas@sandberg.pp.se assert(pte->valid); 1649749Sandreas@sandberg.pp.se 1655606Snate@binkert.org if (!pte->asma) { 1662SN/A DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); 1679647Sdam.sunwoo@arm.com pte->valid = false; 1689647Sdam.sunwoo@arm.com lookupTable.erase(i); 1699647Sdam.sunwoo@arm.com } 1709647Sdam.sunwoo@arm.com 1719647Sdam.sunwoo@arm.com ++i; 1729647Sdam.sunwoo@arm.com } 1739749Sandreas@sandberg.pp.se} 1749749Sandreas@sandberg.pp.se 1759647Sdam.sunwoo@arm.comvoid 1769647Sdam.sunwoo@arm.comAlphaTlb::flushAddr(Addr vaddr, uint8_t asn) 1771400SN/A{ 1785606Snate@binkert.org Addr vpn = VA_VPN(vaddr); 1795606Snate@binkert.org 1802SN/A PageTable::iterator i = lookupTable.find(vpn); 1812SN/A if (i == lookupTable.end()) 1822SN/A return; 1832SN/A 1846221Snate@binkert.org while (i->first == vpn) { 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 (vpn == pte->tag && (pte->asma || pte->asn == asn)) { 1902SN/A DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vpn, pte->ppn); 191124SN/A 1926221Snate@binkert.org // invalidate this entry 1936221Snate@binkert.org pte->valid = false; 1946221Snate@binkert.org 195124SN/A lookupTable.erase(i); 196124SN/A } 197124SN/A 198124SN/A ++i; 1995606Snate@binkert.org } 2005606Snate@binkert.org} 2019749Sandreas@sandberg.pp.se 2029749Sandreas@sandberg.pp.se 2035606Snate@binkert.orgvoid 204124SN/AAlphaTlb::serialize(ostream &os) 2051400SN/A{ 2065606Snate@binkert.org SERIALIZE_SCALAR(size); 207124SN/A SERIALIZE_SCALAR(nlu); 208124SN/A 209124SN/A for (int i = 0; i < size; i++) { 210124SN/A nameOut(os, csprintf("%s.PTE%d", name(), i)); 2116221Snate@binkert.org table[i].serialize(os); 2126221Snate@binkert.org } 2135606Snate@binkert.org} 2146221Snate@binkert.org 2155606Snate@binkert.orgvoid 216124SN/AAlphaTlb::unserialize(Checkpoint *cp, const string §ion) 217124SN/A{ 2181191SN/A UNSERIALIZE_SCALAR(size); 2195529Snate@binkert.org UNSERIALIZE_SCALAR(nlu); 2208634Schris.emmons@arm.com 2218634Schris.emmons@arm.com for (int i = 0; i < size; i++) { 2228634Schris.emmons@arm.com table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); 2238634Schris.emmons@arm.com if (table[i].valid) { 2248634Schris.emmons@arm.com lookupTable.insert(make_pair(table[i].tag, i)); 2251191SN/A } 2265529Snate@binkert.org } 2271191SN/A} 2285529Snate@binkert.org 2291191SN/A 2301191SN/A/////////////////////////////////////////////////////////////////////// 2315606Snate@binkert.org// 2325606Snate@binkert.org// Alpha ITB 2335606Snate@binkert.org// 2341191SN/AAlphaItb::AlphaItb(const std::string &name, int size) 2351191SN/A : AlphaTlb(name, size) 2368876Sandreas.hansson@arm.com{} 2378876Sandreas.hansson@arm.com 2388876Sandreas.hansson@arm.com 2399433SAndreas.Sandberg@ARM.comvoid 2408876Sandreas.hansson@arm.comAlphaItb::regStats() 2418876Sandreas.hansson@arm.com{ 2428876Sandreas.hansson@arm.com hits 2438876Sandreas.hansson@arm.com .name(name() + ".hits") 2448876Sandreas.hansson@arm.com .desc("ITB hits"); 2458876Sandreas.hansson@arm.com misses 2468876Sandreas.hansson@arm.com .name(name() + ".misses") 2475810Sgblack@eecs.umich.edu .desc("ITB misses"); 2488779Sgblack@eecs.umich.edu acv 2498779Sgblack@eecs.umich.edu .name(name() + ".acv") 2508779Sgblack@eecs.umich.edu .desc("ITB acv"); 2518779Sgblack@eecs.umich.edu accesses 2525529Snate@binkert.org .name(name() + ".accesses") 2539384SAndreas.Sandberg@arm.com .desc("ITB accesses"); 2549384SAndreas.Sandberg@arm.com 2559384SAndreas.Sandberg@arm.com accesses = hits + misses; 2569384SAndreas.Sandberg@arm.com} 2579384SAndreas.Sandberg@arm.com 2581917SN/Avoid 2591191SN/AAlphaItb::fault(Addr pc, ExecContext *xc) const 2601191SN/A{ 2611191SN/A uint64_t *ipr = xc->regs.ipr; 2621191SN/A 2631191SN/A if (!xc->misspeculating()) { 2641191SN/A ipr[AlphaISA::IPR_ITB_TAG] = pc; 2651191SN/A ipr[AlphaISA::IPR_IFAULT_VA_FORM] = 2661191SN/A ipr[AlphaISA::IPR_IVPTBR] | (VA_VPN(pc) << 3); 2671191SN/A } 2689086Sandreas.hansson@arm.com} 2699086Sandreas.hansson@arm.com 2709086Sandreas.hansson@arm.com 2711191SN/AFault 2721191SN/AAlphaItb::translate(MemReqPtr &req) const 2731129SN/A{ 27410529Smorr@cs.wisc.edu InternalProcReg *ipr = req->xc->regs.ipr; 27510529Smorr@cs.wisc.edu 27610529Smorr@cs.wisc.edu if (PC_PAL(req->vaddr)) { 27710529Smorr@cs.wisc.edu // strip off PAL PC marker (lsb is 1) 27810529Smorr@cs.wisc.edu req->paddr = (req->vaddr & ~3) & PA_IMPL_MASK; 27910529Smorr@cs.wisc.edu hits++; 28010529Smorr@cs.wisc.edu return No_Fault; 28110529Smorr@cs.wisc.edu } 28210529Smorr@cs.wisc.edu 28310529Smorr@cs.wisc.edu // verify that this is a good virtual address 28410529Smorr@cs.wisc.edu if (!validVirtualAddress(req->vaddr)) { 28510529Smorr@cs.wisc.edu fault(req->vaddr, req->xc); 28610529Smorr@cs.wisc.edu acv++; 28710529Smorr@cs.wisc.edu return Itb_Acv_Fault; 28810529Smorr@cs.wisc.edu } 28910529Smorr@cs.wisc.edu 29010529Smorr@cs.wisc.edu // Check for "superpage" mapping: when SP<1> is set, and 29110529Smorr@cs.wisc.edu // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. 29210529Smorr@cs.wisc.edu if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && 29310529Smorr@cs.wisc.edu VA_SPACE(req->vaddr) == 2) { 29410529Smorr@cs.wisc.edu // only valid in kernel mode 29510529Smorr@cs.wisc.edu if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) { 29610529Smorr@cs.wisc.edu fault(req->vaddr, req->xc); 29710529Smorr@cs.wisc.edu acv++; 29810529Smorr@cs.wisc.edu return Itb_Acv_Fault; 29910529Smorr@cs.wisc.edu } 30010529Smorr@cs.wisc.edu 30110529Smorr@cs.wisc.edu req->flags |= PHYSICAL; 30210529Smorr@cs.wisc.edu } 30310529Smorr@cs.wisc.edu 30410529Smorr@cs.wisc.edu if (req->flags & PHYSICAL) { 30510529Smorr@cs.wisc.edu req->paddr = req->vaddr & PA_IMPL_MASK; 30610529Smorr@cs.wisc.edu } else { 30710529Smorr@cs.wisc.edu // not a physical address: need to look up pte 30810529Smorr@cs.wisc.edu 30910529Smorr@cs.wisc.edu AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), 31010529Smorr@cs.wisc.edu DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 31110529Smorr@cs.wisc.edu 31210529Smorr@cs.wisc.edu if (!pte) { 31310529Smorr@cs.wisc.edu fault(req->vaddr, req->xc); 31410529Smorr@cs.wisc.edu misses++; 31510529Smorr@cs.wisc.edu return Itb_Fault_Fault; 31610529Smorr@cs.wisc.edu } 31710529Smorr@cs.wisc.edu 31810529Smorr@cs.wisc.edu req->paddr = PA_PFN2PA(pte->ppn) + VA_POFS(req->vaddr & ~3); 31910529Smorr@cs.wisc.edu 32010529Smorr@cs.wisc.edu // check permissions for this access 32110529Smorr@cs.wisc.edu if (!(pte->xre & (1 << ICM_CM(ipr[AlphaISA::IPR_ICM])))) { 32210529Smorr@cs.wisc.edu // instruction access fault 32310529Smorr@cs.wisc.edu fault(req->vaddr, req->xc); 32410529Smorr@cs.wisc.edu acv++; 32510529Smorr@cs.wisc.edu return Itb_Acv_Fault; 32610529Smorr@cs.wisc.edu } 32710529Smorr@cs.wisc.edu } 32810529Smorr@cs.wisc.edu 32910529Smorr@cs.wisc.edu checkCacheability(req); 33010529Smorr@cs.wisc.edu 3311129SN/A hits++; 3321129SN/A return No_Fault; 3339523SAndreas.Sandberg@ARM.com} 3342680Sktlim@umich.edu 3359523SAndreas.Sandberg@ARM.com/////////////////////////////////////////////////////////////////////// 3369523SAndreas.Sandberg@ARM.com// 3379523SAndreas.Sandberg@ARM.com// Alpha DTB 3381129SN/A// 339180SN/AAlphaDtb::AlphaDtb(const std::string &name, int size) 3402SN/A : AlphaTlb(name, size) 3411917SN/A{} 3421917SN/A 3438779Sgblack@eecs.umich.eduvoid 3449433SAndreas.Sandberg@ARM.comAlphaDtb::regStats() 3458779Sgblack@eecs.umich.edu{ 3468779Sgblack@eecs.umich.edu read_hits 3472356SN/A .name(name() + ".read_hits") 3485529Snate@binkert.org .desc("DTB read hits") 3499179Sandreas.hansson@arm.com ; 3502356SN/A 3511917SN/A read_misses 3521917SN/A .name(name() + ".read_misses") 35310464SAndreas.Sandberg@ARM.com .desc("DTB read misses") 35410464SAndreas.Sandberg@ARM.com ; 35510464SAndreas.Sandberg@ARM.com 35610464SAndreas.Sandberg@ARM.com read_acv 35710464SAndreas.Sandberg@ARM.com .name(name() + ".read_acv") 35810464SAndreas.Sandberg@ARM.com .desc("DTB read access violations") 35910464SAndreas.Sandberg@ARM.com ; 36010464SAndreas.Sandberg@ARM.com 36110464SAndreas.Sandberg@ARM.com read_accesses 36210464SAndreas.Sandberg@ARM.com .name(name() + ".read_accesses") 36310464SAndreas.Sandberg@ARM.com .desc("DTB read accesses") 36410464SAndreas.Sandberg@ARM.com ; 36510464SAndreas.Sandberg@ARM.com 36610464SAndreas.Sandberg@ARM.com write_hits 36710464SAndreas.Sandberg@ARM.com .name(name() + ".write_hits") 36810464SAndreas.Sandberg@ARM.com .desc("DTB write hits") 36910464SAndreas.Sandberg@ARM.com ; 37010464SAndreas.Sandberg@ARM.com 37110464SAndreas.Sandberg@ARM.com write_misses 37210464SAndreas.Sandberg@ARM.com .name(name() + ".write_misses") 37310464SAndreas.Sandberg@ARM.com .desc("DTB write misses") 37410464SAndreas.Sandberg@ARM.com ; 37510464SAndreas.Sandberg@ARM.com 37610464SAndreas.Sandberg@ARM.com write_acv 37710464SAndreas.Sandberg@ARM.com .name(name() + ".write_acv") 37810464SAndreas.Sandberg@ARM.com .desc("DTB write access violations") 37910464SAndreas.Sandberg@ARM.com ; 38010464SAndreas.Sandberg@ARM.com 38110464SAndreas.Sandberg@ARM.com write_accesses 38210464SAndreas.Sandberg@ARM.com .name(name() + ".write_accesses") 38310464SAndreas.Sandberg@ARM.com .desc("DTB write accesses") 38410643Snikos.nikoleris@gmail.com ; 38510464SAndreas.Sandberg@ARM.com 38610464SAndreas.Sandberg@ARM.com hits 38710464SAndreas.Sandberg@ARM.com .name(name() + ".hits") 38810464SAndreas.Sandberg@ARM.com .desc("DTB hits") 3891917SN/A ; 3901917SN/A 3912SN/A misses 3922SN/A .name(name() + ".misses") 393729SN/A .desc("DTB misses") 394707SN/A ; 395707SN/A 396707SN/A acv 397707SN/A .name(name() + ".acv") 398707SN/A .desc("DTB access violations") 399707SN/A ; 4007914SBrad.Beckmann@amd.com 4017914SBrad.Beckmann@amd.com accesses 4027914SBrad.Beckmann@amd.com .name(name() + ".accesses") 4037914SBrad.Beckmann@amd.com .desc("DTB accesses") 4047914SBrad.Beckmann@amd.com ; 4057914SBrad.Beckmann@amd.com 4067914SBrad.Beckmann@amd.com hits = read_hits + write_hits; 4077914SBrad.Beckmann@amd.com misses = read_misses + write_misses; 4087914SBrad.Beckmann@amd.com acv = read_acv + write_acv; 4097914SBrad.Beckmann@amd.com accesses = read_accesses + write_accesses; 4102680Sktlim@umich.edu} 4112SN/A 4122SN/Avoid 4132SN/AAlphaDtb::fault(Addr vaddr, uint64_t flags, ExecContext *xc) const 4142SN/A{ 4152680Sktlim@umich.edu uint64_t *ipr = xc->regs.ipr; 4162SN/A 4172SN/A // set fault address and flags 4182680Sktlim@umich.edu if (!xc->misspeculating() && !xc->regs.intrlock) { 4192SN/A // set VA register with faulting address 4202SN/A ipr[AlphaISA::IPR_VA] = vaddr; 4219294Sandreas.hansson@arm.com 4229294Sandreas.hansson@arm.com // set MM_STAT register flags 4238850Sandreas.hansson@arm.com ipr[AlphaISA::IPR_MM_STAT] = (((xc->regs.opcode & 0x3f) << 11) 4248850Sandreas.hansson@arm.com | ((xc->regs.ra & 0x1f) << 6) 4258850Sandreas.hansson@arm.com | (flags & 0x3f)); 4268850Sandreas.hansson@arm.com 4279608Sandreas.hansson@arm.com // set VA_FORM register with faulting formatted address 4288850Sandreas.hansson@arm.com ipr[AlphaISA::IPR_VA_FORM] = 4298922Swilliam.wang@arm.com ipr[AlphaISA::IPR_MVPTBR] | (VA_VPN(vaddr) << 3); 4308850Sandreas.hansson@arm.com 4318922Swilliam.wang@arm.com // lock these registers until the VA register is read 4328850Sandreas.hansson@arm.com xc->regs.intrlock = true; 4338922Swilliam.wang@arm.com } 4348850Sandreas.hansson@arm.com} 4358850Sandreas.hansson@arm.com 436180SN/AFault 4372680Sktlim@umich.eduAlphaDtb::translate(MemReqPtr &req, bool write) const 438180SN/A{ 4396221Snate@binkert.org RegFile *regs = &req->xc->regs; 4406221Snate@binkert.org Addr pc = regs->pc; 4416221Snate@binkert.org InternalProcReg *ipr = regs->ipr; 4422378SN/A 4435718Shsul@eecs.umich.edu if (write) 4445718Shsul@eecs.umich.edu write_accesses++; 4455718Shsul@eecs.umich.edu else 4465718Shsul@eecs.umich.edu read_accesses++; 4475718Shsul@eecs.umich.edu 4485718Shsul@eecs.umich.edu AlphaISA::mode_type mode = 4495718Shsul@eecs.umich.edu (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]); 4506221Snate@binkert.org 4515718Shsul@eecs.umich.edu if (PC_PAL(pc)) { 4525718Shsul@eecs.umich.edu mode = (req->flags & ALTMODE) ? 4535718Shsul@eecs.umich.edu (AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE]) 4548779Sgblack@eecs.umich.edu : AlphaISA::mode_kernel; 4558779Sgblack@eecs.umich.edu } 4568779Sgblack@eecs.umich.edu 457180SN/A // verify that this is a good virtual address 458180SN/A if (!validVirtualAddress(req->vaddr)) { 459180SN/A fault(req->vaddr, 460180SN/A ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | 4614000Ssaidi@eecs.umich.edu MM_STAT_ACV_MASK), 4624000Ssaidi@eecs.umich.edu req->xc); 4634000Ssaidi@eecs.umich.edu 4646221Snate@binkert.org if (write) { write_acv++; } else { read_acv++; } 4656221Snate@binkert.org return Dtb_Fault_Fault; 4666221Snate@binkert.org } 4676221Snate@binkert.org 4684000Ssaidi@eecs.umich.edu // Check for "superpage" mapping: when SP<1> is set, and 4694000Ssaidi@eecs.umich.edu // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. 4704000Ssaidi@eecs.umich.edu if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && VA_SPACE(req->vaddr) == 2) { 4714000Ssaidi@eecs.umich.edu // only valid in kernel mode 472180SN/A if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != AlphaISA::mode_kernel) { 4732798Sktlim@umich.edu fault(req->vaddr, 474180SN/A ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK), 4759430SAndreas.Sandberg@ARM.com req->xc); 4769430SAndreas.Sandberg@ARM.com if (write) { write_acv++; } else { read_acv++; } 4772359SN/A return Dtb_Acv_Fault; 4785606Snate@binkert.org } 4799446SAndreas.Sandberg@ARM.com 4809446SAndreas.Sandberg@ARM.com req->flags |= PHYSICAL; 4819446SAndreas.Sandberg@ARM.com } 4829446SAndreas.Sandberg@ARM.com 483180SN/A if (req->flags & PHYSICAL) { 484180SN/A req->paddr = req->vaddr & PA_IMPL_MASK; 485180SN/A } else { 4868737Skoansin.tan@gmail.com // not a physical address: need to look up pte 487180SN/A 4882680Sktlim@umich.edu AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), 4899152Satgutier@umich.edu DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 4909430SAndreas.Sandberg@ARM.com 4919430SAndreas.Sandberg@ARM.com if (!pte) { 4929332Sdam.sunwoo@arm.com // page fault 4939332Sdam.sunwoo@arm.com fault(req->vaddr, 4949430SAndreas.Sandberg@ARM.com ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK), 4955712Shsul@eecs.umich.edu req->xc); 4966221Snate@binkert.org if (write) { write_misses++; } else { read_misses++; } 4976221Snate@binkert.org return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault; 4982680Sktlim@umich.edu } 4992680Sktlim@umich.edu 500180SN/A req->paddr = PA_PFN2PA(pte->ppn) | VA_POFS(req->vaddr); 5012680Sktlim@umich.edu 5022651Ssaidi@eecs.umich.edu if (write) { 5032680Sktlim@umich.edu if (!(pte->xwe & MODE2MASK(mode))) { 5042651Ssaidi@eecs.umich.edu // declare the instruction access fault 5055714Shsul@eecs.umich.edu fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_ACV_MASK | 5065715Shsul@eecs.umich.edu (pte->fonw ? MM_STAT_FONW_MASK : 0), 5075714Shsul@eecs.umich.edu req->xc); 5082359SN/A write_acv++; 5095875Ssteve.reinhardt@amd.com return Dtb_Fault_Fault; 5105875Ssteve.reinhardt@amd.com } 5115875Ssteve.reinhardt@amd.com if (pte->fonw) { 5125875Ssteve.reinhardt@amd.com fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_FONW_MASK, 5135217Ssaidi@eecs.umich.edu req->xc); 5145875Ssteve.reinhardt@amd.com write_acv++; 5157781SAli.Saidi@ARM.com return Dtb_Fault_Fault; 5169294Sandreas.hansson@arm.com } 5179294Sandreas.hansson@arm.com } else { 5189294Sandreas.hansson@arm.com if (!(pte->xre & MODE2MASK(mode))) { 5199294Sandreas.hansson@arm.com fault(req->vaddr, 5207781SAli.Saidi@ARM.com MM_STAT_ACV_MASK | (pte->fonr ? MM_STAT_FONR_MASK : 0), 5217781SAli.Saidi@ARM.com req->xc); 5229178Sandreas.hansson@arm.com read_acv++; 5239178Sandreas.hansson@arm.com return Dtb_Acv_Fault; 5247781SAli.Saidi@ARM.com } 5259178Sandreas.hansson@arm.com if (pte->fonr) { 5269294Sandreas.hansson@arm.com fault(req->vaddr, MM_STAT_FONR_MASK, req->xc); 5279178Sandreas.hansson@arm.com read_acv++; 5288922Swilliam.wang@arm.com return Dtb_Fault_Fault; 5297781SAli.Saidi@ARM.com } 5309178Sandreas.hansson@arm.com } 5319178Sandreas.hansson@arm.com } 5327781SAli.Saidi@ARM.com 5339178Sandreas.hansson@arm.com checkCacheability(req); 5349294Sandreas.hansson@arm.com 5359178Sandreas.hansson@arm.com if (write) 5368922Swilliam.wang@arm.com write_hits++; 5377781SAli.Saidi@ARM.com else 53810194SGeoffrey.Blake@arm.com read_hits++; 53910194SGeoffrey.Blake@arm.com 5408733Sgeoffrey.blake@arm.com return No_Fault; 5418887Sgeoffrey.blake@arm.com} 5428887Sgeoffrey.blake@arm.com 5438887Sgeoffrey.blake@arm.comAlphaISA::PTE & 5448887Sgeoffrey.blake@arm.comAlphaTlb::index() 5458887Sgeoffrey.blake@arm.com{ 5469294Sandreas.hansson@arm.com AlphaISA::PTE *pte = &table[nlu]; 5478922Swilliam.wang@arm.com nextnlu(); 5489294Sandreas.hansson@arm.com 5498922Swilliam.wang@arm.com return *pte; 5509294Sandreas.hansson@arm.com} 5518922Swilliam.wang@arm.com 5529294Sandreas.hansson@arm.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaItb) 5538922Swilliam.wang@arm.com 5548733Sgeoffrey.blake@arm.com Param<int> size; 55510194SGeoffrey.Blake@arm.com 55610194SGeoffrey.Blake@arm.comEND_DECLARE_SIM_OBJECT_PARAMS(AlphaItb) 55710194SGeoffrey.Blake@arm.com 5588887Sgeoffrey.blake@arm.comBEGIN_INIT_SIM_OBJECT_PARAMS(AlphaItb) 5599178Sandreas.hansson@arm.com 5609178Sandreas.hansson@arm.com INIT_PARAM_DFLT(size, "TLB size", 48) 5618887Sgeoffrey.blake@arm.com 5629178Sandreas.hansson@arm.comEND_INIT_SIM_OBJECT_PARAMS(AlphaItb) 5639294Sandreas.hansson@arm.com 5649294Sandreas.hansson@arm.com 5659178Sandreas.hansson@arm.comCREATE_SIM_OBJECT(AlphaItb) 5668922Swilliam.wang@arm.com{ 5678887Sgeoffrey.blake@arm.com return new AlphaItb(getInstanceName(), size); 5689178Sandreas.hansson@arm.com} 5699178Sandreas.hansson@arm.com 5708887Sgeoffrey.blake@arm.comREGISTER_SIM_OBJECT("AlphaITB", AlphaItb) 5719178Sandreas.hansson@arm.com 5729294Sandreas.hansson@arm.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb) 5739294Sandreas.hansson@arm.com 5749178Sandreas.hansson@arm.com Param<int> size; 5758922Swilliam.wang@arm.com 5768887Sgeoffrey.blake@arm.comEND_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb) 5778733Sgeoffrey.blake@arm.com 578180SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDtb) 579605SN/A 5803520Sgblack@eecs.umich.edu INIT_PARAM_DFLT(size, "TLB size", 64) 5815810Sgblack@eecs.umich.edu 5829152Satgutier@umich.eduEND_INIT_SIM_OBJECT_PARAMS(AlphaDtb) 5832254SN/A 5848779Sgblack@eecs.umich.edu 5858779Sgblack@eecs.umich.eduCREATE_SIM_OBJECT(AlphaDtb) 5868779Sgblack@eecs.umich.edu{ 5872254SN/A return new AlphaDtb(getInstanceName(), size); 5888779Sgblack@eecs.umich.edu} 5898779Sgblack@eecs.umich.edu 5908779Sgblack@eecs.umich.eduREGISTER_SIM_OBJECT("AlphaDTB", AlphaDtb) 5914192Sktlim@umich.edu 5929178Sandreas.hansson@arm.com