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" |
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" |
63#include "sim/process.hh" 64 65#if FULL_SYSTEM 66#include "arch/arm/system.hh" |
67#endif 68 69using namespace std; 70using namespace ArmISA; 71 72TLB::TLB(const Params *p) |
73 : BaseTLB(p), size(p->size) , tableWalker(p->walker), 74 rangeMRU(1), bootUncacheability(false), miscRegValid(false) |
75{ 76 table = new TlbEntry[size]; 77 memset(table, 0, sizeof(TlbEntry) * size); 78 |
79 tableWalker->setTlb(this); |
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 |
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 |
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 |
432 433 return NoFault; 434} 435 |
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, |
451 Translation *translation, bool &delay, bool timing) |
452{ |
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, |
539 timing); |
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 |
576#if FULL_SYSTEM |
577 if (!bootUncacheability && 578 ((ArmSystem*)tc->getSystemPtr())->adderBootUncacheable(vaddr)) 579 req->setFlags(Request::UNCACHEABLE); |
580#endif |
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 |
683Fault 684TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) 685{ 686 bool delay = false; 687 Fault fault; |
688 if (FullSystem) 689 fault = translateFs(req, tc, mode, NULL, delay, false); 690 else 691 fault = translateSe(req, tc, mode, NULL, delay, false); |
692 assert(!delay); 693 return fault; 694} 695 696Fault |
697TLB::translateTiming(RequestPtr req, ThreadContext *tc, 698 Translation *translation, Mode mode) 699{ 700 assert(translation); 701 bool delay = false; 702 Fault fault; |
703 if (FullSystem) 704 fault = translateFs(req, tc, mode, translation, delay, true); 705 else 706 fault = translateSe(req, tc, mode, translation, delay, true); |
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{ |
719 return tableWalker->getPort("port"); |
720} 721 722 723 724ArmISA::TLB * 725ArmTLBParams::create() 726{ 727 return new ArmISA::TLB(this); 728} |