tlb.cc (5568:d14250d688d2) | tlb.cc (5569:baeee670d4ce) |
---|---|
1/* 2 * Copyright (c) 2001-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 31 unchanged lines hidden (view full) --- 40#include "base/str.hh" 41#include "base/trace.hh" 42#include "config/alpha_tlaser.hh" 43#include "cpu/thread_context.hh" 44 45using namespace std; 46 47namespace AlphaISA { | 1/* 2 * Copyright (c) 2001-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 31 unchanged lines hidden (view full) --- 40#include "base/str.hh" 41#include "base/trace.hh" 42#include "config/alpha_tlaser.hh" 43#include "cpu/thread_context.hh" 44 45using namespace std; 46 47namespace AlphaISA { |
48 |
|
48/////////////////////////////////////////////////////////////////////// 49// 50// Alpha TLB 51// | 49/////////////////////////////////////////////////////////////////////// 50// 51// Alpha TLB 52// |
53 |
|
52#ifdef DEBUG 53bool uncacheBit39 = false; 54bool uncacheBit40 = false; 55#endif 56 | 54#ifdef DEBUG 55bool uncacheBit39 = false; 56bool uncacheBit40 = false; 57#endif 58 |
57#define MODE2MASK(X) (1 << (X)) | 59#define MODE2MASK(X) (1 << (X)) |
58 59TLB::TLB(const Params *p) 60 : BaseTLB(p), size(p->size), nlu(0) 61{ 62 table = new TlbEntry[size]; 63 memset(table, 0, sizeof(TlbEntry[size])); 64 flushCache(); 65} --- 42 unchanged lines hidden (view full) --- 108 } 109 } 110 111 DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, 112 retval ? "hit" : "miss", retval ? retval->ppn : 0); 113 return retval; 114} 115 | 60 61TLB::TLB(const Params *p) 62 : BaseTLB(p), size(p->size), nlu(0) 63{ 64 table = new TlbEntry[size]; 65 memset(table, 0, sizeof(TlbEntry[size])); 66 flushCache(); 67} --- 42 unchanged lines hidden (view full) --- 110 } 111 } 112 113 DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, 114 retval ? "hit" : "miss", retval ? retval->ppn : 0); 115 return retval; 116} 117 |
116 | |
117Fault 118TLB::checkCacheability(RequestPtr &req, bool itb) 119{ | 118Fault 119TLB::checkCacheability(RequestPtr &req, bool itb) 120{ |
120// in Alpha, cacheability is controlled by upper-level bits of the 121// physical address | 121 // in Alpha, cacheability is controlled by upper-level bits of the 122 // physical address |
122 | 123 |
123/* 124 * We support having the uncacheable bit in either bit 39 or bit 40. 125 * The Turbolaser platform (and EV5) support having the bit in 39, but 126 * Tsunami (which Linux assumes uses an EV6) generates accesses with 127 * the bit in 40. So we must check for both, but we have debug flags 128 * to catch a weird case where both are used, which shouldn't happen. 129 */ | 124 /* 125 * We support having the uncacheable bit in either bit 39 or bit 126 * 40. The Turbolaser platform (and EV5) support having the bit 127 * in 39, but Tsunami (which Linux assumes uses an EV6) generates 128 * accesses with the bit in 40. So we must check for both, but we 129 * have debug flags to catch a weird case where both are used, 130 * which shouldn't happen. 131 */ |
130 131 132#if ALPHA_TLASER 133 if (req->getPaddr() & PAddrUncachedBit39) 134#else 135 if (req->getPaddr() & PAddrUncachedBit43) 136#endif 137 { 138 // IPR memory space not implemented 139 if (PAddrIprSpace(req->getPaddr())) { 140 return new UnimpFault("IPR memory space not implemented!"); 141 } else { 142 // mark request as uncacheable 143 req->setFlags(req->getFlags() | UNCACHEABLE); 144 145#if !ALPHA_TLASER | 132 133 134#if ALPHA_TLASER 135 if (req->getPaddr() & PAddrUncachedBit39) 136#else 137 if (req->getPaddr() & PAddrUncachedBit43) 138#endif 139 { 140 // IPR memory space not implemented 141 if (PAddrIprSpace(req->getPaddr())) { 142 return new UnimpFault("IPR memory space not implemented!"); 143 } else { 144 // mark request as uncacheable 145 req->setFlags(req->getFlags() | UNCACHEABLE); 146 147#if !ALPHA_TLASER |
146 // Clear bits 42:35 of the physical address (10-2 in Tsunami manual) | 148 // Clear bits 42:35 of the physical address (10-2 in 149 // Tsunami manual) |
147 req->setPaddr(req->getPaddr() & PAddrUncachedMask); 148#endif 149 } 150 // We shouldn't be able to read from an uncachable address in Alpha as 151 // we don't have a ROM and we don't want to try to fetch from a device 152 // register as we destroy any data that is clear-on-read. 153 if (req->isUncacheable() && itb) 154 return new UnimpFault("CPU trying to fetch from uncached I/O"); --- 61 unchanged lines hidden (view full) --- 216 assert(entry->valid); 217 218 // we can't increment i after we erase it, so save a copy and 219 // increment it to get the next entry now 220 PageTable::iterator cur = i; 221 ++i; 222 223 if (!entry->asma) { | 150 req->setPaddr(req->getPaddr() & PAddrUncachedMask); 151#endif 152 } 153 // We shouldn't be able to read from an uncachable address in Alpha as 154 // we don't have a ROM and we don't want to try to fetch from a device 155 // register as we destroy any data that is clear-on-read. 156 if (req->isUncacheable() && itb) 157 return new UnimpFault("CPU trying to fetch from uncached I/O"); --- 61 unchanged lines hidden (view full) --- 219 assert(entry->valid); 220 221 // we can't increment i after we erase it, so save a copy and 222 // increment it to get the next entry now 223 PageTable::iterator cur = i; 224 ++i; 225 226 if (!entry->asma) { |
224 DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, entry->tag, entry->ppn); | 227 DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, 228 entry->tag, entry->ppn); |
225 entry->valid = false; 226 lookupTable.erase(cur); 227 } 228 } 229} 230 231void 232TLB::flushAddr(Addr addr, uint8_t asn) --- 46 unchanged lines hidden (view full) --- 279 for (int i = 0; i < size; i++) { 280 table[i].unserialize(cp, csprintf("%s.Entry%d", section, i)); 281 if (table[i].valid) { 282 lookupTable.insert(make_pair(table[i].tag, i)); 283 } 284 } 285} 286 | 229 entry->valid = false; 230 lookupTable.erase(cur); 231 } 232 } 233} 234 235void 236TLB::flushAddr(Addr addr, uint8_t asn) --- 46 unchanged lines hidden (view full) --- 283 for (int i = 0; i < size; i++) { 284 table[i].unserialize(cp, csprintf("%s.Entry%d", section, i)); 285 if (table[i].valid) { 286 lookupTable.insert(make_pair(table[i].tag, i)); 287 } 288 } 289} 290 |
287 | |
288/////////////////////////////////////////////////////////////////////// 289// 290// Alpha ITB 291// 292ITB::ITB(const Params *p) 293 : TLB(p) 294{} 295 --- 12 unchanged lines hidden (view full) --- 308 .desc("ITB acv"); 309 accesses 310 .name(name() + ".accesses") 311 .desc("ITB accesses"); 312 313 accesses = hits + misses; 314} 315 | 291/////////////////////////////////////////////////////////////////////// 292// 293// Alpha ITB 294// 295ITB::ITB(const Params *p) 296 : TLB(p) 297{} 298 --- 12 unchanged lines hidden (view full) --- 311 .desc("ITB acv"); 312 accesses 313 .name(name() + ".accesses") 314 .desc("ITB accesses"); 315 316 accesses = hits + misses; 317} 318 |
316 | |
317Fault 318ITB::translate(RequestPtr &req, ThreadContext *tc) 319{ 320 //If this is a pal pc, then set PHYSICAL | 319Fault 320ITB::translate(RequestPtr &req, ThreadContext *tc) 321{ 322 //If this is a pal pc, then set PHYSICAL |
321 if(FULL_SYSTEM && PcPAL(req->getPC())) | 323 if (FULL_SYSTEM && PcPAL(req->getPC())) |
322 req->setFlags(req->getFlags() | PHYSICAL); 323 324 if (PcPAL(req->getPC())) { 325 // strip off PAL PC marker (lsb is 1) 326 req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask); 327 hits++; 328 return NoFault; 329 } --- 68 unchanged lines hidden (view full) --- 398 return checkCacheability(req, true); 399 400} 401 402/////////////////////////////////////////////////////////////////////// 403// 404// Alpha DTB 405// | 324 req->setFlags(req->getFlags() | PHYSICAL); 325 326 if (PcPAL(req->getPC())) { 327 // strip off PAL PC marker (lsb is 1) 328 req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask); 329 hits++; 330 return NoFault; 331 } --- 68 unchanged lines hidden (view full) --- 400 return checkCacheability(req, true); 401 402} 403 404/////////////////////////////////////////////////////////////////////// 405// 406// Alpha DTB 407// |
406 DTB::DTB(const Params *p) | 408DTB::DTB(const Params *p) |
407 : TLB(p) 408{} 409 410void 411DTB::regStats() 412{ 413 read_hits 414 .name(name() + ".read_hits") --- 64 unchanged lines hidden (view full) --- 479Fault 480DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) 481{ 482 Addr pc = tc->readPC(); 483 484 mode_type mode = 485 (mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)); 486 | 409 : TLB(p) 410{} 411 412void 413DTB::regStats() 414{ 415 read_hits 416 .name(name() + ".read_hits") --- 64 unchanged lines hidden (view full) --- 481Fault 482DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) 483{ 484 Addr pc = tc->readPC(); 485 486 mode_type mode = 487 (mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)); 488 |
487 | |
488 /** 489 * Check for alignment faults 490 */ 491 if (req->getVaddr() & (req->getSize() - 1)) { 492 DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(), 493 req->getSize()); 494 uint64_t flags = write ? MM_STAT_WR_MASK : 0; 495 return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags); --- 21 unchanged lines hidden (view full) --- 517 // Check for "superpage" mapping 518#if ALPHA_TLASER 519 if ((MCSR_SP(tc->readMiscRegNoEffect(IPR_MCSR)) & 2) && 520 VAddrSpaceEV5(req->getVaddr()) == 2) 521#else 522 if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) 523#endif 524 { | 489 /** 490 * Check for alignment faults 491 */ 492 if (req->getVaddr() & (req->getSize() - 1)) { 493 DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(), 494 req->getSize()); 495 uint64_t flags = write ? MM_STAT_WR_MASK : 0; 496 return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags); --- 21 unchanged lines hidden (view full) --- 518 // Check for "superpage" mapping 519#if ALPHA_TLASER 520 if ((MCSR_SP(tc->readMiscRegNoEffect(IPR_MCSR)) & 2) && 521 VAddrSpaceEV5(req->getVaddr()) == 2) 522#else 523 if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) 524#endif 525 { |
525 | |
526 // only valid in kernel mode 527 if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) != 528 mode_kernel) { 529 if (write) { write_acv++; } else { read_acv++; } 530 uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) | 531 MM_STAT_ACV_MASK); | 526 // only valid in kernel mode 527 if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) != 528 mode_kernel) { 529 if (write) { write_acv++; } else { read_acv++; } 530 uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) | 531 MM_STAT_ACV_MASK); |
532 return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); | 532 533 return new DtbAcvFault(req->getVaddr(), req->getFlags(), 534 flags); |
533 } 534 535 req->setPaddr(req->getVaddr() & PAddrImplMask); 536 537#if !ALPHA_TLASER 538 // sign extend the physical address properly 539 if (req->getPaddr() & PAddrUncachedBit40) 540 req->setPaddr(req->getPaddr() | ULL(0xf0000000000)); --- 29 unchanged lines hidden (view full) --- 570 571 if (write) { 572 if (!(entry->xwe & MODE2MASK(mode))) { 573 // declare the instruction access fault 574 write_acv++; 575 uint64_t flags = MM_STAT_WR_MASK | 576 MM_STAT_ACV_MASK | 577 (entry->fonw ? MM_STAT_FONW_MASK : 0); | 535 } 536 537 req->setPaddr(req->getVaddr() & PAddrImplMask); 538 539#if !ALPHA_TLASER 540 // sign extend the physical address properly 541 if (req->getPaddr() & PAddrUncachedBit40) 542 req->setPaddr(req->getPaddr() | ULL(0xf0000000000)); --- 29 unchanged lines hidden (view full) --- 572 573 if (write) { 574 if (!(entry->xwe & MODE2MASK(mode))) { 575 // declare the instruction access fault 576 write_acv++; 577 uint64_t flags = MM_STAT_WR_MASK | 578 MM_STAT_ACV_MASK | 579 (entry->fonw ? MM_STAT_FONW_MASK : 0); |
578 return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); | 580 return new DtbPageFault(req->getVaddr(), req->getFlags(), 581 flags); |
579 } 580 if (entry->fonw) { 581 write_acv++; | 582 } 583 if (entry->fonw) { 584 write_acv++; |
582 uint64_t flags = MM_STAT_WR_MASK | 583 MM_STAT_FONW_MASK; 584 return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); | 585 uint64_t flags = MM_STAT_WR_MASK | MM_STAT_FONW_MASK; 586 return new DtbPageFault(req->getVaddr(), req->getFlags(), 587 flags); |
585 } 586 } else { 587 if (!(entry->xre & MODE2MASK(mode))) { 588 read_acv++; 589 uint64_t flags = MM_STAT_ACV_MASK | 590 (entry->fonr ? MM_STAT_FONR_MASK : 0); | 588 } 589 } else { 590 if (!(entry->xre & MODE2MASK(mode))) { 591 read_acv++; 592 uint64_t flags = MM_STAT_ACV_MASK | 593 (entry->fonr ? MM_STAT_FONR_MASK : 0); |
591 return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); | 594 return new DtbAcvFault(req->getVaddr(), req->getFlags(), 595 flags); |
592 } 593 if (entry->fonr) { 594 read_acv++; 595 uint64_t flags = MM_STAT_FONR_MASK; | 596 } 597 if (entry->fonr) { 598 read_acv++; 599 uint64_t flags = MM_STAT_FONR_MASK; |
596 return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); | 600 return new DtbPageFault(req->getVaddr(), req->getFlags(), 601 flags); |
597 } 598 } 599 } 600 601 if (write) 602 write_hits++; 603 else 604 read_hits++; --- 12 unchanged lines hidden (view full) --- 617 TlbEntry *entry = &table[nlu]; 618 619 if (advance) 620 nextnlu(); 621 622 return *entry; 623} 624 | 602 } 603 } 604 } 605 606 if (write) 607 write_hits++; 608 else 609 read_hits++; --- 12 unchanged lines hidden (view full) --- 622 TlbEntry *entry = &table[nlu]; 623 624 if (advance) 625 nextnlu(); 626 627 return *entry; 628} 629 |
625} // namespace AlphaISA | 630/* end namespace AlphaISA */ } |
626 627AlphaISA::ITB * 628AlphaITBParams::create() 629{ 630 return new AlphaISA::ITB(this); 631} 632 633AlphaISA::DTB * 634AlphaDTBParams::create() 635{ 636 return new AlphaISA::DTB(this); 637} | 631 632AlphaISA::ITB * 633AlphaITBParams::create() 634{ 635 return new AlphaISA::ITB(this); 636} 637 638AlphaISA::DTB * 639AlphaDTBParams::create() 640{ 641 return new AlphaISA::DTB(this); 642} |