Deleted Added
sdiff udiff text old ( 8733:64a7bf8fa56c ) new ( 8756:cce8cf3906ca )
full compact
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/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"
61#include "sim/process.hh"
62
63#if FULL_SYSTEM
64#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)
72 : BaseTLB(p), size(p->size)
73#if FULL_SYSTEM
74 , tableWalker(p->walker)
75#endif
76 , rangeMRU(1), bootUncacheability(false), miscRegValid(false)
77{
78 table = new TlbEntry[size];
79 memset(table, 0, sizeof(TlbEntry) * size);
80
81#if FULL_SYSTEM
82 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
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
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);
435
436 return NoFault;
437}
438
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,
456 Translation *translation, bool &delay, bool timing, bool functional)
457{
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,
547 timing, functional);
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
584
585 if (!bootUncacheability &&
586 ((ArmSystem*)tc->getSystemPtr())->adderBootUncacheable(vaddr))
587 req->setFlags(Request::UNCACHEABLE);
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
690#endif
691
692Fault
693TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
694{
695 bool delay = false;
696 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
702 assert(!delay);
703 return fault;
704}
705
706Fault
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;
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
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{
744#if FULL_SYSTEM
745 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}