tlb.cc revision 860
12810SN/A/* 211893Snikos.nikoleris@arm.com * Copyright (c) 2003 The Regents of The University of Michigan 39796Sprakash.ramrakhyani@arm.com * All rights reserved. 49796Sprakash.ramrakhyani@arm.com * 59796Sprakash.ramrakhyani@arm.com * Redistribution and use in source and binary forms, with or without 69796Sprakash.ramrakhyani@arm.com * modification, are permitted provided that the following conditions are 79796Sprakash.ramrakhyani@arm.com * met: redistributions of source code must retain the above copyright 89796Sprakash.ramrakhyani@arm.com * notice, this list of conditions and the following disclaimer; 99796Sprakash.ramrakhyani@arm.com * redistributions in binary form must reproduce the above copyright 109796Sprakash.ramrakhyani@arm.com * notice, this list of conditions and the following disclaimer in the 119796Sprakash.ramrakhyani@arm.com * documentation and/or other materials provided with the distribution; 129796Sprakash.ramrakhyani@arm.com * neither the name of the copyright holders nor the names of its 139796Sprakash.ramrakhyani@arm.com * contributors may be used to endorse or promote products derived from 142810SN/A * this software without specific prior written permission. 152810SN/A * 162810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272810SN/A */ 282810SN/A 292810SN/A#include <sstream> 302810SN/A#include <string> 312810SN/A#include <vector> 322810SN/A 332810SN/A#include "base/inifile.hh" 342810SN/A#include "base/str.hh" 352810SN/A#include "base/trace.hh" 362810SN/A#include "cpu/exec_context.hh" 372810SN/A#include "sim/builder.hh" 382810SN/A#include "targetarch/alpha_memory.hh" 392810SN/A#include "targetarch/ev5.hh" 402810SN/A 412810SN/Ausing namespace std; 422810SN/A 432810SN/A/////////////////////////////////////////////////////////////////////// 442810SN/A// 452810SN/A// Alpha TLB 462810SN/A// 472810SN/A#ifdef DEBUG 482810SN/Abool uncacheBit39 = false; 4911486Snikos.nikoleris@arm.combool uncacheBit40 = false; 5011486Snikos.nikoleris@arm.com#endif 518229Snate@binkert.org 525338Sstever@gmail.comAlphaTLB::AlphaTLB(const string &name, int s) 532810SN/A : SimObject(name), size(s), nlu(0) 542810SN/A{ 552810SN/A table = new AlphaISA::PTE[size]; 562810SN/A memset(table, 0, sizeof(AlphaISA::PTE[size])); 579796Sprakash.ramrakhyani@arm.com} 5811893Snikos.nikoleris@arm.com 5911893Snikos.nikoleris@arm.comAlphaTLB::~AlphaTLB() 6011722Ssophiane.senni@gmail.com{ 6111722Ssophiane.senni@gmail.com if (table) 6211722Ssophiane.senni@gmail.com delete [] table; 6311722Ssophiane.senni@gmail.com} 6412513Sodanrc@yahoo.com.br 6512513Sodanrc@yahoo.com.br// look up an entry in the TLB 6612629Sodanrc@yahoo.com.brAlphaISA::PTE * 6712629Sodanrc@yahoo.com.brAlphaTLB::lookup(Addr vpn, uint8_t asn) const 689796Sprakash.ramrakhyani@arm.com{ 699796Sprakash.ramrakhyani@arm.com DPRINTF(TLB, "lookup %#x\n", vpn); 709796Sprakash.ramrakhyani@arm.com 712810SN/A PageTable::const_iterator i = lookupTable.find(vpn); 722810SN/A if (i == lookupTable.end()) 732810SN/A return NULL; 7410360Sandreas.hansson@arm.com 752810SN/A while (i->first == vpn) { 762810SN/A int index = i->second; 772810SN/A AlphaISA::PTE *pte = &table[index]; 782810SN/A assert(pte->valid); 7912636Sodanrc@yahoo.com.br if (vpn == pte->tag && (pte->asma || pte->asn == asn)) 8012636Sodanrc@yahoo.com.br return pte; 8112636Sodanrc@yahoo.com.br 8212636Sodanrc@yahoo.com.br ++i; 8312636Sodanrc@yahoo.com.br } 8412636Sodanrc@yahoo.com.br 8512636Sodanrc@yahoo.com.br // not found... 8612636Sodanrc@yahoo.com.br return NULL; 8712636Sodanrc@yahoo.com.br} 8812636Sodanrc@yahoo.com.br 8912636Sodanrc@yahoo.com.br 9012636Sodanrc@yahoo.com.brvoid 9112636Sodanrc@yahoo.com.brAlphaTLB::checkCacheability(MemReqPtr &req) 9212636Sodanrc@yahoo.com.br{ 9312636Sodanrc@yahoo.com.br // in Alpha, cacheability is controlled by upper-level bits of the 9412636Sodanrc@yahoo.com.br // physical address 9512636Sodanrc@yahoo.com.br 9612636Sodanrc@yahoo.com.br /* 9712636Sodanrc@yahoo.com.br * We support having the uncacheable bit in either bit 39 or bit 40. 9812636Sodanrc@yahoo.com.br * The Turbolaser platform (and EV5) support having the bit in 39, but 9912636Sodanrc@yahoo.com.br * Tsunami (which Linux assumes uses an EV6) generates accesses with 10012636Sodanrc@yahoo.com.br * the bit in 40. So we must check for both, but we have debug flags 10112636Sodanrc@yahoo.com.br * to catch a weird case where both are used, which shouldn't happen. 10212636Sodanrc@yahoo.com.br */ 10312636Sodanrc@yahoo.com.br 10412636Sodanrc@yahoo.com.br if (req->paddr & PA_UNCACHED_BIT_40 || 10512636Sodanrc@yahoo.com.br req->paddr & PA_UNCACHED_BIT_39) { 10612636Sodanrc@yahoo.com.br 10712636Sodanrc@yahoo.com.br#ifdef DEBUG 10812636Sodanrc@yahoo.com.br if (req->paddr & PA_UNCACHED_BIT_40) { 10912636Sodanrc@yahoo.com.br if(uncacheBit39) 11012636Sodanrc@yahoo.com.br panic("Bit 40 access follows bit 39 access, PA=%x\n", 11112636Sodanrc@yahoo.com.br req->paddr); 11212636Sodanrc@yahoo.com.br 11312636Sodanrc@yahoo.com.br uncacheBit40 = true; 11412636Sodanrc@yahoo.com.br } else if (req->paddr & PA_UNCACHED_BIT_39) { 11512636Sodanrc@yahoo.com.br if(uncacheBit40) 11612636Sodanrc@yahoo.com.br panic("Bit 39 acceess follows bit 40 access, PA=%x\n", 11712636Sodanrc@yahoo.com.br req->paddr); 11812636Sodanrc@yahoo.com.br 11912636Sodanrc@yahoo.com.br uncacheBit39 = true; 12012636Sodanrc@yahoo.com.br } 12112636Sodanrc@yahoo.com.br#endif 12212636Sodanrc@yahoo.com.br 12312636Sodanrc@yahoo.com.br // IPR memory space not implemented 12412636Sodanrc@yahoo.com.br if (PA_IPR_SPACE(req->paddr)) 12512636Sodanrc@yahoo.com.br if (!req->xc->misspeculating()) 12612636Sodanrc@yahoo.com.br panic("IPR memory space not implemented! PA=%x\n", 1279796Sprakash.ramrakhyani@arm.com req->paddr); 1282810SN/A 12911522Sstephan.diestelhorst@arm.com // mark request as uncacheable 13011522Sstephan.diestelhorst@arm.com req->flags |= UNCACHEABLE; 1312810SN/A } 13211522Sstephan.diestelhorst@arm.com} 1332810SN/A 1342810SN/A 1359796Sprakash.ramrakhyani@arm.com// insert a new TLB entry 1362810SN/Avoid 1372810SN/AAlphaTLB::insert(Addr vaddr, AlphaISA::PTE &pte) 1382810SN/A{ 1392810SN/A if (table[nlu].valid) { 1402810SN/A Addr oldvpn = table[nlu].tag; 1419796Sprakash.ramrakhyani@arm.com PageTable::iterator i = lookupTable.find(oldvpn); 1422810SN/A 1432810SN/A if (i == lookupTable.end()) 1442810SN/A panic("TLB entry not found in lookupTable"); 1452810SN/A 1469796Sprakash.ramrakhyani@arm.com int index; 1472810SN/A while ((index = i->second) != nlu) { 1482810SN/A if (table[index].tag != oldvpn) 1492810SN/A panic("TLB entry not found in lookupTable"); 1502810SN/A 1519796Sprakash.ramrakhyani@arm.com ++i; 1522810SN/A } 1532810SN/A 1542810SN/A DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); 1552810SN/A 1569796Sprakash.ramrakhyani@arm.com lookupTable.erase(i); 1572810SN/A } 1582810SN/A 1592810SN/A Addr vpn = VA_VPN(vaddr); 1602810SN/A DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vpn, pte.ppn); 1612810SN/A 1622810SN/A table[nlu] = pte; 1639796Sprakash.ramrakhyani@arm.com table[nlu].tag = vpn; 1642810SN/A table[nlu].valid = true; 1652810SN/A 1662810SN/A lookupTable.insert(make_pair(vpn, nlu)); 1676978SLisa.Hsu@amd.com nextnlu(); 1688833Sdam.sunwoo@arm.com} 1699796Sprakash.ramrakhyani@arm.com 1708833Sdam.sunwoo@arm.comvoid 1716978SLisa.Hsu@amd.comAlphaTLB::flushAll() 1726978SLisa.Hsu@amd.com{ 1738833Sdam.sunwoo@arm.com memset(table, 0, sizeof(AlphaISA::PTE[size])); 1748833Sdam.sunwoo@arm.com lookupTable.clear(); 1758833Sdam.sunwoo@arm.com nlu = 0; 1766978SLisa.Hsu@amd.com} 1776978SLisa.Hsu@amd.com 1789796Sprakash.ramrakhyani@arm.comvoid 1796978SLisa.Hsu@amd.comAlphaTLB::flushProcesses() 1808833Sdam.sunwoo@arm.com{ 1816978SLisa.Hsu@amd.com PageTable::iterator i = lookupTable.begin(); 1828833Sdam.sunwoo@arm.com PageTable::iterator end = lookupTable.end(); 1838833Sdam.sunwoo@arm.com while (i != end) { 1848833Sdam.sunwoo@arm.com int index = i->second; 1856978SLisa.Hsu@amd.com AlphaISA::PTE *pte = &table[index]; 1866978SLisa.Hsu@amd.com assert(pte->valid); 1876978SLisa.Hsu@amd.com 18810024Sdam.sunwoo@arm.com if (!pte->asma) { 18910024Sdam.sunwoo@arm.com DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); 19010024Sdam.sunwoo@arm.com pte->valid = false; 19110024Sdam.sunwoo@arm.com lookupTable.erase(i); 19210024Sdam.sunwoo@arm.com } 19310024Sdam.sunwoo@arm.com 19410024Sdam.sunwoo@arm.com ++i; 19510024Sdam.sunwoo@arm.com } 19610024Sdam.sunwoo@arm.com} 19710024Sdam.sunwoo@arm.com 19810024Sdam.sunwoo@arm.comvoid 19910024Sdam.sunwoo@arm.comAlphaTLB::flushAddr(Addr vaddr, uint8_t asn) 20010024Sdam.sunwoo@arm.com{ 20110024Sdam.sunwoo@arm.com Addr vpn = VA_VPN(vaddr); 20210024Sdam.sunwoo@arm.com 20310024Sdam.sunwoo@arm.com PageTable::iterator i = lookupTable.find(vpn); 20410024Sdam.sunwoo@arm.com if (i == lookupTable.end()) 20510024Sdam.sunwoo@arm.com return; 20610024Sdam.sunwoo@arm.com 20710024Sdam.sunwoo@arm.com while (i->first == vpn) { 20810024Sdam.sunwoo@arm.com int index = i->second; 20910024Sdam.sunwoo@arm.com AlphaISA::PTE *pte = &table[index]; 21010025Stimothy.jones@arm.com assert(pte->valid); 21110025Stimothy.jones@arm.com 21210025Stimothy.jones@arm.com if (vpn == pte->tag && (pte->asma || pte->asn == asn)) { 21310025Stimothy.jones@arm.com DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vpn, pte->ppn); 21410025Stimothy.jones@arm.com 21510025Stimothy.jones@arm.com // invalidate this entry 21610025Stimothy.jones@arm.com pte->valid = false; 21710025Stimothy.jones@arm.com 21810025Stimothy.jones@arm.com lookupTable.erase(i); 21910025Stimothy.jones@arm.com } 22010024Sdam.sunwoo@arm.com 2212810SN/A ++i; 2222810SN/A } 223} 224 225 226void 227AlphaTLB::serialize(ostream &os) 228{ 229 SERIALIZE_SCALAR(size); 230 SERIALIZE_SCALAR(nlu); 231 232 for (int i = 0; i < size; i++) { 233 nameOut(os, csprintf("%s.PTE%d", name(), i)); 234 table[i].serialize(os); 235 } 236} 237 238void 239AlphaTLB::unserialize(Checkpoint *cp, const string §ion) 240{ 241 UNSERIALIZE_SCALAR(size); 242 UNSERIALIZE_SCALAR(nlu); 243 244 for (int i = 0; i < size; i++) { 245 table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); 246 if (table[i].valid) { 247 lookupTable.insert(make_pair(table[i].tag, i)); 248 } 249 } 250} 251 252 253/////////////////////////////////////////////////////////////////////// 254// 255// Alpha ITB 256// 257AlphaITB::AlphaITB(const std::string &name, int size) 258 : AlphaTLB(name, size) 259{} 260 261 262void 263AlphaITB::regStats() 264{ 265 hits 266 .name(name() + ".hits") 267 .desc("ITB hits"); 268 misses 269 .name(name() + ".misses") 270 .desc("ITB misses"); 271 acv 272 .name(name() + ".acv") 273 .desc("ITB acv"); 274 accesses 275 .name(name() + ".accesses") 276 .desc("ITB accesses"); 277 278 accesses = hits + misses; 279} 280 281void 282AlphaITB::fault(Addr pc, ExecContext *xc) const 283{ 284 uint64_t *ipr = xc->regs.ipr; 285 286 if (!xc->misspeculating()) { 287 ipr[AlphaISA::IPR_ITB_TAG] = pc; 288 ipr[AlphaISA::IPR_IFAULT_VA_FORM] = 289 ipr[AlphaISA::IPR_IVPTBR] | (VA_VPN(pc) << 3); 290 } 291} 292 293 294Fault 295AlphaITB::translate(MemReqPtr &req) const 296{ 297 InternalProcReg *ipr = req->xc->regs.ipr; 298 299 if (PC_PAL(req->vaddr)) { 300 // strip off PAL PC marker (lsb is 1) 301 req->paddr = (req->vaddr & ~3) & PA_IMPL_MASK; 302 hits++; 303 return No_Fault; 304 } 305 306 if (req->flags & PHYSICAL) { 307 req->paddr = req->vaddr; 308 } else { 309 // verify that this is a good virtual address 310 if (!validVirtualAddress(req->vaddr)) { 311 fault(req->vaddr, req->xc); 312 acv++; 313 return ITB_Acv_Fault; 314 } 315 316 // Check for "superpage" mapping: when SP<1> is set, and 317 // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. 318 if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && 319 VA_SPACE(req->vaddr) == 2) { 320 321 // only valid in kernel mode 322 if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) { 323 fault(req->vaddr, req->xc); 324 acv++; 325 return ITB_Acv_Fault; 326 } 327 328 req->paddr = req->vaddr & PA_IMPL_MASK; 329 330 // sign extend the physical address properly 331 if (req->paddr & PA_UNCACHED_BIT_39 || 332 req->paddr & PA_UNCACHED_BIT_40) 333 req->paddr |= 0xf0000000000ULL; 334 else 335 req->paddr &= 0xffffffffffULL; 336 337 } else { 338 // not a physical address: need to look up pte 339 AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), 340 DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 341 342 if (!pte) { 343 fault(req->vaddr, req->xc); 344 misses++; 345 return ITB_Fault_Fault; 346 } 347 348 req->paddr = PA_PFN2PA(pte->ppn) + VA_POFS(req->vaddr & ~3); 349 350 // check permissions for this access 351 if (!(pte->xre & (1 << ICM_CM(ipr[AlphaISA::IPR_ICM])))) { 352 // instruction access fault 353 fault(req->vaddr, req->xc); 354 acv++; 355 return ITB_Acv_Fault; 356 } 357 358 hits++; 359 } 360 } 361 362 // check that the physical address is ok (catch bad physical addresses) 363 if (req->paddr & ~PA_IMPL_MASK) 364 return Machine_Check_Fault; 365 366 checkCacheability(req); 367 368 return No_Fault; 369} 370 371/////////////////////////////////////////////////////////////////////// 372// 373// Alpha DTB 374// 375AlphaDTB::AlphaDTB(const std::string &name, int size) 376 : AlphaTLB(name, size) 377{} 378 379void 380AlphaDTB::regStats() 381{ 382 read_hits 383 .name(name() + ".read_hits") 384 .desc("DTB read hits") 385 ; 386 387 read_misses 388 .name(name() + ".read_misses") 389 .desc("DTB read misses") 390 ; 391 392 read_acv 393 .name(name() + ".read_acv") 394 .desc("DTB read access violations") 395 ; 396 397 read_accesses 398 .name(name() + ".read_accesses") 399 .desc("DTB read accesses") 400 ; 401 402 write_hits 403 .name(name() + ".write_hits") 404 .desc("DTB write hits") 405 ; 406 407 write_misses 408 .name(name() + ".write_misses") 409 .desc("DTB write misses") 410 ; 411 412 write_acv 413 .name(name() + ".write_acv") 414 .desc("DTB write access violations") 415 ; 416 417 write_accesses 418 .name(name() + ".write_accesses") 419 .desc("DTB write accesses") 420 ; 421 422 hits 423 .name(name() + ".hits") 424 .desc("DTB hits") 425 ; 426 427 misses 428 .name(name() + ".misses") 429 .desc("DTB misses") 430 ; 431 432 acv 433 .name(name() + ".acv") 434 .desc("DTB access violations") 435 ; 436 437 accesses 438 .name(name() + ".accesses") 439 .desc("DTB accesses") 440 ; 441 442 hits = read_hits + write_hits; 443 misses = read_misses + write_misses; 444 acv = read_acv + write_acv; 445 accesses = read_accesses + write_accesses; 446} 447 448void 449AlphaDTB::fault(Addr vaddr, uint64_t flags, ExecContext *xc) const 450{ 451 uint64_t *ipr = xc->regs.ipr; 452 453 // set fault address and flags 454 if (!xc->misspeculating() && !xc->regs.intrlock) { 455 // set VA register with faulting address 456 ipr[AlphaISA::IPR_VA] = vaddr; 457 458 // set MM_STAT register flags 459 ipr[AlphaISA::IPR_MM_STAT] = (((xc->regs.opcode & 0x3f) << 11) 460 | ((xc->regs.ra & 0x1f) << 6) 461 | (flags & 0x3f)); 462 463 // set VA_FORM register with faulting formatted address 464 ipr[AlphaISA::IPR_VA_FORM] = 465 ipr[AlphaISA::IPR_MVPTBR] | (VA_VPN(vaddr) << 3); 466 467 // lock these registers until the VA register is read 468 xc->regs.intrlock = true; 469 } 470} 471 472Fault 473AlphaDTB::translate(MemReqPtr &req, bool write) const 474{ 475 RegFile *regs = &req->xc->regs; 476 Addr pc = regs->pc; 477 InternalProcReg *ipr = regs->ipr; 478 479 AlphaISA::mode_type mode = 480 (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]); 481 482 if (PC_PAL(pc)) { 483 mode = (req->flags & ALTMODE) ? 484 (AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE]) 485 : AlphaISA::mode_kernel; 486 } 487 488 if (req->flags & PHYSICAL) { 489 req->paddr = req->vaddr; 490 } else { 491 // verify that this is a good virtual address 492 if (!validVirtualAddress(req->vaddr)) { 493 fault(req->vaddr, 494 ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | 495 MM_STAT_ACV_MASK), 496 req->xc); 497 498 if (write) { write_acv++; } else { read_acv++; } 499 return DTB_Fault_Fault; 500 } 501 502 // Check for "superpage" mapping: when SP<1> is set, and 503 // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. 504 if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && 505 VA_SPACE(req->vaddr) == 2) { 506 507 // only valid in kernel mode 508 if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != 509 AlphaISA::mode_kernel) { 510 fault(req->vaddr, 511 ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK), 512 req->xc); 513 if (write) { write_acv++; } else { read_acv++; } 514 return DTB_Acv_Fault; 515 } 516 517 req->paddr = req->vaddr & PA_IMPL_MASK; 518 519 // sign extend the physical address properly 520 if (req->paddr & PA_UNCACHED_BIT_39 || 521 req->paddr & PA_UNCACHED_BIT_40) 522 req->paddr |= 0xf0000000000ULL; 523 else 524 req->paddr &= 0xffffffffffULL; 525 526 } else { 527 if (write) 528 write_accesses++; 529 else 530 read_accesses++; 531 532 // not a physical address: need to look up pte 533 AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), 534 DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 535 536 if (!pte) { 537 // page fault 538 fault(req->vaddr, 539 ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK), 540 req->xc); 541 if (write) { write_misses++; } else { read_misses++; } 542 return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault; 543 } 544 545 req->paddr = PA_PFN2PA(pte->ppn) | VA_POFS(req->vaddr); 546 547 if (write) { 548 if (!(pte->xwe & MODE2MASK(mode))) { 549 // declare the instruction access fault 550 fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_ACV_MASK | 551 (pte->fonw ? MM_STAT_FONW_MASK : 0), 552 req->xc); 553 write_acv++; 554 return DTB_Fault_Fault; 555 } 556 if (pte->fonw) { 557 fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_FONW_MASK, 558 req->xc); 559 write_acv++; 560 return DTB_Fault_Fault; 561 } 562 } else { 563 if (!(pte->xre & MODE2MASK(mode))) { 564 fault(req->vaddr, 565 MM_STAT_ACV_MASK | 566 (pte->fonr ? MM_STAT_FONR_MASK : 0), 567 req->xc); 568 read_acv++; 569 return DTB_Acv_Fault; 570 } 571 if (pte->fonr) { 572 fault(req->vaddr, MM_STAT_FONR_MASK, req->xc); 573 read_acv++; 574 return DTB_Fault_Fault; 575 } 576 } 577 } 578 579 if (write) 580 write_hits++; 581 else 582 read_hits++; 583 } 584 585 // check that the physical address is ok (catch bad physical addresses) 586 if (req->paddr & ~PA_IMPL_MASK) 587 return Machine_Check_Fault; 588 589 checkCacheability(req); 590 591 return No_Fault; 592} 593 594AlphaISA::PTE & 595AlphaTLB::index(bool advance) 596{ 597 AlphaISA::PTE *pte = &table[nlu]; 598 599 if (advance) 600 nextnlu(); 601 602 return *pte; 603} 604 605DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", AlphaTLB) 606 607BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaITB) 608 609 Param<int> size; 610 611END_DECLARE_SIM_OBJECT_PARAMS(AlphaITB) 612 613BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaITB) 614 615 INIT_PARAM_DFLT(size, "TLB size", 48) 616 617END_INIT_SIM_OBJECT_PARAMS(AlphaITB) 618 619 620CREATE_SIM_OBJECT(AlphaITB) 621{ 622 return new AlphaITB(getInstanceName(), size); 623} 624 625REGISTER_SIM_OBJECT("AlphaITB", AlphaITB) 626 627BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB) 628 629 Param<int> size; 630 631END_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB) 632 633BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDTB) 634 635 INIT_PARAM_DFLT(size, "TLB size", 64) 636 637END_INIT_SIM_OBJECT_PARAMS(AlphaDTB) 638 639 640CREATE_SIM_OBJECT(AlphaDTB) 641{ 642 return new AlphaDTB(getInstanceName(), size); 643} 644 645REGISTER_SIM_OBJECT("AlphaDTB", AlphaDTB) 646 647