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}