tlb.cc (5358:e9acb84bbafb) | tlb.cc (5555:07c10d7dd62d) |
---|---|
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; --- 37 unchanged lines hidden (view full) --- 46namespace SparcISA { 47 48TLB::TLB(const Params *p) 49 : BaseTLB(p), size(p->size), usedEntries(0), lastReplaced(0), 50 cacheValid(false) 51{ 52 // To make this work you'll have to change the hypervisor and OS 53 if (size > 64) | 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; --- 37 unchanged lines hidden (view full) --- 46namespace SparcISA { 47 48TLB::TLB(const Params *p) 49 : BaseTLB(p), size(p->size), usedEntries(0), lastReplaced(0), 50 cacheValid(false) 51{ 52 // To make this work you'll have to change the hypervisor and OS 53 if (size > 64) |
54 fatal("SPARC T1 TLB registers don't support more than 64 TLB entries."); | 54 fatal("SPARC T1 TLB registers don't support more than 64 TLB entries"); |
55 56 tlb = new TlbEntry[size]; 57 std::memset(tlb, 0, sizeof(TlbEntry) * size); 58 59 for (int x = 0; x < size; x++) 60 freeList.push_back(&tlb[x]); 61 62 c0_tsb_ps0 = 0; --- 19 unchanged lines hidden (view full) --- 82 } 83} 84 85 86void 87TLB::insert(Addr va, int partition_id, int context_id, bool real, 88 const PageTableEntry& PTE, int entry) 89{ | 55 56 tlb = new TlbEntry[size]; 57 std::memset(tlb, 0, sizeof(TlbEntry) * size); 58 59 for (int x = 0; x < size; x++) 60 freeList.push_back(&tlb[x]); 61 62 c0_tsb_ps0 = 0; --- 19 unchanged lines hidden (view full) --- 82 } 83} 84 85 86void 87TLB::insert(Addr va, int partition_id, int context_id, bool real, 88 const PageTableEntry& PTE, int entry) 89{ |
90 91 | |
92 MapIter i; 93 TlbEntry *new_entry = NULL; 94// TlbRange tr; 95 int x; 96 97 cacheValid = false; 98 va &= ~(PTE.size()-1); 99 /* tr.va = va; 100 tr.size = PTE.size() - 1; 101 tr.contextId = context_id; 102 tr.partitionId = partition_id; 103 tr.real = real; 104*/ 105 | 90 MapIter i; 91 TlbEntry *new_entry = NULL; 92// TlbRange tr; 93 int x; 94 95 cacheValid = false; 96 va &= ~(PTE.size()-1); 97 /* tr.va = va; 98 tr.size = PTE.size() - 1; 99 tr.contextId = context_id; 100 tr.partitionId = partition_id; 101 tr.real = real; 102*/ 103 |
106 DPRINTF(TLB, "TLB: Inserting TLB Entry; va=%#x pa=%#x pid=%d cid=%d r=%d entryid=%d\n", 107 va, PTE.paddr(), partition_id, context_id, (int)real, entry); | 104 DPRINTF(TLB, 105 "TLB: Inserting Entry; va=%#x pa=%#x pid=%d cid=%d r=%d entryid=%d\n", 106 va, PTE.paddr(), partition_id, context_id, (int)real, entry); |
108 109 // Demap any entry that conflicts 110 for (x = 0; x < size; x++) { 111 if (tlb[x].range.real == real && 112 tlb[x].range.partitionId == partition_id && 113 tlb[x].range.va < va + PTE.size() - 1 && 114 tlb[x].range.va + tlb[x].range.size >= va && 115 (real || tlb[x].range.contextId == context_id )) --- 7 unchanged lines hidden (view full) --- 123 tlb[x].used = false; 124 usedEntries--; 125 } 126 lookupTable.erase(tlb[x].range); 127 } 128 } 129 } 130 | 107 108 // Demap any entry that conflicts 109 for (x = 0; x < size; x++) { 110 if (tlb[x].range.real == real && 111 tlb[x].range.partitionId == partition_id && 112 tlb[x].range.va < va + PTE.size() - 1 && 113 tlb[x].range.va + tlb[x].range.size >= va && 114 (real || tlb[x].range.contextId == context_id )) --- 7 unchanged lines hidden (view full) --- 122 tlb[x].used = false; 123 usedEntries--; 124 } 125 lookupTable.erase(tlb[x].range); 126 } 127 } 128 } 129 |
131 | |
132/* 133 i = lookupTable.find(tr); 134 if (i != lookupTable.end()) { 135 i->second->valid = false; 136 if (i->second->used) { 137 i->second->used = false; 138 usedEntries--; 139 } --- 50 unchanged lines hidden (view full) --- 190 new_entry->range.partitionId = partition_id; 191 new_entry->range.contextId = context_id; 192 new_entry->range.real = real; 193 new_entry->pte = PTE; 194 new_entry->used = true;; 195 new_entry->valid = true; 196 usedEntries++; 197 | 130/* 131 i = lookupTable.find(tr); 132 if (i != lookupTable.end()) { 133 i->second->valid = false; 134 if (i->second->used) { 135 i->second->used = false; 136 usedEntries--; 137 } --- 50 unchanged lines hidden (view full) --- 188 new_entry->range.partitionId = partition_id; 189 new_entry->range.contextId = context_id; 190 new_entry->range.real = real; 191 new_entry->pte = PTE; 192 new_entry->used = true;; 193 new_entry->valid = true; 194 usedEntries++; 195 |
198 199 | |
200 i = lookupTable.insert(new_entry->range, new_entry); 201 assert(i != lookupTable.end()); 202 | 196 i = lookupTable.insert(new_entry->range, new_entry); 197 assert(i != lookupTable.end()); 198 |
203 // If all entries have there used bit set, clear it on them all, but the 204 // one we just inserted | 199 // If all entries have their used bit set, clear it on them all, 200 // but the one we just inserted |
205 if (usedEntries == size) { 206 clearUsedBits(); 207 new_entry->used = true; 208 usedEntries++; 209 } | 201 if (usedEntries == size) { 202 clearUsedBits(); 203 new_entry->used = true; 204 usedEntries++; 205 } |
210 | |
211} 212 213 214TlbEntry* | 206} 207 208 209TlbEntry* |
215TLB::lookup(Addr va, int partition_id, bool real, int context_id, bool 216 update_used) | 210TLB::lookup(Addr va, int partition_id, bool real, int context_id, 211 bool update_used) |
217{ 218 MapIter i; 219 TlbRange tr; 220 TlbEntry *t; 221 222 DPRINTF(TLB, "TLB: Looking up entry va=%#x pid=%d cid=%d r=%d\n", 223 va, partition_id, context_id, real); 224 // Assemble full address structure --- 10 unchanged lines hidden (view full) --- 235 return NULL; 236 } 237 238 // Mark the entries used bit and clear other used bits in needed 239 t = i->second; 240 DPRINTF(TLB, "TLB: Valid entry found pa: %#x size: %#x\n", t->pte.paddr(), 241 t->pte.size()); 242 | 212{ 213 MapIter i; 214 TlbRange tr; 215 TlbEntry *t; 216 217 DPRINTF(TLB, "TLB: Looking up entry va=%#x pid=%d cid=%d r=%d\n", 218 va, partition_id, context_id, real); 219 // Assemble full address structure --- 10 unchanged lines hidden (view full) --- 230 return NULL; 231 } 232 233 // Mark the entries used bit and clear other used bits in needed 234 t = i->second; 235 DPRINTF(TLB, "TLB: Valid entry found pa: %#x size: %#x\n", t->pte.paddr(), 236 t->pte.size()); 237 |
243 // Update the used bits only if this is a real access (not a fake one from 244 // virttophys() | 238 // Update the used bits only if this is a real access (not a fake 239 // one from virttophys() |
245 if (!t->used && update_used) { 246 t->used = true; 247 usedEntries++; 248 if (usedEntries == size) { 249 clearUsedBits(); 250 t->used = true; 251 usedEntries++; 252 } --- 46 unchanged lines hidden (view full) --- 299 freeList.push_front(i->second); 300 lookupTable.erase(i); 301 } 302} 303 304void 305TLB::demapContext(int partition_id, int context_id) 306{ | 240 if (!t->used && update_used) { 241 t->used = true; 242 usedEntries++; 243 if (usedEntries == size) { 244 clearUsedBits(); 245 t->used = true; 246 usedEntries++; 247 } --- 46 unchanged lines hidden (view full) --- 294 freeList.push_front(i->second); 295 lookupTable.erase(i); 296 } 297} 298 299void 300TLB::demapContext(int partition_id, int context_id) 301{ |
307 int x; | |
308 DPRINTF(IPR, "TLB: Demapping Context pid=%#d cid=%d\n", 309 partition_id, context_id); 310 cacheValid = false; | 302 DPRINTF(IPR, "TLB: Demapping Context pid=%#d cid=%d\n", 303 partition_id, context_id); 304 cacheValid = false; |
311 for (x = 0; x < size; x++) { | 305 for (int x = 0; x < size; x++) { |
312 if (tlb[x].range.contextId == context_id && 313 tlb[x].range.partitionId == partition_id) { 314 if (tlb[x].valid == true) { 315 freeList.push_front(&tlb[x]); 316 } 317 tlb[x].valid = false; 318 if (tlb[x].used) { 319 tlb[x].used = false; 320 usedEntries--; 321 } 322 lookupTable.erase(tlb[x].range); 323 } 324 } 325} 326 327void 328TLB::demapAll(int partition_id) 329{ | 306 if (tlb[x].range.contextId == context_id && 307 tlb[x].range.partitionId == partition_id) { 308 if (tlb[x].valid == true) { 309 freeList.push_front(&tlb[x]); 310 } 311 tlb[x].valid = false; 312 if (tlb[x].used) { 313 tlb[x].used = false; 314 usedEntries--; 315 } 316 lookupTable.erase(tlb[x].range); 317 } 318 } 319} 320 321void 322TLB::demapAll(int partition_id) 323{ |
330 int x; | |
331 DPRINTF(TLB, "TLB: Demapping All pid=%#d\n", partition_id); 332 cacheValid = false; | 324 DPRINTF(TLB, "TLB: Demapping All pid=%#d\n", partition_id); 325 cacheValid = false; |
333 for (x = 0; x < size; x++) { | 326 for (int x = 0; x < size; x++) { |
334 if (tlb[x].valid && !tlb[x].pte.locked() && 335 tlb[x].range.partitionId == partition_id) { 336 freeList.push_front(&tlb[x]); 337 tlb[x].valid = false; 338 if (tlb[x].used) { 339 tlb[x].used = false; 340 usedEntries--; 341 } 342 lookupTable.erase(tlb[x].range); 343 } 344 } 345} 346 347void 348TLB::invalidateAll() 349{ | 327 if (tlb[x].valid && !tlb[x].pte.locked() && 328 tlb[x].range.partitionId == partition_id) { 329 freeList.push_front(&tlb[x]); 330 tlb[x].valid = false; 331 if (tlb[x].used) { 332 tlb[x].used = false; 333 usedEntries--; 334 } 335 lookupTable.erase(tlb[x].range); 336 } 337 } 338} 339 340void 341TLB::invalidateAll() 342{ |
350 int x; | |
351 cacheValid = false; | 343 cacheValid = false; |
352 | |
353 lookupTable.clear(); | 344 lookupTable.clear(); |
354 for (x = 0; x < size; x++) { | 345 346 for (int x = 0; x < size; x++) { |
355 if (tlb[x].valid == true) 356 freeList.push_back(&tlb[x]); 357 tlb[x].valid = false; 358 tlb[x].used = false; 359 } 360 usedEntries = 0; 361} 362 363uint64_t | 347 if (tlb[x].valid == true) 348 freeList.push_back(&tlb[x]); 349 tlb[x].valid = false; 350 tlb[x].used = false; 351 } 352 usedEntries = 0; 353} 354 355uint64_t |
364TLB::TteRead(int entry) { | 356TLB::TteRead(int entry) 357{ |
365 if (entry >= size) 366 panic("entry: %d\n", entry); 367 368 assert(entry < size); 369 if (tlb[entry].valid) 370 return tlb[entry].pte(); 371 else 372 return (uint64_t)-1ll; 373} 374 375uint64_t | 358 if (entry >= size) 359 panic("entry: %d\n", entry); 360 361 assert(entry < size); 362 if (tlb[entry].valid) 363 return tlb[entry].pte(); 364 else 365 return (uint64_t)-1ll; 366} 367 368uint64_t |
376TLB::TagRead(int entry) { | 369TLB::TagRead(int entry) 370{ |
377 assert(entry < size); 378 uint64_t tag; 379 if (!tlb[entry].valid) 380 return (uint64_t)-1ll; 381 382 tag = tlb[entry].range.contextId; 383 tag |= tlb[entry].range.va; 384 tag |= (uint64_t)tlb[entry].range.partitionId << 61; --- 69 unchanged lines hidden (view full) --- 454 DPRINTF(TLB, "TLB: ITB Request to translate va=%#x size=%d\n", 455 vaddr, req->getSize()); 456 457 // Be fast if we can! 458 if (cacheValid && cacheState == tlbdata) { 459 if (cacheEntry) { 460 if (cacheEntry->range.va < vaddr + sizeof(MachInst) && 461 cacheEntry->range.va + cacheEntry->range.size >= vaddr) { | 371 assert(entry < size); 372 uint64_t tag; 373 if (!tlb[entry].valid) 374 return (uint64_t)-1ll; 375 376 tag = tlb[entry].range.contextId; 377 tag |= tlb[entry].range.va; 378 tag |= (uint64_t)tlb[entry].range.partitionId << 61; --- 69 unchanged lines hidden (view full) --- 448 DPRINTF(TLB, "TLB: ITB Request to translate va=%#x size=%d\n", 449 vaddr, req->getSize()); 450 451 // Be fast if we can! 452 if (cacheValid && cacheState == tlbdata) { 453 if (cacheEntry) { 454 if (cacheEntry->range.va < vaddr + sizeof(MachInst) && 455 cacheEntry->range.va + cacheEntry->range.size >= vaddr) { |
462 req->setPaddr(cacheEntry->pte.paddr() & ~(cacheEntry->pte.size()-1) | 463 vaddr & cacheEntry->pte.size()-1 ); 464 return NoFault; | 456 req->setPaddr(cacheEntry->pte.translate(vaddr)); 457 return NoFault; |
465 } 466 } else { 467 req->setPaddr(vaddr & PAddrImplMask); 468 return NoFault; 469 } 470 } 471 472 bool hpriv = bits(tlbdata,0,0); --- 72 unchanged lines hidden (view full) --- 545 return new InstructionAccessException; 546 } 547 548 // cache translation date for next translation 549 cacheValid = true; 550 cacheState = tlbdata; 551 cacheEntry = e; 552 | 458 } 459 } else { 460 req->setPaddr(vaddr & PAddrImplMask); 461 return NoFault; 462 } 463 } 464 465 bool hpriv = bits(tlbdata,0,0); --- 72 unchanged lines hidden (view full) --- 538 return new InstructionAccessException; 539 } 540 541 // cache translation date for next translation 542 cacheValid = true; 543 cacheState = tlbdata; 544 cacheEntry = e; 545 |
553 req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) | 554 vaddr & e->pte.size()-1 ); | 546 req->setPaddr(e->pte.translate(vaddr)); |
555 DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); 556 return NoFault; 557} 558 | 547 DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); 548 return NoFault; 549} 550 |
559 560 | |
561Fault 562DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) 563{ | 551Fault 552DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) 553{ |
564 /* @todo this could really use some profiling and fixing to make it faster! */ | 554 /* 555 * @todo this could really use some profiling and fixing to make 556 * it faster! 557 */ |
565 uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA); 566 Addr vaddr = req->getVaddr(); 567 Addr size = req->getSize(); 568 ASI asi; 569 asi = (ASI)req->getAsi(); 570 bool implicit = false; 571 bool hpriv = bits(tlbdata,0,0); 572 bool unaligned = (vaddr & size-1); --- 21 unchanged lines hidden (view full) --- 594 595 596 if (cacheEntry[0]) { 597 TlbEntry *ce = cacheEntry[0]; 598 Addr ce_va = ce->range.va; 599 if (cacheAsi[0] == asi && 600 ce_va < vaddr + size && ce_va + ce->range.size > vaddr && 601 (!write || ce->pte.writable())) { | 558 uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA); 559 Addr vaddr = req->getVaddr(); 560 Addr size = req->getSize(); 561 ASI asi; 562 asi = (ASI)req->getAsi(); 563 bool implicit = false; 564 bool hpriv = bits(tlbdata,0,0); 565 bool unaligned = (vaddr & size-1); --- 21 unchanged lines hidden (view full) --- 587 588 589 if (cacheEntry[0]) { 590 TlbEntry *ce = cacheEntry[0]; 591 Addr ce_va = ce->range.va; 592 if (cacheAsi[0] == asi && 593 ce_va < vaddr + size && ce_va + ce->range.size > vaddr && 594 (!write || ce->pte.writable())) { |
602 req->setPaddr(ce->pte.paddrMask() | vaddr & ce->pte.sizeMask()); 603 if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) 604 req->setFlags(req->getFlags() | UNCACHEABLE); 605 DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); 606 return NoFault; | 595 req->setPaddr(ce->pte.translate(vaddr)); 596 if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) 597 req->setFlags(req->getFlags() | UNCACHEABLE); 598 DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); 599 return NoFault; |
607 } // if matched 608 } // if cache entry valid 609 if (cacheEntry[1]) { 610 TlbEntry *ce = cacheEntry[1]; 611 Addr ce_va = ce->range.va; 612 if (cacheAsi[1] == asi && 613 ce_va < vaddr + size && ce_va + ce->range.size > vaddr && 614 (!write || ce->pte.writable())) { | 600 } // if matched 601 } // if cache entry valid 602 if (cacheEntry[1]) { 603 TlbEntry *ce = cacheEntry[1]; 604 Addr ce_va = ce->range.va; 605 if (cacheAsi[1] == asi && 606 ce_va < vaddr + size && ce_va + ce->range.size > vaddr && 607 (!write || ce->pte.writable())) { |
615 req->setPaddr(ce->pte.paddrMask() | vaddr & ce->pte.sizeMask()); 616 if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) 617 req->setFlags(req->getFlags() | UNCACHEABLE); 618 DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); 619 return NoFault; | 608 req->setPaddr(ce->pte.translate(vaddr)); 609 if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) 610 req->setFlags(req->getFlags() | UNCACHEABLE); 611 DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); 612 return NoFault; |
620 } // if matched 621 } // if cache entry valid 622 } 623 } 624 625 bool red = bits(tlbdata,1,1); 626 bool priv = bits(tlbdata,2,2); 627 bool addr_mask = bits(tlbdata,3,3); --- 6 unchanged lines hidden (view full) --- 634 635 bool real = false; 636 ContextType ct = Primary; 637 int context = 0; 638 639 TlbEntry *e; 640 641 DPRINTF(TLB, "TLB: priv:%d hpriv:%d red:%d lsudm:%d part_id: %#X\n", | 613 } // if matched 614 } // if cache entry valid 615 } 616 } 617 618 bool red = bits(tlbdata,1,1); 619 bool priv = bits(tlbdata,2,2); 620 bool addr_mask = bits(tlbdata,3,3); --- 6 unchanged lines hidden (view full) --- 627 628 bool real = false; 629 ContextType ct = Primary; 630 int context = 0; 631 632 TlbEntry *e; 633 634 DPRINTF(TLB, "TLB: priv:%d hpriv:%d red:%d lsudm:%d part_id: %#X\n", |
642 priv, hpriv, red, lsu_dm, part_id); | 635 priv, hpriv, red, lsu_dm, part_id); |
643 644 if (implicit) { 645 if (tl > 0) { 646 asi = ASI_N; 647 ct = Nucleus; 648 context = 0; 649 } else { 650 asi = ASI_P; --- 69 unchanged lines hidden (view full) --- 720 if (addr_mask) 721 vaddr = vaddr & VAddrAMask; 722 723 if (!validVirtualAddress(vaddr, addr_mask)) { 724 writeSfsr(vaddr, false, ct, true, VaOutOfRange, asi); 725 return new DataAccessException; 726 } 727 | 636 637 if (implicit) { 638 if (tl > 0) { 639 asi = ASI_N; 640 ct = Nucleus; 641 context = 0; 642 } else { 643 asi = ASI_P; --- 69 unchanged lines hidden (view full) --- 713 if (addr_mask) 714 vaddr = vaddr & VAddrAMask; 715 716 if (!validVirtualAddress(vaddr, addr_mask)) { 717 writeSfsr(vaddr, false, ct, true, VaOutOfRange, asi); 718 return new DataAccessException; 719 } 720 |
728 | |
729 if ((!lsu_dm && !hpriv && !red) || AsiIsReal(asi)) { 730 real = true; 731 context = 0; | 721 if ((!lsu_dm && !hpriv && !red) || AsiIsReal(asi)) { 722 real = true; 723 context = 0; |
732 }; | 724 } |
733 734 if (hpriv && (implicit || (!AsiIsAsIfUser(asi) && !AsiIsReal(asi)))) { 735 req->setPaddr(vaddr & PAddrImplMask); 736 return NoFault; 737 } 738 739 e = lookup(vaddr, part_id, real, context); 740 --- 30 unchanged lines hidden (view full) --- 771 } 772 773 if (e->pte.sideffect() && AsiIsNoFault(asi)) { 774 writeTagAccess(vaddr, context); 775 writeSfsr(vaddr, write, ct, e->pte.sideffect(), SideEffect, asi); 776 return new DataAccessException; 777 } 778 | 725 726 if (hpriv && (implicit || (!AsiIsAsIfUser(asi) && !AsiIsReal(asi)))) { 727 req->setPaddr(vaddr & PAddrImplMask); 728 return NoFault; 729 } 730 731 e = lookup(vaddr, part_id, real, context); 732 --- 30 unchanged lines hidden (view full) --- 763 } 764 765 if (e->pte.sideffect() && AsiIsNoFault(asi)) { 766 writeTagAccess(vaddr, context); 767 writeSfsr(vaddr, write, ct, e->pte.sideffect(), SideEffect, asi); 768 return new DataAccessException; 769 } 770 |
779 | |
780 if (e->pte.sideffect() || (e->pte.paddr() >> 39) & 1) 781 req->setFlags(req->getFlags() | UNCACHEABLE); 782 783 // cache translation date for next translation 784 cacheState = tlbdata; 785 if (!cacheValid) { 786 cacheEntry[1] = NULL; 787 cacheEntry[0] = NULL; 788 } 789 790 if (cacheEntry[0] != e && cacheEntry[1] != e) { 791 cacheEntry[1] = cacheEntry[0]; 792 cacheEntry[0] = e; 793 cacheAsi[1] = cacheAsi[0]; 794 cacheAsi[0] = asi; 795 if (implicit) 796 cacheAsi[0] = (ASI)0; 797 } 798 cacheValid = true; | 771 if (e->pte.sideffect() || (e->pte.paddr() >> 39) & 1) 772 req->setFlags(req->getFlags() | UNCACHEABLE); 773 774 // cache translation date for next translation 775 cacheState = tlbdata; 776 if (!cacheValid) { 777 cacheEntry[1] = NULL; 778 cacheEntry[0] = NULL; 779 } 780 781 if (cacheEntry[0] != e && cacheEntry[1] != e) { 782 cacheEntry[1] = cacheEntry[0]; 783 cacheEntry[0] = e; 784 cacheAsi[1] = cacheAsi[0]; 785 cacheAsi[0] = asi; 786 if (implicit) 787 cacheAsi[0] = (ASI)0; 788 } 789 cacheValid = true; |
799 req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) | 800 vaddr & e->pte.size()-1); | 790 req->setPaddr(e->pte.translate(vaddr)); |
801 DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); 802 return NoFault; 803 804 /** Normal flow ends here. */ 805handleIntRegAccess: 806 if (!hpriv) { 807 writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi); 808 if (priv) --- 55 unchanged lines hidden (view full) --- 864{ 865 Addr va = pkt->getAddr(); 866 ASI asi = (ASI)pkt->req->getAsi(); 867 uint64_t temp; 868 869 DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n", 870 (uint32_t)pkt->req->getAsi(), pkt->getAddr()); 871 | 791 DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); 792 return NoFault; 793 794 /** Normal flow ends here. */ 795handleIntRegAccess: 796 if (!hpriv) { 797 writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi); 798 if (priv) --- 55 unchanged lines hidden (view full) --- 854{ 855 Addr va = pkt->getAddr(); 856 ASI asi = (ASI)pkt->req->getAsi(); 857 uint64_t temp; 858 859 DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n", 860 (uint32_t)pkt->req->getAsi(), pkt->getAddr()); 861 |
872 ITB * itb = tc->getITBPtr(); | 862 ITB *itb = tc->getITBPtr(); |
873 874 switch (asi) { 875 case ASI_LSU_CONTROL_REG: 876 assert(va == 0); 877 pkt->set(tc->readMiscReg(MISCREG_MMU_LSU_CTRL)); 878 break; 879 case ASI_MMU: 880 switch (va) { --- 169 unchanged lines hidden (view full) --- 1050 bool ignore; 1051 int part_id; 1052 int ctx_id; 1053 PageTableEntry pte; 1054 1055 DPRINTF(IPR, "Memory Mapped IPR Write: asi=%#X a=%#x d=%#X\n", 1056 (uint32_t)asi, va, data); 1057 | 863 864 switch (asi) { 865 case ASI_LSU_CONTROL_REG: 866 assert(va == 0); 867 pkt->set(tc->readMiscReg(MISCREG_MMU_LSU_CTRL)); 868 break; 869 case ASI_MMU: 870 switch (va) { --- 169 unchanged lines hidden (view full) --- 1040 bool ignore; 1041 int part_id; 1042 int ctx_id; 1043 PageTableEntry pte; 1044 1045 DPRINTF(IPR, "Memory Mapped IPR Write: asi=%#X a=%#x d=%#X\n", 1046 (uint32_t)asi, va, data); 1047 |
1058 ITB * itb = tc->getITBPtr(); | 1048 ITB *itb = tc->getITBPtr(); |
1059 1060 switch (asi) { 1061 case ASI_LSU_CONTROL_REG: 1062 assert(va == 0); 1063 tc->setMiscReg(MISCREG_MMU_LSU_CTRL, data); 1064 break; 1065 case ASI_MMU: 1066 switch (va) { --- 101 unchanged lines hidden (view full) --- 1168 assert(entry_insert != -1 || mbits(va,10,9) == va); 1169 ta_insert = tag_access; 1170 va_insert = mbits(ta_insert, 63,13); 1171 ct_insert = mbits(ta_insert, 12,0); 1172 part_insert = tc->readMiscReg(MISCREG_MMU_PART_ID); 1173 real_insert = bits(va, 9,9); 1174 pte.populate(data, bits(va,10,10) ? PageTableEntry::sun4v : 1175 PageTableEntry::sun4u); | 1049 1050 switch (asi) { 1051 case ASI_LSU_CONTROL_REG: 1052 assert(va == 0); 1053 tc->setMiscReg(MISCREG_MMU_LSU_CTRL, data); 1054 break; 1055 case ASI_MMU: 1056 switch (va) { --- 101 unchanged lines hidden (view full) --- 1158 assert(entry_insert != -1 || mbits(va,10,9) == va); 1159 ta_insert = tag_access; 1160 va_insert = mbits(ta_insert, 63,13); 1161 ct_insert = mbits(ta_insert, 12,0); 1162 part_insert = tc->readMiscReg(MISCREG_MMU_PART_ID); 1163 real_insert = bits(va, 9,9); 1164 pte.populate(data, bits(va,10,10) ? PageTableEntry::sun4v : 1165 PageTableEntry::sun4u); |
1176 insert(va_insert, part_insert, ct_insert, real_insert, pte, entry_insert); | 1166 insert(va_insert, part_insert, ct_insert, real_insert, pte, 1167 entry_insert); |
1177 break; 1178 case ASI_IMMU_DEMAP: 1179 ignore = false; 1180 ctx_id = -1; 1181 part_id = tc->readMiscReg(MISCREG_MMU_PART_ID); 1182 switch (bits(va,5,4)) { 1183 case 0: 1184 ctx_id = tc->readMiscReg(MISCREG_MMU_P_CONTEXT); --- 82 unchanged lines hidden (view full) --- 1267 msb = findMsbSet(tc->getCpuPtr()->get_interrupts(IT_INT_VEC) & data); 1268 tc->getCpuPtr()->clear_interrupt(IT_INT_VEC, msb); 1269 } 1270 break; 1271 case ASI_SWVR_UDB_INTR_W: 1272 tc->getSystemPtr()->threadContexts[bits(data,12,8)]->getCpuPtr()-> 1273 post_interrupt(bits(data,5,0),0); 1274 break; | 1168 break; 1169 case ASI_IMMU_DEMAP: 1170 ignore = false; 1171 ctx_id = -1; 1172 part_id = tc->readMiscReg(MISCREG_MMU_PART_ID); 1173 switch (bits(va,5,4)) { 1174 case 0: 1175 ctx_id = tc->readMiscReg(MISCREG_MMU_P_CONTEXT); --- 82 unchanged lines hidden (view full) --- 1258 msb = findMsbSet(tc->getCpuPtr()->get_interrupts(IT_INT_VEC) & data); 1259 tc->getCpuPtr()->clear_interrupt(IT_INT_VEC, msb); 1260 } 1261 break; 1262 case ASI_SWVR_UDB_INTR_W: 1263 tc->getSystemPtr()->threadContexts[bits(data,12,8)]->getCpuPtr()-> 1264 post_interrupt(bits(data,5,0),0); 1265 break; |
1275 default: | 1266 default: |
1276doMmuWriteError: 1277 panic("need to impl DTB::doMmuRegWrite() got asi=%#x, va=%#x d=%#x\n", 1278 (uint32_t)pkt->req->getAsi(), pkt->getAddr(), data); 1279 } 1280 pkt->makeAtomicResponse(); 1281 return tc->getCpuPtr()->ticks(1); 1282} 1283 --- 21 unchanged lines hidden (view full) --- 1305 itb->cx_config); 1306 ptrs[3] = MakeTsbPtr(Ps1, tag_access, 1307 itb->c0_tsb_ps1, 1308 itb->c0_config, 1309 itb->cx_tsb_ps1, 1310 itb->cx_config); 1311} 1312 | 1267doMmuWriteError: 1268 panic("need to impl DTB::doMmuRegWrite() got asi=%#x, va=%#x d=%#x\n", 1269 (uint32_t)pkt->req->getAsi(), pkt->getAddr(), data); 1270 } 1271 pkt->makeAtomicResponse(); 1272 return tc->getCpuPtr()->ticks(1); 1273} 1274 --- 21 unchanged lines hidden (view full) --- 1296 itb->cx_config); 1297 ptrs[3] = MakeTsbPtr(Ps1, tag_access, 1298 itb->c0_tsb_ps1, 1299 itb->c0_config, 1300 itb->cx_tsb_ps1, 1301 itb->cx_config); 1302} 1303 |
1313 1314 1315 1316 | |
1317uint64_t 1318DTB::MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb, 1319 uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config) 1320{ 1321 uint64_t tsb; 1322 uint64_t config; 1323 1324 if (bits(tag_access, 12,0) == 0) { --- 11 unchanged lines hidden (view full) --- 1336 1337 if (ps == Ps1 && split) 1338 ptr |= ULL(1) << (13 + tsb_size); 1339 ptr |= (tag_access >> (9 + page_size * 3)) & mask(12+tsb_size, 4); 1340 1341 return ptr; 1342} 1343 | 1304uint64_t 1305DTB::MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb, 1306 uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config) 1307{ 1308 uint64_t tsb; 1309 uint64_t config; 1310 1311 if (bits(tag_access, 12,0) == 0) { --- 11 unchanged lines hidden (view full) --- 1323 1324 if (ps == Ps1 && split) 1325 ptr |= ULL(1) << (13 + tsb_size); 1326 ptr |= (tag_access >> (9 + page_size * 3)) & mask(12+tsb_size, 4); 1327 1328 return ptr; 1329} 1330 |
1344 | |
1345void 1346TLB::serialize(std::ostream &os) 1347{ 1348 SERIALIZE_SCALAR(size); 1349 SERIALIZE_SCALAR(usedEntries); 1350 SERIALIZE_SCALAR(lastReplaced); 1351 1352 // convert the pointer based free list into an index based one --- 91 unchanged lines hidden --- | 1331void 1332TLB::serialize(std::ostream &os) 1333{ 1334 SERIALIZE_SCALAR(size); 1335 SERIALIZE_SCALAR(usedEntries); 1336 SERIALIZE_SCALAR(lastReplaced); 1337 1338 // convert the pointer based free list into an index based one --- 91 unchanged lines hidden --- |