tlb.cc (8733:64a7bf8fa56c) | tlb.cc (8756:cce8cf3906ca) |
---|---|
1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 33 unchanged lines hidden (view full) --- 42 * Steve Reinhardt 43 */ 44 45#include <string> 46#include <vector> 47 48#include "arch/arm/faults.hh" 49#include "arch/arm/pagetable.hh" | 1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 33 unchanged lines hidden (view full) --- 42 * Steve Reinhardt 43 */ 44 45#include <string> 46#include <vector> 47 48#include "arch/arm/faults.hh" 49#include "arch/arm/pagetable.hh" |
50#include "arch/arm/table_walker.hh" |
|
50#include "arch/arm/tlb.hh" 51#include "arch/arm/utility.hh" 52#include "base/inifile.hh" 53#include "base/str.hh" 54#include "base/trace.hh" 55#include "cpu/thread_context.hh" 56#include "debug/Checkpoint.hh" 57#include "debug/TLB.hh" 58#include "debug/TLBVerbose.hh" 59#include "mem/page_table.hh" 60#include "params/ArmTLB.hh" | 51#include "arch/arm/tlb.hh" 52#include "arch/arm/utility.hh" 53#include "base/inifile.hh" 54#include "base/str.hh" 55#include "base/trace.hh" 56#include "cpu/thread_context.hh" 57#include "debug/Checkpoint.hh" 58#include "debug/TLB.hh" 59#include "debug/TLBVerbose.hh" 60#include "mem/page_table.hh" 61#include "params/ArmTLB.hh" |
62#include "sim/full_system.hh" |
|
61#include "sim/process.hh" 62 63#if FULL_SYSTEM 64#include "arch/arm/system.hh" | 63#include "sim/process.hh" 64 65#if FULL_SYSTEM 66#include "arch/arm/system.hh" |
65#include "arch/arm/table_walker.hh" | |
66#endif 67 68using namespace std; 69using namespace ArmISA; 70 71TLB::TLB(const Params *p) | 67#endif 68 69using namespace std; 70using namespace ArmISA; 71 72TLB::TLB(const Params *p) |
72 : BaseTLB(p), size(p->size) 73#if FULL_SYSTEM 74 , tableWalker(p->walker) 75#endif 76 , rangeMRU(1), bootUncacheability(false), miscRegValid(false) | 73 : BaseTLB(p), size(p->size) , tableWalker(p->walker), 74 rangeMRU(1), bootUncacheability(false), miscRegValid(false) |
77{ 78 table = new TlbEntry[size]; 79 memset(table, 0, sizeof(TlbEntry) * size); 80 | 75{ 76 table = new TlbEntry[size]; 77 memset(table, 0, sizeof(TlbEntry) * size); 78 |
81#if FULL_SYSTEM | |
82 tableWalker->setTlb(this); | 79 tableWalker->setTlb(this); |
83#endif | |
84} 85 86TLB::~TLB() 87{ 88 if (table) 89 delete [] table; 90} 91 --- 307 unchanged lines hidden (view full) --- 399 instAccesses = instHits + instMisses; 400 readAccesses = readHits + readMisses; 401 writeAccesses = writeHits + writeMisses; 402 hits = readHits + writeHits + instHits; 403 misses = readMisses + writeMisses + instMisses; 404 accesses = readAccesses + writeAccesses + instAccesses; 405} 406 | 80} 81 82TLB::~TLB() 83{ 84 if (table) 85 delete [] table; 86} 87 --- 307 unchanged lines hidden (view full) --- 395 instAccesses = instHits + instMisses; 396 readAccesses = readHits + readMisses; 397 writeAccesses = writeHits + writeMisses; 398 hits = readHits + writeHits + instHits; 399 misses = readMisses + writeMisses + instMisses; 400 accesses = readAccesses + writeAccesses + instAccesses; 401} 402 |
407#if !FULL_SYSTEM | |
408Fault 409TLB::translateSe(RequestPtr req, ThreadContext *tc, Mode mode, 410 Translation *translation, bool &delay, bool timing) 411{ 412 if (!miscRegValid) 413 updateMiscReg(tc); 414 Addr vaddr = req->getVaddr(); 415 uint32_t flags = req->getFlags(); --- 5 unchanged lines hidden (view full) --- 421 assert(flags & MustBeOne); 422 if (sctlr.a || !(flags & AllowUnaligned)) { 423 if (vaddr & flags & AlignmentMask) { 424 return new DataAbort(vaddr, 0, is_write, ArmFault::AlignmentFault); 425 } 426 } 427 } 428 | 403Fault 404TLB::translateSe(RequestPtr req, ThreadContext *tc, Mode mode, 405 Translation *translation, bool &delay, bool timing) 406{ 407 if (!miscRegValid) 408 updateMiscReg(tc); 409 Addr vaddr = req->getVaddr(); 410 uint32_t flags = req->getFlags(); --- 5 unchanged lines hidden (view full) --- 416 assert(flags & MustBeOne); 417 if (sctlr.a || !(flags & AllowUnaligned)) { 418 if (vaddr & flags & AlignmentMask) { 419 return new DataAbort(vaddr, 0, is_write, ArmFault::AlignmentFault); 420 } 421 } 422 } 423 |
424#if !FULL_SYSTEM |
|
429 Addr paddr; 430 Process *p = tc->getProcessPtr(); 431 432 if (!p->pTable->translate(vaddr, paddr)) 433 return Fault(new GenericPageTableFault(vaddr)); 434 req->setPaddr(paddr); | 425 Addr paddr; 426 Process *p = tc->getProcessPtr(); 427 428 if (!p->pTable->translate(vaddr, paddr)) 429 return Fault(new GenericPageTableFault(vaddr)); 430 req->setPaddr(paddr); |
431#endif |
|
435 436 return NoFault; 437} 438 | 432 433 return NoFault; 434} 435 |
439#else // FULL_SYSTEM 440 | |
441Fault 442TLB::trickBoxCheck(RequestPtr req, Mode mode, uint8_t domain, bool sNp) 443{ 444 return NoFault; 445} 446 447Fault 448TLB::walkTrickBoxCheck(Addr pa, Addr va, Addr sz, bool is_exec, 449 bool is_write, uint8_t domain, bool sNp) 450{ 451 return NoFault; 452} 453 454Fault 455TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode, | 436Fault 437TLB::trickBoxCheck(RequestPtr req, Mode mode, uint8_t domain, bool sNp) 438{ 439 return NoFault; 440} 441 442Fault 443TLB::walkTrickBoxCheck(Addr pa, Addr va, Addr sz, bool is_exec, 444 bool is_write, uint8_t domain, bool sNp) 445{ 446 return NoFault; 447} 448 449Fault 450TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode, |
456 Translation *translation, bool &delay, bool timing, bool functional) | 451 Translation *translation, bool &delay, bool timing) |
457{ | 452{ |
458 // No such thing as a functional timing access 459 assert(!(timing && functional)); 460 | |
461 if (!miscRegValid) { 462 updateMiscReg(tc); 463 DPRINTF(TLBVerbose, "TLB variables changed!\n"); 464 } 465 466 Addr vaddr = req->getVaddr(); 467 uint32_t flags = req->getFlags(); 468 --- 70 unchanged lines hidden (view full) --- 539 else 540 readMisses++; 541 542 // start translation table walk, pass variables rather than 543 // re-retreaving in table walker for speed 544 DPRINTF(TLB, "TLB Miss: Starting hardware table walker for %#x(%d)\n", 545 vaddr, contextId); 546 fault = tableWalker->walk(req, tc, contextId, mode, translation, | 453 if (!miscRegValid) { 454 updateMiscReg(tc); 455 DPRINTF(TLBVerbose, "TLB variables changed!\n"); 456 } 457 458 Addr vaddr = req->getVaddr(); 459 uint32_t flags = req->getFlags(); 460 --- 70 unchanged lines hidden (view full) --- 531 else 532 readMisses++; 533 534 // start translation table walk, pass variables rather than 535 // re-retreaving in table walker for speed 536 DPRINTF(TLB, "TLB Miss: Starting hardware table walker for %#x(%d)\n", 537 vaddr, contextId); 538 fault = tableWalker->walk(req, tc, contextId, mode, translation, |
547 timing, functional); | 539 timing); |
548 if (timing && fault == NoFault) { 549 delay = true; 550 // for timing mode, return and wait for table walk 551 return fault; 552 } 553 if (fault) 554 return fault; 555 --- 20 unchanged lines hidden (view full) --- 576 req->setFlags(Request::UNCACHEABLE); 577 578 // Prevent prefetching from I/O devices. 579 if (req->isPrefetch()) { 580 return new PrefetchAbort(vaddr, ArmFault::PrefetchUncacheable); 581 } 582 } 583 | 540 if (timing && fault == NoFault) { 541 delay = true; 542 // for timing mode, return and wait for table walk 543 return fault; 544 } 545 if (fault) 546 return fault; 547 --- 20 unchanged lines hidden (view full) --- 568 req->setFlags(Request::UNCACHEABLE); 569 570 // Prevent prefetching from I/O devices. 571 if (req->isPrefetch()) { 572 return new PrefetchAbort(vaddr, ArmFault::PrefetchUncacheable); 573 } 574 } 575 |
584 | 576#if FULL_SYSTEM |
585 if (!bootUncacheability && 586 ((ArmSystem*)tc->getSystemPtr())->adderBootUncacheable(vaddr)) 587 req->setFlags(Request::UNCACHEABLE); | 577 if (!bootUncacheability && 578 ((ArmSystem*)tc->getSystemPtr())->adderBootUncacheable(vaddr)) 579 req->setFlags(Request::UNCACHEABLE); |
580#endif |
|
588 589 switch ( (dacr >> (te->domain * 2)) & 0x3) { 590 case 0: 591 domainFaults++; 592 DPRINTF(TLB, "TLB Fault: Data abort on domain. DACR: %#x domain: %#x" 593 " write:%d sNp:%d\n", dacr, te->domain, is_write, te->sNp); 594 if (is_fetch) 595 return new PrefetchAbort(vaddr, --- 86 unchanged lines hidden (view full) --- 682 // Check for a trickbox generated address fault 683 fault = trickBoxCheck(req, mode, te->domain, te->sNp); 684 if (fault) 685 return fault; 686 687 return NoFault; 688} 689 | 581 582 switch ( (dacr >> (te->domain * 2)) & 0x3) { 583 case 0: 584 domainFaults++; 585 DPRINTF(TLB, "TLB Fault: Data abort on domain. DACR: %#x domain: %#x" 586 " write:%d sNp:%d\n", dacr, te->domain, is_write, te->sNp); 587 if (is_fetch) 588 return new PrefetchAbort(vaddr, --- 86 unchanged lines hidden (view full) --- 675 // Check for a trickbox generated address fault 676 fault = trickBoxCheck(req, mode, te->domain, te->sNp); 677 if (fault) 678 return fault; 679 680 return NoFault; 681} 682 |
690#endif 691 | |
692Fault 693TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) 694{ 695 bool delay = false; 696 Fault fault; | 683Fault 684TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) 685{ 686 bool delay = false; 687 Fault fault; |
697#if FULL_SYSTEM 698 fault = translateFs(req, tc, mode, NULL, delay, false); 699#else 700 fault = translateSe(req, tc, mode, NULL, delay, false); 701#endif | 688 if (FullSystem) 689 fault = translateFs(req, tc, mode, NULL, delay, false); 690 else 691 fault = translateSe(req, tc, mode, NULL, delay, false); |
702 assert(!delay); 703 return fault; 704} 705 706Fault | 692 assert(!delay); 693 return fault; 694} 695 696Fault |
707TLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode) 708{ 709 bool delay = false; 710 Fault fault; 711#if FULL_SYSTEM 712 fault = translateFs(req, tc, mode, NULL, delay, false, true); 713#else 714 fault = translateSe(req, tc, mode, NULL, delay, false); 715#endif 716 assert(!delay); 717 return fault; 718} 719 720Fault | |
721TLB::translateTiming(RequestPtr req, ThreadContext *tc, 722 Translation *translation, Mode mode) 723{ 724 assert(translation); 725 bool delay = false; 726 Fault fault; | 697TLB::translateTiming(RequestPtr req, ThreadContext *tc, 698 Translation *translation, Mode mode) 699{ 700 assert(translation); 701 bool delay = false; 702 Fault fault; |
727#if FULL_SYSTEM 728 fault = translateFs(req, tc, mode, translation, delay, true); 729#else 730 fault = translateSe(req, tc, mode, translation, delay, true); 731#endif | 703 if (FullSystem) 704 fault = translateFs(req, tc, mode, translation, delay, true); 705 else 706 fault = translateSe(req, tc, mode, translation, delay, true); |
732 DPRINTF(TLBVerbose, "Translation returning delay=%d fault=%d\n", delay, fault != 733 NoFault); 734 if (!delay) 735 translation->finish(fault, req, tc, mode); 736 else 737 translation->markDelayed(); 738 return fault; 739} 740 741Port* 742TLB::getPort() 743{ | 707 DPRINTF(TLBVerbose, "Translation returning delay=%d fault=%d\n", delay, fault != 708 NoFault); 709 if (!delay) 710 translation->finish(fault, req, tc, mode); 711 else 712 translation->markDelayed(); 713 return fault; 714} 715 716Port* 717TLB::getPort() 718{ |
744#if FULL_SYSTEM | |
745 return tableWalker->getPort("port"); | 719 return tableWalker->getPort("port"); |
746#else 747 return NULL; 748#endif | |
749} 750 751 752 753ArmISA::TLB * 754ArmTLBParams::create() 755{ 756 return new ArmISA::TLB(this); 757} | 720} 721 722 723 724ArmISA::TLB * 725ArmTLBParams::create() 726{ 727 return new ArmISA::TLB(this); 728} |