tlb.cc revision 828
12SN/A/* 21762SN/A * Copyright (c) 2003 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "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 292439SN/A#include <sstream> 30146SN/A#include <string> 31146SN/A#include <vector> 32146SN/A 33146SN/A#include "base/inifile.hh" 34146SN/A#include "base/str.hh" 35146SN/A#include "base/trace.hh" 361717SN/A#include "cpu/exec_context.hh" 37146SN/A#include "sim/builder.hh" 381717SN/A#include "targetarch/alpha_memory.hh" 392190SN/A#include "targetarch/ev5.hh" 40146SN/A 41146SN/Ausing namespace std; 421977SN/A 431717SN/A/////////////////////////////////////////////////////////////////////// 442623SN/A// 451717SN/A// Alpha TLB 46146SN/A// 471917SN/A 482592SN/A#ifdef DEBUG 492036SN/A bool uncacheBit39 = false; 50146SN/A bool uncacheBit40 = false; 51146SN/A#endif 5256SN/A 5356SN/AAlphaTlb::AlphaTlb(const string &name, int s) 5456SN/A : SimObject(name), size(s), nlu(0) 55695SN/A{ 562SN/A table = new AlphaISA::PTE[size]; 571858SN/A memset(table, 0, sizeof(AlphaISA::PTE[size])); 5856SN/A} 59146SN/A 602171SN/AAlphaTlb::~AlphaTlb() 612170SN/A{ 622170SN/A if (table) 63146SN/A delete [] table; 642462SN/A} 65146SN/A 662SN/A// look up an entry in the TLB 672SN/AAlphaISA::PTE * 682449SN/AAlphaTlb::lookup(Addr vpn, uint8_t asn) const 691355SN/A{ 702623SN/A DPRINTF(TLB, "lookup %#x\n", vpn); 712623SN/A 72224SN/A PageTable::const_iterator i = lookupTable.find(vpn); 731858SN/A if (i == lookupTable.end()) 742518SN/A return NULL; 752420SN/A 762519SN/A while (i->first == vpn) { 772520SN/A int index = i->second; 782420SN/A AlphaISA::PTE *pte = &table[index]; 792SN/A assert(pte->valid); 802190SN/A if (vpn == pte->tag && (pte->asma || pte->asn == asn)) 812SN/A return pte; 822SN/A 83334SN/A ++i; 84140SN/A } 85334SN/A 862SN/A // not found... 872SN/A return NULL; 882SN/A} 892190SN/A 902SN/A 912SN/Avoid 922623SN/AAlphaTlb::checkCacheability(MemReqPtr &req) 932SN/A{ 942SN/A // in Alpha, cacheability is controlled by upper-level bits of the 952SN/A // physical address 96180SN/A 972623SN/A /* 98393SN/A * We support having the uncacheable bit in either bit 39 or bit 40. 99393SN/A * The Turbolaser platform (and EV5) support having the bit in 39, but 100393SN/A * Tsunami (which Linux assumes uses an EV6) generates accesses with 101393SN/A * the bit in 40. So we must check for both, but we have debug flags 102384SN/A * to catch a weird case where both are used, which shouldn't happen. 103384SN/A */ 104393SN/A 1052623SN/A if (req->paddr & PA_UNCACHED_BIT_40 || 106393SN/A req->paddr & PA_UNCACHED_BIT_39) { 107393SN/A 108393SN/A#ifdef DEBUG 109393SN/A if (req->paddr & PA_UNCACHED_BIT_40) { 110384SN/A if(uncacheBit39) 111189SN/A panic("Bit 40 access follows bit 39 access, PA=%x\n", 112189SN/A req->paddr); 1132623SN/A 1142SN/A uncacheBit40 = true; 115729SN/A } else if (req->paddr & PA_UNCACHED_BIT_39) { 116334SN/A if(uncacheBit40) 1172SN/A panic("Bit 39 acceess follows bit 40 access, PA=%x\n", 1182SN/A req->paddr); 1192SN/A 1202SN/A uncacheBit39 = true; 1212SN/A } 1222SN/A#endif 1232SN/A 1242SN/A // IPR memory space not implemented 1252SN/A if (PA_IPR_SPACE(req->paddr)) 1262SN/A if (!req->xc->misspeculating()) 1272SN/A panic("IPR memory space not implemented! PA=%x\n", 1282SN/A req->paddr); 1291001SN/A 1301001SN/A // mark request as uncacheable 1311001SN/A req->flags |= UNCACHEABLE; 1321001SN/A } 1331001SN/A} 1342SN/A 1352SN/A 1362SN/A// insert a new TLB entry 1372SN/Avoid 1382SN/AAlphaTlb::insert(Addr vaddr, AlphaISA::PTE &pte) 1392SN/A{ 1402SN/A if (table[nlu].valid) { 1412SN/A Addr oldvpn = table[nlu].tag; 1422SN/A PageTable::iterator i = lookupTable.find(oldvpn); 1432SN/A 1442SN/A if (i == lookupTable.end()) 1452SN/A panic("TLB entry not found in lookupTable"); 1462SN/A 1472SN/A int index; 1482SN/A while ((index = i->second) != nlu) { 1492SN/A if (table[index].tag != oldvpn) 1502SN/A panic("TLB entry not found in lookupTable"); 1512390SN/A 1522390SN/A ++i; 1532390SN/A } 1542390SN/A 1552390SN/A DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); 1562390SN/A 1572390SN/A lookupTable.erase(i); 1582390SN/A } 1592390SN/A 1602390SN/A Addr vpn = VA_VPN(vaddr); 1612390SN/A DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vpn, pte.ppn); 1622390SN/A 163385SN/A table[nlu] = pte; 1642SN/A table[nlu].tag = vpn; 1652SN/A table[nlu].valid = true; 1662SN/A 1672623SN/A lookupTable.insert(make_pair(vpn, nlu)); 168334SN/A nextnlu(); 169334SN/A} 1702623SN/A 171334SN/Avoid 172334SN/AAlphaTlb::flushAll() 173334SN/A{ 1742623SN/A memset(table, 0, sizeof(AlphaISA::PTE[size])); 1752SN/A lookupTable.clear(); 176921SN/A nlu = 0; 177224SN/A} 178237SN/A 1792190SN/Avoid 1802SN/AAlphaTlb::flushProcesses() 1812SN/A{ 1822SN/A PageTable::iterator i = lookupTable.begin(); 1832623SN/A PageTable::iterator end = lookupTable.end(); 1842SN/A while (i != end) { 185921SN/A int index = i->second; 186224SN/A AlphaISA::PTE *pte = &table[index]; 1872190SN/A assert(pte->valid); 1882SN/A 1892SN/A if (!pte->asma) { 1902SN/A DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); 1912SN/A pte->valid = false; 1922SN/A lookupTable.erase(i); 1932SN/A } 1942SN/A 195595SN/A ++i; 1962623SN/A } 197595SN/A} 1982390SN/A 1991080SN/Avoid 2001080SN/AAlphaTlb::flushAddr(Addr vaddr, uint8_t asn) 2011080SN/A{ 2021080SN/A Addr vpn = VA_VPN(vaddr); 2031080SN/A 2041080SN/A PageTable::iterator i = lookupTable.find(vpn); 2051080SN/A if (i == lookupTable.end()) 2061121SN/A return; 2072107SN/A 2081089SN/A while (i->first == vpn) { 2091089SN/A int index = i->second; 2101080SN/A AlphaISA::PTE *pte = &table[index]; 2111080SN/A assert(pte->valid); 2121080SN/A 2131080SN/A if (vpn == pte->tag && (pte->asma || pte->asn == asn)) { 214595SN/A DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vpn, pte->ppn); 2152623SN/A 2162623SN/A // invalidate this entry 217595SN/A pte->valid = false; 2182090SN/A 2192190SN/A lookupTable.erase(i); 2202190SN/A } 221595SN/A 2222205SN/A ++i; 2232205SN/A } 2242190SN/A} 2252190SN/A 226595SN/A 227595SN/Avoid 2282390SN/AAlphaTlb::serialize(ostream &os) 2292423SN/A{ 2302390SN/A SERIALIZE_SCALAR(size); 231595SN/A SERIALIZE_SCALAR(nlu); 232595SN/A 233595SN/A for (int i = 0; i < size; i++) { 2342623SN/A nameOut(os, csprintf("%s.PTE%d", name(), i)); 235595SN/A table[i].serialize(os); 2362390SN/A } 2371080SN/A} 238595SN/A 2391080SN/Avoid 2401080SN/AAlphaTlb::unserialize(Checkpoint *cp, const string §ion) 241595SN/A{ 2422190SN/A UNSERIALIZE_SCALAR(size); 2431080SN/A UNSERIALIZE_SCALAR(nlu); 2441080SN/A 2451080SN/A for (int i = 0; i < size; i++) { 2461121SN/A table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); 2472107SN/A if (table[i].valid) { 2481089SN/A lookupTable.insert(make_pair(table[i].tag, i)); 2491080SN/A } 2501089SN/A } 2511080SN/A} 2521080SN/A 2531080SN/A 254595SN/A/////////////////////////////////////////////////////////////////////// 2552422SN/A// 2561080SN/A// Alpha ITB 2572090SN/A// 2581080SN/AAlphaItb::AlphaItb(const std::string &name, int size) 259595SN/A : AlphaTlb(name, size) 2602190SN/A{} 2612190SN/A 262595SN/A 2632190SN/Avoid 2641098SN/AAlphaItb::regStats() 2651098SN/A{ 2661098SN/A hits 2672190SN/A .name(name() + ".hits") 2681098SN/A .desc("ITB hits"); 2691098SN/A misses 2701098SN/A .name(name() + ".misses") 2712012SN/A .desc("ITB misses"); 2721098SN/A acv 2731098SN/A .name(name() + ".acv") 274595SN/A .desc("ITB acv"); 2752205SN/A accesses 2762205SN/A .name(name() + ".accesses") 2772205SN/A .desc("ITB accesses"); 278595SN/A 2792390SN/A accesses = hits + misses; 2802420SN/A} 2812423SN/A 2822390SN/Avoid 283595SN/AAlphaItb::fault(Addr pc, ExecContext *xc) const 284595SN/A{ 2851858SN/A uint64_t *ipr = xc->regs.ipr; 2862SN/A 2872623SN/A if (!xc->misspeculating()) { 2882SN/A ipr[AlphaISA::IPR_ITB_TAG] = pc; 2892190SN/A ipr[AlphaISA::IPR_IFAULT_VA_FORM] = 2902SN/A ipr[AlphaISA::IPR_IVPTBR] | (VA_VPN(pc) << 3); 2912SN/A } 2922SN/A} 2931858SN/A 2942SN/A 2952623SN/AFault 2962SN/AAlphaItb::translate(MemReqPtr &req) const 2972SN/A{ 2982SN/A InternalProcReg *ipr = req->xc->regs.ipr; 2992190SN/A 3002SN/A if (PC_PAL(req->vaddr)) { 3012190SN/A // strip off PAL PC marker (lsb is 1) 3022SN/A req->paddr = (req->vaddr & ~3) & PA_IMPL_MASK; 3032SN/A hits++; 3042SN/A return No_Fault; 3052SN/A } 3062SN/A 3072623SN/A if (req->flags & PHYSICAL) { 3082SN/A req->paddr = req->vaddr; 3091858SN/A } else { 3102626SN/A // verify that this is a good virtual address 3112SN/A if (!validVirtualAddress(req->vaddr)) { 3122SN/A fault(req->vaddr, req->xc); 3131133SN/A acv++; 3142SN/A return Itb_Acv_Fault; 3152190SN/A } 3162107SN/A 3172107SN/A // Check for "superpage" mapping: when SP<1> is set, and 3182190SN/A // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. 3192SN/A if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && 3202107SN/A VA_SPACE(req->vaddr) == 2) { 3212SN/A 3222SN/A // only valid in kernel mode 3232SN/A if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) { 3242SN/A fault(req->vaddr, req->xc); 3252SN/A acv++; 3262190SN/A return Itb_Acv_Fault; 3272107SN/A } 3282107SN/A 3292SN/A req->paddr = req->vaddr & PA_IMPL_MASK; 3302SN/A 3312SN/A // sign extend the physical address properly 3322SN/A if (req->paddr & PA_UNCACHED_BIT_39 || 3332SN/A req->paddr & PA_UNCACHED_BIT_40) 3342SN/A req->paddr |= 0xf0000000000; 3352SN/A else 3362190SN/A req->paddr &= 0xffffffffff; 3372SN/A 3382SN/A } else { 3392190SN/A // not a physical address: need to look up pte 3402190SN/A AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), 3412190SN/A DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 3422234SN/A 3432234SN/A if (!pte) { 3442SN/A fault(req->vaddr, req->xc); 3452SN/A misses++; 3462190SN/A return Itb_Fault_Fault; 3472SN/A } 3482SN/A 3492SN/A req->paddr = PA_PFN2PA(pte->ppn) + VA_POFS(req->vaddr & ~3); 3502623SN/A 3512SN/A // check permissions for this access 3522623SN/A if (!(pte->xre & (1 << ICM_CM(ipr[AlphaISA::IPR_ICM])))) { 3532623SN/A // instruction access fault 3542662Sstever@eecs.umich.edu fault(req->vaddr, req->xc); 3552623SN/A acv++; 3562623SN/A return Itb_Acv_Fault; 3572623SN/A } 3582623SN/A 3592623SN/A hits++; 3602663Sstever@eecs.umich.edu } 3612663Sstever@eecs.umich.edu } 3622663Sstever@eecs.umich.edu 3632623SN/A // check that the physical address is ok (catch bad physical addresses) 3642662Sstever@eecs.umich.edu if (req->paddr & ~PA_IMPL_MASK) 3652623SN/A return Machine_Check_Fault; 3662623SN/A 3672623SN/A checkCacheability(req); 3682623SN/A 3692623SN/A return No_Fault; 3702623SN/A} 3712623SN/A 3722623SN/A/////////////////////////////////////////////////////////////////////// 3732SN/A// 3742190SN/A// Alpha DTB 3752427SN/A// 3762455SN/AAlphaDtb::AlphaDtb(const std::string &name, int size) 3772427SN/A : AlphaTlb(name, size) 3782SN/A{} 3792623SN/A 3802623SN/Avoid 3812623SN/AAlphaDtb::regStats() 3822SN/A{ 3832623SN/A read_hits 3842SN/A .name(name() + ".read_hits") 3852623SN/A .desc("DTB read hits") 3862623SN/A ; 3872SN/A 3882623SN/A read_misses 3892623SN/A .name(name() + ".read_misses") 3902623SN/A .desc("DTB read misses") 3912470SN/A ; 3922623SN/A 3932623SN/A read_acv 3942623SN/A .name(name() + ".read_acv") 3952623SN/A .desc("DTB read access violations") 3962623SN/A ; 3972623SN/A 3982623SN/A read_accesses 3992623SN/A .name(name() + ".read_accesses") 4002623SN/A .desc("DTB read accesses") 4012623SN/A ; 4022623SN/A 4032623SN/A write_hits 4042623SN/A .name(name() + ".write_hits") 4052623SN/A .desc("DTB write hits") 4062623SN/A ; 4072623SN/A 4082623SN/A write_misses 4092623SN/A .name(name() + ".write_misses") 4102623SN/A .desc("DTB write misses") 4112623SN/A ; 4122623SN/A 4132623SN/A write_acv 4142623SN/A .name(name() + ".write_acv") 4152623SN/A .desc("DTB write access violations") 4162623SN/A ; 4172623SN/A 4182623SN/A write_accesses 4192623SN/A .name(name() + ".write_accesses") 4202623SN/A .desc("DTB write accesses") 4212420SN/A ; 4222SN/A 4232623SN/A hits 4242623SN/A .name(name() + ".hits") 4252SN/A .desc("DTB hits") 4262SN/A ; 4272623SN/A 4282623SN/A misses 4292623SN/A .name(name() + ".misses") 4302623SN/A .desc("DTB misses") 4312SN/A ; 4322623SN/A 4332644Sstever@eecs.umich.edu acv 4342644Sstever@eecs.umich.edu .name(name() + ".acv") 4352644Sstever@eecs.umich.edu .desc("DTB access violations") 4362644Sstever@eecs.umich.edu ; 4372623SN/A 4382SN/A accesses 4392SN/A .name(name() + ".accesses") 4402623SN/A .desc("DTB accesses") 4412623SN/A ; 4422623SN/A 4432090SN/A hits = read_hits + write_hits; 4441858SN/A misses = read_misses + write_misses; 4452234SN/A acv = read_acv + write_acv; 4462SN/A accesses = read_accesses + write_accesses; 4472470SN/A} 4482SN/A 4492SN/Avoid 4502SN/AAlphaDtb::fault(Addr vaddr, uint64_t flags, ExecContext *xc) const 4512SN/A{ 4522190SN/A uint64_t *ipr = xc->regs.ipr; 4532623SN/A 4542190SN/A // set fault address and flags 4552251SN/A if (!xc->misspeculating() && !xc->regs.intrlock) { 4562262SN/A // set VA register with faulting address 4572262SN/A ipr[AlphaISA::IPR_VA] = vaddr; 4582251SN/A 4592251SN/A // set MM_STAT register flags 4602SN/A ipr[AlphaISA::IPR_MM_STAT] = (((xc->regs.opcode & 0x3f) << 11) 4612SN/A | ((xc->regs.ra & 0x1f) << 6) 4621858SN/A | (flags & 0x3f)); 4632SN/A 4642SN/A // set VA_FORM register with faulting formatted address 4652190SN/A ipr[AlphaISA::IPR_VA_FORM] = 4662190SN/A ipr[AlphaISA::IPR_MVPTBR] | (VA_VPN(vaddr) << 3); 4672190SN/A 4682SN/A // lock these registers until the VA register is read 4692SN/A xc->regs.intrlock = true; 4702SN/A } 471} 472 473Fault 474AlphaDtb::translate(MemReqPtr &req, bool write) const 475{ 476 RegFile *regs = &req->xc->regs; 477 Addr pc = regs->pc; 478 InternalProcReg *ipr = regs->ipr; 479 480 AlphaISA::mode_type mode = 481 (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]); 482 483 if (PC_PAL(pc)) { 484 mode = (req->flags & ALTMODE) ? 485 (AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE]) 486 : AlphaISA::mode_kernel; 487 } 488 489 if (req->flags & PHYSICAL) { 490 req->paddr = req->vaddr; 491 } else { 492 // verify that this is a good virtual address 493 if (!validVirtualAddress(req->vaddr)) { 494 fault(req->vaddr, 495 ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | 496 MM_STAT_ACV_MASK), 497 req->xc); 498 499 if (write) { write_acv++; } else { read_acv++; } 500 return Dtb_Fault_Fault; 501 } 502 503 // Check for "superpage" mapping: when SP<1> is set, and 504 // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. 505 if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && 506 VA_SPACE(req->vaddr) == 2) { 507 508 // only valid in kernel mode 509 if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != 510 AlphaISA::mode_kernel) { 511 fault(req->vaddr, 512 ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK), 513 req->xc); 514 if (write) { write_acv++; } else { read_acv++; } 515 return Dtb_Acv_Fault; 516 } 517 518 req->paddr = req->vaddr & PA_IMPL_MASK; 519 520 // sign extend the physical address properly 521 if (req->paddr & PA_UNCACHED_BIT_39 || 522 req->paddr & PA_UNCACHED_BIT_40) 523 req->paddr |= 0xf0000000000; 524 else 525 req->paddr &= 0xffffffffff; 526 527 } else { 528 if (write) 529 write_accesses++; 530 else 531 read_accesses++; 532 533 // not a physical address: need to look up pte 534 AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), 535 DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 536 537 if (!pte) { 538 // page fault 539 fault(req->vaddr, 540 ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK), 541 req->xc); 542 if (write) { write_misses++; } else { read_misses++; } 543 return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault; 544 } 545 546 req->paddr = PA_PFN2PA(pte->ppn) | VA_POFS(req->vaddr); 547 548 if (write) { 549 if (!(pte->xwe & MODE2MASK(mode))) { 550 // declare the instruction access fault 551 fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_ACV_MASK | 552 (pte->fonw ? MM_STAT_FONW_MASK : 0), 553 req->xc); 554 write_acv++; 555 return Dtb_Fault_Fault; 556 } 557 if (pte->fonw) { 558 fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_FONW_MASK, 559 req->xc); 560 write_acv++; 561 return Dtb_Fault_Fault; 562 } 563 } else { 564 if (!(pte->xre & MODE2MASK(mode))) { 565 fault(req->vaddr, 566 MM_STAT_ACV_MASK | 567 (pte->fonr ? MM_STAT_FONR_MASK : 0), 568 req->xc); 569 read_acv++; 570 return Dtb_Acv_Fault; 571 } 572 if (pte->fonr) { 573 fault(req->vaddr, MM_STAT_FONR_MASK, req->xc); 574 read_acv++; 575 return Dtb_Fault_Fault; 576 } 577 } 578 } 579 580 if (write) 581 write_hits++; 582 else 583 read_hits++; 584 } 585 586 // check that the physical address is ok (catch bad physical addresses) 587 if (req->paddr & ~PA_IMPL_MASK) 588 return Machine_Check_Fault; 589 590 checkCacheability(req); 591 592 return No_Fault; 593} 594 595AlphaISA::PTE & 596AlphaTlb::index(bool advance) 597{ 598 AlphaISA::PTE *pte = &table[nlu]; 599 600 if (advance) 601 nextnlu(); 602 603 return *pte; 604} 605 606BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaItb) 607 608 Param<int> size; 609 610END_DECLARE_SIM_OBJECT_PARAMS(AlphaItb) 611 612BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaItb) 613 614 INIT_PARAM_DFLT(size, "TLB size", 48) 615 616END_INIT_SIM_OBJECT_PARAMS(AlphaItb) 617 618 619CREATE_SIM_OBJECT(AlphaItb) 620{ 621 return new AlphaItb(getInstanceName(), size); 622} 623 624REGISTER_SIM_OBJECT("AlphaITB", AlphaItb) 625 626BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb) 627 628 Param<int> size; 629 630END_DECLARE_SIM_OBJECT_PARAMS(AlphaDtb) 631 632BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDtb) 633 634 INIT_PARAM_DFLT(size, "TLB size", 64) 635 636END_INIT_SIM_OBJECT_PARAMS(AlphaDtb) 637 638 639CREATE_SIM_OBJECT(AlphaDtb) 640{ 641 return new AlphaDtb(getInstanceName(), size); 642} 643 644REGISTER_SIM_OBJECT("AlphaDTB", AlphaDtb) 645 646