tlb.cc (3806:65ae5388c059) | tlb.cc (3811:ee71d61347f1) |
---|---|
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; --- 15 unchanged lines hidden (view full) --- 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Ali Saidi 29 */ 30 31#include "arch/sparc/asi.hh" | 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; --- 15 unchanged lines hidden (view full) --- 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Ali Saidi 29 */ 30 31#include "arch/sparc/asi.hh" |
32#include "arch/sparc/tlb.hh" 33#include "sim/builder.hh" | |
34#include "arch/sparc/miscregfile.hh" | 32#include "arch/sparc/miscregfile.hh" |
33#include "arch/sparc/tlb.hh" 34#include "base/trace.hh" |
|
35#include "cpu/thread_context.hh" | 35#include "cpu/thread_context.hh" |
36#include "sim/builder.hh" |
|
36 37/* @todo remove some of the magic constants. -- ali 38 * */ 39namespace SparcISA 40{ 41 42TLB::TLB(const std::string &name, int s) 43 : SimObject(name), size(s) --- 23 unchanged lines hidden (view full) --- 67void 68TLB::insert(Addr va, int partition_id, int context_id, bool real, 69 const PageTableEntry& PTE) 70{ 71 72 73 MapIter i; 74 TlbEntry *new_entry; | 37 38/* @todo remove some of the magic constants. -- ali 39 * */ 40namespace SparcISA 41{ 42 43TLB::TLB(const std::string &name, int s) 44 : SimObject(name), size(s) --- 23 unchanged lines hidden (view full) --- 68void 69TLB::insert(Addr va, int partition_id, int context_id, bool real, 70 const PageTableEntry& PTE) 71{ 72 73 74 MapIter i; 75 TlbEntry *new_entry; |
76 77 DPRINTF(TLB, "TLB: Inserting TLB Entry; va=%#x, pid=%d cid=%d r=%d\n", 78 va, partition_id, context_id, (int)real); 79 |
|
75 int x = -1; 76 for (x = 0; x < size; x++) { 77 if (!tlb[x].valid || !tlb[x].used) { 78 new_entry = &tlb[x]; 79 break; 80 } 81 } 82 --- 16 unchanged lines hidden (view full) --- 99 // Demap any entry that conflicts 100 i = lookupTable.find(new_entry->range); 101 if (i != lookupTable.end()) { 102 i->second->valid = false; 103 if (i->second->used) { 104 i->second->used = false; 105 usedEntries--; 106 } | 80 int x = -1; 81 for (x = 0; x < size; x++) { 82 if (!tlb[x].valid || !tlb[x].used) { 83 new_entry = &tlb[x]; 84 break; 85 } 86 } 87 --- 16 unchanged lines hidden (view full) --- 104 // Demap any entry that conflicts 105 i = lookupTable.find(new_entry->range); 106 if (i != lookupTable.end()) { 107 i->second->valid = false; 108 if (i->second->used) { 109 i->second->used = false; 110 usedEntries--; 111 } |
112 DPRINTF(TLB, "TLB: Found conflicting entry, deleting it\n"); |
|
107 lookupTable.erase(i); 108 } 109 110 lookupTable.insert(new_entry->range, new_entry);; 111 112 // If all entries have there used bit set, clear it on them all, but the 113 // one we just inserted 114 if (usedEntries == size) { --- 7 unchanged lines hidden (view full) --- 122 123TlbEntry* 124TLB::lookup(Addr va, int partition_id, bool real, int context_id) 125{ 126 MapIter i; 127 TlbRange tr; 128 TlbEntry *t; 129 | 113 lookupTable.erase(i); 114 } 115 116 lookupTable.insert(new_entry->range, new_entry);; 117 118 // If all entries have there used bit set, clear it on them all, but the 119 // one we just inserted 120 if (usedEntries == size) { --- 7 unchanged lines hidden (view full) --- 128 129TlbEntry* 130TLB::lookup(Addr va, int partition_id, bool real, int context_id) 131{ 132 MapIter i; 133 TlbRange tr; 134 TlbEntry *t; 135 |
136 DPRINTF(TLB, "TLB: Looking up entry va=%#x pid=%d cid=%d r=%d\n", 137 va, partition_id, context_id, real); |
|
130 // Assemble full address structure 131 tr.va = va; 132 tr.size = va + MachineBytes; 133 tr.contextId = context_id; 134 tr.partitionId = partition_id; 135 tr.real = real; 136 137 // Try to find the entry 138 i = lookupTable.find(tr); 139 if (i == lookupTable.end()) { | 138 // Assemble full address structure 139 tr.va = va; 140 tr.size = va + MachineBytes; 141 tr.contextId = context_id; 142 tr.partitionId = partition_id; 143 tr.real = real; 144 145 // Try to find the entry 146 i = lookupTable.find(tr); 147 if (i == lookupTable.end()) { |
148 DPRINTF(TLB, "TLB: No valid entry found\n"); |
|
140 return NULL; 141 } | 149 return NULL; 150 } |
151 DPRINTF(TLB, "TLB: Valid entry found\n"); |
|
142 143 // Mark the entries used bit and clear other used bits in needed 144 t = i->second; 145 if (!t->used) { 146 t->used = true; 147 usedEntries++; 148 if (usedEntries == size) { 149 clearUsedBits(); --- 124 unchanged lines hidden (view full) --- 274 tc->setMiscReg(reg, sfsr); 275} 276 277 278void 279ITB::writeSfsr(ThreadContext *tc, bool write, ContextType ct, 280 bool se, FaultTypes ft, int asi) 281{ | 152 153 // Mark the entries used bit and clear other used bits in needed 154 t = i->second; 155 if (!t->used) { 156 t->used = true; 157 usedEntries++; 158 if (usedEntries == size) { 159 clearUsedBits(); --- 124 unchanged lines hidden (view full) --- 284 tc->setMiscReg(reg, sfsr); 285} 286 287 288void 289ITB::writeSfsr(ThreadContext *tc, bool write, ContextType ct, 290 bool se, FaultTypes ft, int asi) 291{ |
292 DPRINTF(TLB, "TLB: ITB Fault: w=%d ct=%d ft=%d asi=%d\n", 293 (int)write, ct, ft, asi); |
|
282 TLB::writeSfsr(tc, MISCREG_MMU_ITLB_SFSR, write, ct, se, ft, asi); 283} 284 285void 286DTB::writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct, 287 bool se, FaultTypes ft, int asi) 288{ | 294 TLB::writeSfsr(tc, MISCREG_MMU_ITLB_SFSR, write, ct, se, ft, asi); 295} 296 297void 298DTB::writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct, 299 bool se, FaultTypes ft, int asi) 300{ |
301 DPRINTF(TLB, "TLB: DTB Fault: A=%#x w=%d ct=%d ft=%d asi=%d\n", 302 a, (int)write, ct, ft, asi); |
|
289 TLB::writeSfsr(tc, MISCREG_MMU_DTLB_SFSR, write, ct, se, ft, asi); 290 tc->setMiscReg(MISCREG_MMU_DTLB_SFAR, a); 291} 292 293 294Fault 295ITB::translate(RequestPtr &req, ThreadContext *tc) 296{ --- 6 unchanged lines hidden (view full) --- 303 bool priv = pstate >> 2 & 0x1; 304 Addr vaddr = req->getVaddr(); 305 int context; 306 ContextType ct; 307 int asi; 308 bool real = false; 309 TlbEntry *e; 310 | 303 TLB::writeSfsr(tc, MISCREG_MMU_DTLB_SFSR, write, ct, se, ft, asi); 304 tc->setMiscReg(MISCREG_MMU_DTLB_SFAR, a); 305} 306 307 308Fault 309ITB::translate(RequestPtr &req, ThreadContext *tc) 310{ --- 6 unchanged lines hidden (view full) --- 317 bool priv = pstate >> 2 & 0x1; 318 Addr vaddr = req->getVaddr(); 319 int context; 320 ContextType ct; 321 int asi; 322 bool real = false; 323 TlbEntry *e; 324 |
325 DPRINTF(TLB, "TLB: ITB Request to translate va=%#x size=%d\n", 326 vaddr, req->getSize()); 327 |
|
311 assert(req->getAsi() == ASI_IMPLICIT); 312 313 if (tl > 0) { 314 asi = ASI_N; 315 ct = Nucleus; 316 context = 0; 317 } else { 318 asi = ASI_P; --- 61 unchanged lines hidden (view full) --- 380 uint64_t part_id = tc->readMiscReg(MISCREG_MMU_PART_ID); 381 bool hpriv = hpstate >> 2 & 0x1; 382 bool red = hpstate >> 5 >> 0x1; 383 bool addr_mask = pstate >> 3 & 0x1; 384 bool priv = pstate >> 2 & 0x1; 385 bool implicit = false; 386 bool real = false; 387 Addr vaddr = req->getVaddr(); | 328 assert(req->getAsi() == ASI_IMPLICIT); 329 330 if (tl > 0) { 331 asi = ASI_N; 332 ct = Nucleus; 333 context = 0; 334 } else { 335 asi = ASI_P; --- 61 unchanged lines hidden (view full) --- 397 uint64_t part_id = tc->readMiscReg(MISCREG_MMU_PART_ID); 398 bool hpriv = hpstate >> 2 & 0x1; 399 bool red = hpstate >> 5 >> 0x1; 400 bool addr_mask = pstate >> 3 & 0x1; 401 bool priv = pstate >> 2 & 0x1; 402 bool implicit = false; 403 bool real = false; 404 Addr vaddr = req->getVaddr(); |
405 Addr size = req->getSize(); |
|
388 ContextType ct; 389 int context; 390 ASI asi; 391 392 TlbEntry *e; 393 | 406 ContextType ct; 407 int context; 408 ASI asi; 409 410 TlbEntry *e; 411 |
394 | |
395 asi = (ASI)req->getAsi(); | 412 asi = (ASI)req->getAsi(); |
413 DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n", 414 vaddr, size, asi); 415 |
|
396 if (asi == ASI_IMPLICIT) 397 implicit = true; 398 399 if (implicit) { 400 if (tl > 0) { 401 asi = ASI_N; 402 ct = Nucleus; 403 context = 0; --- 23 unchanged lines hidden (view full) --- 427 if (priv && AsiIsHPriv(asi)) { 428 writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi); 429 return new DataAccessException; 430 } 431 432 } 433 434 // If the asi is unaligned trap | 416 if (asi == ASI_IMPLICIT) 417 implicit = true; 418 419 if (implicit) { 420 if (tl > 0) { 421 asi = ASI_N; 422 ct = Nucleus; 423 context = 0; --- 23 unchanged lines hidden (view full) --- 447 if (priv && AsiIsHPriv(asi)) { 448 writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi); 449 return new DataAccessException; 450 } 451 452 } 453 454 // If the asi is unaligned trap |
435 if (AsiIsBlock(asi) && vaddr & 0x3f || vaddr & 0x7) { | 455 if (vaddr & size-1) { |
436 writeSfr(tc, vaddr, false, ct, false, OtherFault, asi); 437 return new MemAddressNotAligned; 438 } 439 440 if (addr_mask) 441 vaddr = vaddr & VAddrAMask; 442 443 if (!validVirtualAddress(vaddr, addr_mask)) { --- 29 unchanged lines hidden (view full) --- 473 return NoFault; 474 } 475 476 e = lookup(req->getVaddr(), part_id, real, context); 477 478 if (e == NULL || !e->valid) { 479 tc->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS, 480 vaddr & ~BytesInPageMask | context); | 456 writeSfr(tc, vaddr, false, ct, false, OtherFault, asi); 457 return new MemAddressNotAligned; 458 } 459 460 if (addr_mask) 461 vaddr = vaddr & VAddrAMask; 462 463 if (!validVirtualAddress(vaddr, addr_mask)) { --- 29 unchanged lines hidden (view full) --- 493 return NoFault; 494 } 495 496 e = lookup(req->getVaddr(), part_id, real, context); 497 498 if (e == NULL || !e->valid) { 499 tc->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS, 500 vaddr & ~BytesInPageMask | context); |
501 DPRINTF(TLB, "TLB: DTB Failed to find matching TLB entry\n"); |
|
481 if (real) 482 return new DataRealTranslationMiss; 483 else 484 return new FastDataAccessMMUMiss; 485 486 } 487 488 --- 22 unchanged lines hidden (view full) --- 511 /** Normal flow ends here. */ 512 513handleScratchRegAccess: 514 if (vaddr > 0x38 || (vaddr >= 0x20 && vaddr < 0x30 && !hpriv)) { 515 writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi); 516 return new DataAccessException; 517 } 518handleMmuRegAccess: | 502 if (real) 503 return new DataRealTranslationMiss; 504 else 505 return new FastDataAccessMMUMiss; 506 507 } 508 509 --- 22 unchanged lines hidden (view full) --- 532 /** Normal flow ends here. */ 533 534handleScratchRegAccess: 535 if (vaddr > 0x38 || (vaddr >= 0x20 && vaddr < 0x30 && !hpriv)) { 536 writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi); 537 return new DataAccessException; 538 } 539handleMmuRegAccess: |
540 DPRINTF(TLB, "TLB: DTB Translating MM IPR access\n"); |
|
519 req->setMmapedIpr(true); 520 req->setPaddr(req->getVaddr()); 521 return NoFault; 522}; 523 524Tick 525DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) 526{ --- 64 unchanged lines hidden --- | 541 req->setMmapedIpr(true); 542 req->setPaddr(req->getVaddr()); 543 return NoFault; 544}; 545 546Tick 547DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) 548{ --- 64 unchanged lines hidden --- |