2 * Copyright (c) 2010-2013, 2016-2019 ARM Limited
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
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
14 * Copyright (c) 2001-2005 The Regents of The University of Michigan
15 * All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 #include "arch/arm/tlb.hh"
47 #include "arch/arm/faults.hh"
48 #include "arch/arm/isa.hh"
49 #include "arch/arm/pagetable.hh"
50 #include "arch/arm/self_debug.hh"
51 #include "arch/arm/stage2_lookup.hh"
52 #include "arch/arm/stage2_mmu.hh"
53 #include "arch/arm/system.hh"
54 #include "arch/arm/table_walker.hh"
55 #include "arch/arm/utility.hh"
56 #include "base/inifile.hh"
57 #include "base/str.hh"
58 #include "base/trace.hh"
59 #include "cpu/base.hh"
60 #include "cpu/thread_context.hh"
61 #include "debug/Checkpoint.hh"
62 #include "debug/TLB.hh"
63 #include "debug/TLBVerbose.hh"
64 #include "mem/packet_access.hh"
65 #include "mem/page_table.hh"
66 #include "mem/request.hh"
67 #include "params/ArmTLB.hh"
68 #include "sim/full_system.hh"
69 #include "sim/process.hh"
70 #include "sim/pseudo_inst.hh"
73 using namespace ArmISA
;
75 TLB::TLB(const ArmTLBParams
*p
)
76 : BaseTLB(p
), table(new TlbEntry
[p
->size
]), size(p
->size
),
77 isStage2(p
->is_stage2
), stage2Req(false), stage2DescReq(false), _attr(0),
78 directToStage2(false), tableWalker(p
->walker
), stage2Tlb(NULL
),
79 stage2Mmu(NULL
), test(nullptr), rangeMRU(1),
80 aarch64(false), aarch64EL(EL0
), isPriv(false), isSecure(false),
81 isHyp(false), asid(0), vmid(0), hcr(0), dacr(0),
82 miscRegValid(false), miscRegContext(0), curTranType(NormalTran
)
84 const ArmSystem
*sys
= dynamic_cast<const ArmSystem
*>(p
->sys
);
86 tableWalker
->setTlb(this);
88 // Cache system-level properties
89 haveLPAE
= tableWalker
->haveLPAE();
90 haveVirtualization
= tableWalker
->haveVirtualization();
91 haveLargeAsid64
= tableWalker
->haveLargeAsid64();
94 m5opRange
= sys
->m5opRange();
105 if (stage2Mmu
&& !isStage2
)
106 stage2Tlb
= stage2Mmu
->stage2Tlb();
110 TLB::setMMU(Stage2MMU
*m
, MasterID master_id
)
113 tableWalker
->setMMU(m
, master_id
);
117 TLB::translateFunctional(ThreadContext
*tc
, Addr va
, Addr
&pa
)
121 if (directToStage2
) {
123 return stage2Tlb
->translateFunctional(tc
, va
, pa
);
126 TlbEntry
*e
= lookup(va
, asid
, vmid
, isHyp
, isSecure
, true, false,
127 aarch64
? aarch64EL
: EL1
, false);
135 TLB::finalizePhysical(const RequestPtr
&req
,
136 ThreadContext
*tc
, Mode mode
) const
138 const Addr paddr
= req
->getPaddr();
140 if (m5opRange
.contains(paddr
)) {
142 PseudoInst::decodeAddrOffset(paddr
- m5opRange
.start(), func
);
143 req
->setLocalAccessor(
144 [func
, mode
](ThreadContext
*tc
, PacketPtr pkt
) -> Cycles
147 PseudoInst::pseudoInst
<PseudoInstABI
>(tc
, func
, ret
);
159 TLB::lookup(Addr va
, uint16_t asn
, uint8_t vmid
, bool hyp
, bool secure
,
160 bool functional
, bool ignore_asn
, ExceptionLevel target_el
,
164 TlbEntry
*retval
= NULL
;
166 // Maintaining LRU array
168 while (retval
== NULL
&& x
< size
) {
169 if ((!ignore_asn
&& table
[x
].match(va
, asn
, vmid
, hyp
, secure
, false,
170 target_el
, in_host
)) ||
171 (ignore_asn
&& table
[x
].match(va
, vmid
, hyp
, secure
, target_el
,
173 // We only move the hit entry ahead when the position is higher
175 if (x
> rangeMRU
&& !functional
) {
176 TlbEntry tmp_entry
= table
[x
];
177 for (int i
= x
; i
> 0; i
--)
178 table
[i
] = table
[i
- 1];
179 table
[0] = tmp_entry
;
189 DPRINTF(TLBVerbose
, "Lookup %#x, asn %#x -> %s vmn 0x%x hyp %d secure %d "
190 "ppn %#x size: %#x pa: %#x ap:%d ns:%d nstid:%d g:%d asid: %d "
192 va
, asn
, retval
? "hit" : "miss", vmid
, hyp
, secure
,
193 retval
? retval
->pfn
: 0, retval
? retval
->size
: 0,
194 retval
? retval
->pAddr(va
) : 0, retval
? retval
->ap
: 0,
195 retval
? retval
->ns
: 0, retval
? retval
->nstid
: 0,
196 retval
? retval
->global
: 0, retval
? retval
->asid
: 0,
197 retval
? retval
->el
: 0);
202 // insert a new TLB entry
204 TLB::insert(Addr addr
, TlbEntry
&entry
)
206 DPRINTF(TLB
, "Inserting entry into TLB with pfn:%#x size:%#x vpn: %#x"
207 " asid:%d vmid:%d N:%d global:%d valid:%d nc:%d xn:%d"
208 " ap:%#x domain:%#x ns:%d nstid:%d isHyp:%d\n", entry
.pfn
,
209 entry
.size
, entry
.vpn
, entry
.asid
, entry
.vmid
, entry
.N
,
210 entry
.global
, entry
.valid
, entry
.nonCacheable
, entry
.xn
,
211 entry
.ap
, static_cast<uint8_t>(entry
.domain
), entry
.ns
, entry
.nstid
,
214 if (table
[size
- 1].valid
)
215 DPRINTF(TLB
, " - Replacing Valid entry %#x, asn %d vmn %d ppn %#x "
216 "size: %#x ap:%d ns:%d nstid:%d g:%d isHyp:%d el: %d\n",
217 table
[size
-1].vpn
<< table
[size
-1].N
, table
[size
-1].asid
,
218 table
[size
-1].vmid
, table
[size
-1].pfn
<< table
[size
-1].N
,
219 table
[size
-1].size
, table
[size
-1].ap
, table
[size
-1].ns
,
220 table
[size
-1].nstid
, table
[size
-1].global
, table
[size
-1].isHyp
,
223 //inserting to MRU position and evicting the LRU one
225 for (int i
= size
- 1; i
> 0; --i
)
226 table
[i
] = table
[i
-1];
230 ppRefills
->notify(1);
234 TLB::printTlb() const
238 DPRINTF(TLB
, "Current TLB contents:\n");
242 DPRINTF(TLB
, " * %s\n", te
->print());
248 TLB::flushAllSecurity(bool secure_lookup
, ExceptionLevel target_el
,
249 bool ignore_el
, bool in_host
)
251 DPRINTF(TLB
, "Flushing all TLB entries (%s lookup)\n",
252 (secure_lookup
? "secure" : "non-secure"));
257 const bool el_match
= ignore_el
?
258 true : te
->checkELMatch(target_el
, in_host
);
259 if (te
->valid
&& secure_lookup
== !te
->nstid
&&
260 (te
->vmid
== vmid
|| secure_lookup
) && el_match
) {
262 DPRINTF(TLB
, " - %s\n", te
->print());
271 // If there's a second stage TLB (and we're not it) then flush it as well
272 // if we're currently in hyp mode
273 if (!isStage2
&& isHyp
) {
274 stage2Tlb
->flushAllSecurity(secure_lookup
, EL1
, true, false);
279 TLB::flushAllNs(ExceptionLevel target_el
, bool ignore_el
)
281 bool hyp
= target_el
== EL2
;
283 DPRINTF(TLB
, "Flushing all NS TLB entries (%s lookup)\n",
284 (hyp
? "hyp" : "non-hyp"));
289 const bool el_match
= ignore_el
?
290 true : te
->checkELMatch(target_el
, false);
292 if (te
->valid
&& te
->nstid
&& te
->isHyp
== hyp
&& el_match
) {
294 DPRINTF(TLB
, " - %s\n", te
->print());
303 // If there's a second stage TLB (and we're not it) then flush it as well
304 if (!isStage2
&& !hyp
) {
305 stage2Tlb
->flushAllNs(EL1
, true);
310 TLB::flushMvaAsid(Addr mva
, uint64_t asn
, bool secure_lookup
,
311 ExceptionLevel target_el
, bool in_host
)
313 DPRINTF(TLB
, "Flushing TLB entries with mva: %#x, asid: %#x "
314 "(%s lookup)\n", mva
, asn
, (secure_lookup
?
315 "secure" : "non-secure"));
316 _flushMva(mva
, asn
, secure_lookup
, false, target_el
, in_host
);
321 TLB::flushAsid(uint64_t asn
, bool secure_lookup
, ExceptionLevel target_el
,
324 DPRINTF(TLB
, "Flushing TLB entries with asid: %#x (%s lookup)\n", asn
,
325 (secure_lookup
? "secure" : "non-secure"));
332 if (te
->valid
&& te
->asid
== asn
&& secure_lookup
== !te
->nstid
&&
333 (te
->vmid
== vmid
|| secure_lookup
) &&
334 te
->checkELMatch(target_el
, in_host
)) {
337 DPRINTF(TLB
, " - %s\n", te
->print());
346 TLB::flushMva(Addr mva
, bool secure_lookup
, ExceptionLevel target_el
,
349 DPRINTF(TLB
, "Flushing TLB entries with mva: %#x (%s lookup)\n", mva
,
350 (secure_lookup
? "secure" : "non-secure"));
351 _flushMva(mva
, 0xbeef, secure_lookup
, true, target_el
, in_host
);
356 TLB::_flushMva(Addr mva
, uint64_t asn
, bool secure_lookup
,
357 bool ignore_asn
, ExceptionLevel target_el
, bool in_host
)
360 // D5.7.2: Sign-extend address to 64 bits
363 bool hyp
= target_el
== EL2
;
365 te
= lookup(mva
, asn
, vmid
, hyp
, secure_lookup
, false, ignore_asn
,
368 if (secure_lookup
== !te
->nstid
) {
369 DPRINTF(TLB
, " - %s\n", te
->print());
373 te
= lookup(mva
, asn
, vmid
, hyp
, secure_lookup
, false, ignore_asn
,
379 TLB::flushIpaVmid(Addr ipa
, bool secure_lookup
, ExceptionLevel target_el
)
382 stage2Tlb
->_flushMva(ipa
, 0xbeef, secure_lookup
, true, target_el
, false);
388 // We might have unserialized something or switched CPUs, so make
389 // sure to re-read the misc regs.
390 miscRegValid
= false;
394 TLB::takeOverFrom(BaseTLB
*_otlb
)
396 TLB
*otlb
= dynamic_cast<TLB
*>(_otlb
);
397 /* Make sure we actually have a valid type */
400 haveLPAE
= otlb
->haveLPAE
;
401 directToStage2
= otlb
->directToStage2
;
402 stage2Req
= otlb
->stage2Req
;
403 stage2DescReq
= otlb
->stage2DescReq
;
405 /* Sync the stage2 MMU if they exist in both
406 * the old CPU and the new
409 stage2Tlb
&& otlb
->stage2Tlb
) {
410 stage2Tlb
->takeOverFrom(otlb
->stage2Tlb
);
413 panic("Incompatible TLB type!");
422 .name(name() + ".inst_hits")
423 .desc("ITB inst hits")
427 .name(name() + ".inst_misses")
428 .desc("ITB inst misses")
432 .name(name() + ".inst_accesses")
433 .desc("ITB inst accesses")
437 .name(name() + ".read_hits")
438 .desc("DTB read hits")
442 .name(name() + ".read_misses")
443 .desc("DTB read misses")
447 .name(name() + ".read_accesses")
448 .desc("DTB read accesses")
452 .name(name() + ".write_hits")
453 .desc("DTB write hits")
457 .name(name() + ".write_misses")
458 .desc("DTB write misses")
462 .name(name() + ".write_accesses")
463 .desc("DTB write accesses")
467 .name(name() + ".hits")
472 .name(name() + ".misses")
477 .name(name() + ".accesses")
478 .desc("DTB accesses")
482 .name(name() + ".flush_tlb")
483 .desc("Number of times complete TLB was flushed")
487 .name(name() + ".flush_tlb_mva")
488 .desc("Number of times TLB was flushed by MVA")
492 .name(name() + ".flush_tlb_mva_asid")
493 .desc("Number of times TLB was flushed by MVA & ASID")
497 .name(name() + ".flush_tlb_asid")
498 .desc("Number of times TLB was flushed by ASID")
502 .name(name() + ".flush_entries")
503 .desc("Number of entries that have been flushed from TLB")
507 .name(name() + ".align_faults")
508 .desc("Number of TLB faults due to alignment restrictions")
512 .name(name() + ".prefetch_faults")
513 .desc("Number of TLB faults due to prefetch")
517 .name(name() + ".domain_faults")
518 .desc("Number of TLB faults due to domain restrictions")
522 .name(name() + ".perms_faults")
523 .desc("Number of TLB faults due to permissions restrictions")
526 instAccesses
= instHits
+ instMisses
;
527 readAccesses
= readHits
+ readMisses
;
528 writeAccesses
= writeHits
+ writeMisses
;
529 hits
= readHits
+ writeHits
+ instHits
;
530 misses
= readMisses
+ writeMisses
+ instMisses
;
531 accesses
= readAccesses
+ writeAccesses
+ instAccesses
;
535 TLB::regProbePoints()
537 ppRefills
.reset(new ProbePoints::PMU(getProbeManager(), "Refills"));
541 TLB::translateSe(const RequestPtr
&req
, ThreadContext
*tc
, Mode mode
,
542 Translation
*translation
, bool &delay
, bool timing
)
545 Addr vaddr_tainted
= req
->getVaddr();
548 vaddr
= purifyTaggedAddr(vaddr_tainted
, tc
, aarch64EL
, (TCR
)ttbcr
,
551 vaddr
= vaddr_tainted
;
552 Request::Flags flags
= req
->getFlags();
554 bool is_fetch
= (mode
== Execute
);
555 bool is_write
= (mode
== Write
);
558 if (sctlr
.a
|| !(flags
& AllowUnaligned
)) {
559 if (vaddr
& mask(flags
& AlignmentMask
)) {
560 // LPAE is always disabled in SE mode
561 return std::make_shared
<DataAbort
>(
563 TlbEntry::DomainType::NoAccess
, is_write
,
564 ArmFault::AlignmentFault
, isStage2
,
571 Process
*p
= tc
->getProcessPtr();
573 if (!p
->pTable
->translate(vaddr
, paddr
))
574 return std::make_shared
<GenericPageTableFault
>(vaddr_tainted
);
575 req
->setPaddr(paddr
);
577 return finalizePhysical(req
, tc
, mode
);
581 TLB::checkPermissions(TlbEntry
*te
, const RequestPtr
&req
, Mode mode
)
583 // a data cache maintenance instruction that operates by MVA does
584 // not generate a Data Abort exeception due to a Permission fault
585 if (req
->isCacheMaintenance()) {
589 Addr vaddr
= req
->getVaddr(); // 32-bit don't have to purify
590 Request::Flags flags
= req
->getFlags();
591 bool is_fetch
= (mode
== Execute
);
592 bool is_write
= (mode
== Write
);
593 bool is_priv
= isPriv
&& !(flags
& UserMode
);
595 // Get the translation type from the actuall table entry
596 ArmFault::TranMethod tranMethod
= te
->longDescFormat
? ArmFault::LpaeTran
597 : ArmFault::VmsaTran
;
599 // If this is the second stage of translation and the request is for a
600 // stage 1 page table walk then we need to check the HCR.PTW bit. This
601 // allows us to generate a fault if the request targets an area marked
602 // as a device or strongly ordered.
603 if (isStage2
&& req
->isPTWalk() && hcr
.ptw
&&
604 (te
->mtype
!= TlbEntry::MemoryType::Normal
)) {
605 return std::make_shared
<DataAbort
>(
606 vaddr
, te
->domain
, is_write
,
607 ArmFault::PermissionLL
+ te
->lookupLevel
,
608 isStage2
, tranMethod
);
611 // Generate an alignment fault for unaligned data accesses to device or
612 // strongly ordered memory
614 if (te
->mtype
!= TlbEntry::MemoryType::Normal
) {
615 if (vaddr
& mask(flags
& AlignmentMask
)) {
617 return std::make_shared
<DataAbort
>(
618 vaddr
, TlbEntry::DomainType::NoAccess
, is_write
,
619 ArmFault::AlignmentFault
, isStage2
,
625 if (te
->nonCacheable
) {
626 // Prevent prefetching from I/O devices.
627 if (req
->isPrefetch()) {
628 // Here we can safely use the fault status for the short
629 // desc. format in all cases
630 return std::make_shared
<PrefetchAbort
>(
631 vaddr
, ArmFault::PrefetchUncacheable
,
632 isStage2
, tranMethod
);
636 if (!te
->longDescFormat
) {
637 switch ((dacr
>> (static_cast<uint8_t>(te
->domain
) * 2)) & 0x3) {
640 DPRINTF(TLB
, "TLB Fault: Data abort on domain. DACR: %#x"
641 " domain: %#x write:%d\n", dacr
,
642 static_cast<uint8_t>(te
->domain
), is_write
);
644 // Use PC value instead of vaddr because vaddr might
645 // be aligned to cache line and should not be the
646 // address reported in FAR
647 return std::make_shared
<PrefetchAbort
>(
649 ArmFault::DomainLL
+ te
->lookupLevel
,
650 isStage2
, tranMethod
);
652 return std::make_shared
<DataAbort
>(
653 vaddr
, te
->domain
, is_write
,
654 ArmFault::DomainLL
+ te
->lookupLevel
,
655 isStage2
, tranMethod
);
657 // Continue with permissions check
660 panic("UNPRED domain\n");
666 // The 'ap' variable is AP[2:0] or {AP[2,1],1b'0}, i.e. always three bits
667 uint8_t ap
= te
->longDescFormat
? te
->ap
<< 1 : te
->ap
;
668 uint8_t hap
= te
->hap
;
670 if (sctlr
.afe
== 1 || te
->longDescFormat
)
674 bool isWritable
= true;
675 // If this is a stage 2 access (eg for reading stage 1 page table entries)
676 // then don't perform the AP permissions check, we stil do the HAP check
683 DPRINTF(TLB
, "Access permissions 0, checking rs:%#x\n",
686 switch ((int)sctlr
.rs
) {
691 abt
= is_write
|| !is_priv
;
707 abt
= !is_priv
&& is_write
;
708 isWritable
= is_priv
;
714 panic("UNPRED premissions\n");
716 abt
= !is_priv
|| is_write
;
725 panic("Unknown permissions %#x\n", ap
);
729 bool hapAbt
= is_write
? !(hap
& 2) : !(hap
& 1);
730 bool xn
= te
->xn
|| (isWritable
&& sctlr
.wxn
) ||
731 (ap
== 3 && sctlr
.uwxn
&& is_priv
);
732 if (is_fetch
&& (abt
|| xn
||
733 (te
->longDescFormat
&& te
->pxn
&& is_priv
) ||
734 (isSecure
&& te
->ns
&& scr
.sif
))) {
736 DPRINTF(TLB
, "TLB Fault: Prefetch abort on permission check. AP:%d "
737 "priv:%d write:%d ns:%d sif:%d sctlr.afe: %d \n",
738 ap
, is_priv
, is_write
, te
->ns
, scr
.sif
,sctlr
.afe
);
739 // Use PC value instead of vaddr because vaddr might be aligned to
740 // cache line and should not be the address reported in FAR
741 return std::make_shared
<PrefetchAbort
>(
743 ArmFault::PermissionLL
+ te
->lookupLevel
,
744 isStage2
, tranMethod
);
745 } else if (abt
| hapAbt
) {
747 DPRINTF(TLB
, "TLB Fault: Data abort on permission check. AP:%d priv:%d"
748 " write:%d\n", ap
, is_priv
, is_write
);
749 return std::make_shared
<DataAbort
>(
750 vaddr
, te
->domain
, is_write
,
751 ArmFault::PermissionLL
+ te
->lookupLevel
,
752 isStage2
| !abt
, tranMethod
);
759 TLB::checkPermissions64(TlbEntry
*te
, const RequestPtr
&req
, Mode mode
,
764 // A data cache maintenance instruction that operates by VA does
765 // not generate a Permission fault unless:
766 // * It is a data cache invalidate (dc ivac) which requires write
767 // permissions to the VA, or
768 // * It is executed from EL0
769 if (req
->isCacheClean() && aarch64EL
!= EL0
&& !isStage2
) {
773 Addr vaddr_tainted
= req
->getVaddr();
774 Addr vaddr
= purifyTaggedAddr(vaddr_tainted
, tc
, aarch64EL
, (TCR
)ttbcr
,
777 Request::Flags flags
= req
->getFlags();
778 bool is_fetch
= (mode
== Execute
);
779 // Cache clean operations require read permissions to the specified VA
780 bool is_write
= !req
->isCacheClean() && mode
== Write
;
781 bool is_atomic
= req
->isAtomic();
782 bool is_priv M5_VAR_USED
= isPriv
&& !(flags
& UserMode
);
784 updateMiscReg(tc
, curTranType
);
786 // If this is the second stage of translation and the request is for a
787 // stage 1 page table walk then we need to check the HCR.PTW bit. This
788 // allows us to generate a fault if the request targets an area marked
789 // as a device or strongly ordered.
790 if (isStage2
&& req
->isPTWalk() && hcr
.ptw
&&
791 (te
->mtype
!= TlbEntry::MemoryType::Normal
)) {
792 return std::make_shared
<DataAbort
>(
793 vaddr_tainted
, te
->domain
, is_write
,
794 ArmFault::PermissionLL
+ te
->lookupLevel
,
795 isStage2
, ArmFault::LpaeTran
);
798 // Generate an alignment fault for unaligned accesses to device or
799 // strongly ordered memory
801 if (te
->mtype
!= TlbEntry::MemoryType::Normal
) {
802 if (vaddr
& mask(flags
& AlignmentMask
)) {
804 return std::make_shared
<DataAbort
>(
806 TlbEntry::DomainType::NoAccess
,
807 is_atomic
? false : is_write
,
808 ArmFault::AlignmentFault
, isStage2
,
814 if (te
->nonCacheable
) {
815 // Prevent prefetching from I/O devices.
816 if (req
->isPrefetch()) {
817 // Here we can safely use the fault status for the short
818 // desc. format in all cases
819 return std::make_shared
<PrefetchAbort
>(
821 ArmFault::PrefetchUncacheable
,
822 isStage2
, ArmFault::LpaeTran
);
826 uint8_t ap
= 0x3 & (te
->ap
); // 2-bit access protection field
829 bool wxn
= sctlr
.wxn
;
831 uint8_t pxn
= te
->pxn
;
832 bool r
= (!is_write
&& !is_fetch
);
836 if (ArmSystem::haveEL(tc
, EL3
) && isSecure
&& te
->ns
&& scr
.sif
)
839 // grant_read is used for faults from an atomic instruction that
840 // both reads and writes from a memory location. From a ISS point
841 // of view they count as read if a read to that address would have
842 // generated the fault; they count as writes otherwise
843 bool grant_read
= true;
844 DPRINTF(TLBVerbose
, "Checking permissions: ap:%d, xn:%d, pxn:%d, r:%d, "
845 "w:%d, x:%d, is_priv: %d, wxn: %d\n", ap
, xn
,
846 pxn
, r
, w
, x
, is_priv
, wxn
);
849 assert(ArmSystem::haveVirtualization(tc
) && aarch64EL
!= EL2
);
850 // In stage 2 we use the hypervisor access permission bits.
851 // The following permissions are described in ARM DDI 0487A.f
853 uint8_t hap
= 0x3 & te
->hap
;
854 grant_read
= hap
& 0x1;
856 // sctlr.wxn overrides the xn bit
858 } else if (is_atomic
) {
861 } else if (is_write
) {
870 grant_read
= ap
& 0x1;
871 uint8_t perm
= (ap
<< 2) | (xn
<< 1) | pxn
;
881 grant
= r
|| w
|| (x
&& !wxn
);
902 if (checkPAN(tc
, ap
, req
, mode
)) {
908 uint8_t perm
= (ap
<< 2) | (xn
<< 1) | pxn
;
912 grant
= r
|| w
|| (x
&& !wxn
);
920 // regions that are writeable at EL0 should not be
942 if (hcr
.e2h
&& checkPAN(tc
, ap
, req
, mode
)) {
950 uint8_t perm
= (ap
& 0x2) | xn
;
953 grant
= r
|| w
|| (x
&& !wxn
);
975 DPRINTF(TLB
, "TLB Fault: Prefetch abort on permission check. "
976 "AP:%d priv:%d write:%d ns:%d sif:%d "
978 ap
, is_priv
, is_write
, te
->ns
, scr
.sif
, sctlr
.afe
);
979 // Use PC value instead of vaddr because vaddr might be aligned to
980 // cache line and should not be the address reported in FAR
981 return std::make_shared
<PrefetchAbort
>(
983 ArmFault::PermissionLL
+ te
->lookupLevel
,
984 isStage2
, ArmFault::LpaeTran
);
987 DPRINTF(TLB
, "TLB Fault: Data abort on permission check. AP:%d "
988 "priv:%d write:%d\n", ap
, is_priv
, is_write
);
989 return std::make_shared
<DataAbort
>(
990 vaddr_tainted
, te
->domain
,
991 (is_atomic
&& !grant_read
) ? false : is_write
,
992 ArmFault::PermissionLL
+ te
->lookupLevel
,
993 isStage2
, ArmFault::LpaeTran
);
1001 TLB::checkPAN(ThreadContext
*tc
, uint8_t ap
, const RequestPtr
&req
, Mode mode
)
1003 // The PAN bit has no effect on:
1004 // 1) Instruction accesses.
1005 // 2) Data Cache instructions other than DC ZVA
1006 // 3) Address translation instructions, other than ATS1E1RP and
1007 // ATS1E1WP when ARMv8.2-ATS1E1 is implemented. (Unimplemented in
1009 // 4) Unprivileged instructions (Unimplemented in gem5)
1010 AA64MMFR1 mmfr1
= tc
->readMiscReg(MISCREG_ID_AA64MMFR1_EL1
);
1011 if (mmfr1
.pan
&& cpsr
.pan
&& (ap
& 0x1) && mode
!= Execute
&&
1012 (!req
->isCacheMaintenance() ||
1013 (req
->getFlags() & Request::CACHE_BLOCK_ZERO
))) {
1021 TLB::translateMmuOff(ThreadContext
*tc
, const RequestPtr
&req
, Mode mode
,
1022 TLB::ArmTranslationType tranType
, Addr vaddr
, bool long_desc_format
)
1024 bool is_fetch
= (mode
== Execute
);
1025 bool is_atomic
= req
->isAtomic();
1026 req
->setPaddr(vaddr
);
1027 // When the MMU is off the security attribute corresponds to the
1028 // security state of the processor
1030 req
->setFlags(Request::SECURE
);
1033 bool selbit
= bits(vaddr
, 55);
1034 TCR tcr1
= tc
->readMiscReg(MISCREG_TCR_EL1
);
1035 int topbit
= computeAddrTop(tc
, selbit
, is_fetch
, tcr1
, currEL(tc
));
1036 int addr_sz
= bits(vaddr
, topbit
, MaxPhysAddrRange
);
1040 f
= std::make_shared
<PrefetchAbort
>(vaddr
,
1041 ArmFault::AddressSizeLL
, isStage2
, ArmFault::LpaeTran
);
1043 f
= std::make_shared
<DataAbort
>( vaddr
,
1044 TlbEntry::DomainType::NoAccess
,
1045 is_atomic
? false : mode
==Write
,
1046 ArmFault::AddressSizeLL
, isStage2
, ArmFault::LpaeTran
);
1051 // @todo: double check this (ARM ARM issue C B3.2.1)
1052 if (long_desc_format
|| sctlr
.tre
== 0 || nmrr
.ir0
== 0 ||
1053 nmrr
.or0
== 0 || prrr
.tr0
!= 0x2) {
1054 if (!req
->isCacheMaintenance()) {
1055 req
->setFlags(Request::UNCACHEABLE
);
1057 req
->setFlags(Request::STRICT_ORDER
);
1060 // Set memory attributes
1062 temp_te
.ns
= !isSecure
;
1063 bool dc
= (HaveVirtHostExt(tc
)
1064 && hcr
.e2h
== 1 && hcr
.tge
== 1) ? 0: hcr
.dc
;
1065 bool i_cacheability
= sctlr
.i
&& !sctlr
.m
;
1066 if (isStage2
|| !dc
|| isSecure
||
1067 (isHyp
&& !(tranType
& S1CTran
))) {
1069 temp_te
.mtype
= is_fetch
? TlbEntry::MemoryType::Normal
1070 : TlbEntry::MemoryType::StronglyOrdered
;
1071 temp_te
.innerAttrs
= i_cacheability
? 0x2: 0x0;
1072 temp_te
.outerAttrs
= i_cacheability
? 0x2: 0x0;
1073 temp_te
.shareable
= true;
1074 temp_te
.outerShareable
= true;
1076 temp_te
.mtype
= TlbEntry::MemoryType::Normal
;
1077 temp_te
.innerAttrs
= 0x3;
1078 temp_te
.outerAttrs
= 0x3;
1079 temp_te
.shareable
= false;
1080 temp_te
.outerShareable
= false;
1082 temp_te
.setAttributes(long_desc_format
);
1083 DPRINTF(TLBVerbose
, "(No MMU) setting memory attributes: shareable: "
1084 "%d, innerAttrs: %d, outerAttrs: %d, isStage2: %d\n",
1085 temp_te
.shareable
, temp_te
.innerAttrs
, temp_te
.outerAttrs
,
1087 setAttr(temp_te
.attributes
);
1089 return testTranslation(req
, mode
, TlbEntry::DomainType::NoAccess
);
1093 TLB::translateMmuOn(ThreadContext
* tc
, const RequestPtr
&req
, Mode mode
,
1094 Translation
*translation
, bool &delay
, bool timing
,
1095 bool functional
, Addr vaddr
,
1096 ArmFault::TranMethod tranMethod
)
1098 TlbEntry
*te
= NULL
;
1099 bool is_fetch
= (mode
== Execute
);
1102 Request::Flags flags
= req
->getFlags();
1103 Addr vaddr_tainted
= req
->getVaddr();
1105 Fault fault
= getResultTe(&te
, req
, tc
, mode
, translation
, timing
,
1106 functional
, &mergeTe
);
1107 // only proceed if we have a valid table entry
1108 if ((te
== NULL
) && (fault
== NoFault
)) delay
= true;
1110 // If we have the table entry transfer some of the attributes to the
1111 // request that triggered the translation
1113 // Set memory attributes
1115 "Setting memory attributes: shareable: %d, innerAttrs: %d, "
1116 "outerAttrs: %d, mtype: %d, isStage2: %d\n",
1117 te
->shareable
, te
->innerAttrs
, te
->outerAttrs
,
1118 static_cast<uint8_t>(te
->mtype
), isStage2
);
1119 setAttr(te
->attributes
);
1121 if (te
->nonCacheable
&& !req
->isCacheMaintenance())
1122 req
->setFlags(Request::UNCACHEABLE
);
1124 // Require requests to be ordered if the request goes to
1125 // strongly ordered or device memory (i.e., anything other
1126 // than normal memory requires strict order).
1127 if (te
->mtype
!= TlbEntry::MemoryType::Normal
)
1128 req
->setFlags(Request::STRICT_ORDER
);
1130 Addr pa
= te
->pAddr(vaddr
);
1133 if (isSecure
&& !te
->ns
) {
1134 req
->setFlags(Request::SECURE
);
1136 if (!is_fetch
&& fault
== NoFault
&&
1137 (vaddr
& mask(flags
& AlignmentMask
)) &&
1138 (te
->mtype
!= TlbEntry::MemoryType::Normal
)) {
1139 // Unaligned accesses to Device memory should always cause an
1140 // abort regardless of sctlr.a
1142 bool is_write
= (mode
== Write
);
1143 return std::make_shared
<DataAbort
>(
1145 TlbEntry::DomainType::NoAccess
, is_write
,
1146 ArmFault::AlignmentFault
, isStage2
,
1150 // Check for a trickbox generated address fault
1151 if (fault
== NoFault
)
1152 fault
= testTranslation(req
, mode
, te
->domain
);
1155 if (fault
== NoFault
) {
1156 // Don't try to finalize a physical address unless the
1157 // translation has completed (i.e., there is a table entry).
1158 return te
? finalizePhysical(req
, tc
, mode
) : NoFault
;
1165 TLB::translateFs(const RequestPtr
&req
, ThreadContext
*tc
, Mode mode
,
1166 Translation
*translation
, bool &delay
, bool timing
,
1167 TLB::ArmTranslationType tranType
, bool functional
)
1169 // No such thing as a functional timing access
1170 assert(!(timing
&& functional
));
1172 updateMiscReg(tc
, tranType
);
1174 Addr vaddr_tainted
= req
->getVaddr();
1177 vaddr
= purifyTaggedAddr(vaddr_tainted
, tc
, aarch64EL
, (TCR
)ttbcr
,
1180 vaddr
= vaddr_tainted
;
1181 Request::Flags flags
= req
->getFlags();
1183 bool is_fetch
= (mode
== Execute
);
1184 bool is_write
= (mode
== Write
);
1185 bool long_desc_format
= aarch64
|| longDescFormatInUse(tc
);
1186 ArmFault::TranMethod tranMethod
= long_desc_format
? ArmFault::LpaeTran
1187 : ArmFault::VmsaTran
;
1190 "CPSR is priv:%d UserMode:%d secure:%d S1S2NsTran:%d\n",
1191 isPriv
, flags
& UserMode
, isSecure
, tranType
& S1S2NsTran
);
1193 DPRINTF(TLB
, "translateFs addr %#x, mode %d, st2 %d, scr %#x sctlr %#x "
1194 "flags %#lx tranType 0x%x\n", vaddr_tainted
, mode
, isStage2
,
1195 scr
, sctlr
, flags
, tranType
);
1197 if ((req
->isInstFetch() && (!sctlr
.i
)) ||
1198 ((!req
->isInstFetch()) && (!sctlr
.c
))){
1199 if (!req
->isCacheMaintenance()) {
1200 req
->setFlags(Request::UNCACHEABLE
);
1202 req
->setFlags(Request::STRICT_ORDER
);
1205 if (sctlr
.a
|| !(flags
& AllowUnaligned
)) {
1206 if (vaddr
& mask(flags
& AlignmentMask
)) {
1208 return std::make_shared
<DataAbort
>(
1210 TlbEntry::DomainType::NoAccess
, is_write
,
1211 ArmFault::AlignmentFault
, isStage2
,
1218 if (HaveVirtHostExt(tc
) && hcr
.e2h
== 1 && hcr
.tge
==1)
1220 else if (hcr
.dc
== 1)
1223 Fault fault
= NoFault
;
1224 // If guest MMU is off or hcr.vm=0 go straight to stage2
1225 if ((isStage2
&& !vm
) || (!isStage2
&& !sctlr
.m
)) {
1226 fault
= translateMmuOff(tc
, req
, mode
, tranType
, vaddr
,
1229 DPRINTF(TLBVerbose
, "Translating %s=%#x context=%d\n",
1230 isStage2
? "IPA" : "VA", vaddr_tainted
, asid
);
1231 // Translation enabled
1232 fault
= translateMmuOn(tc
, req
, mode
, translation
, delay
, timing
,
1233 functional
, vaddr
, tranMethod
);
1236 //Check for Debug Exceptions
1237 if (fault
== NoFault
) {
1238 SelfDebug
*sd
= ArmISA::ISA::getSelfDebug(tc
);
1240 fault
= sd
->testDebug(tc
, req
, mode
);
1247 TLB::translateAtomic(const RequestPtr
&req
, ThreadContext
*tc
, Mode mode
,
1248 TLB::ArmTranslationType tranType
)
1250 updateMiscReg(tc
, tranType
);
1252 if (directToStage2
) {
1254 return stage2Tlb
->translateAtomic(req
, tc
, mode
, tranType
);
1260 fault
= translateFs(req
, tc
, mode
, NULL
, delay
, false, tranType
);
1262 fault
= translateSe(req
, tc
, mode
, NULL
, delay
, false);
1268 TLB::translateFunctional(const RequestPtr
&req
, ThreadContext
*tc
, Mode mode
,
1269 TLB::ArmTranslationType tranType
)
1271 updateMiscReg(tc
, tranType
);
1273 if (directToStage2
) {
1275 return stage2Tlb
->translateFunctional(req
, tc
, mode
, tranType
);
1281 fault
= translateFs(req
, tc
, mode
, NULL
, delay
, false, tranType
, true);
1283 fault
= translateSe(req
, tc
, mode
, NULL
, delay
, false);
1289 TLB::translateTiming(const RequestPtr
&req
, ThreadContext
*tc
,
1290 Translation
*translation
, Mode mode
, TLB::ArmTranslationType tranType
)
1292 updateMiscReg(tc
, tranType
);
1294 if (directToStage2
) {
1296 stage2Tlb
->translateTiming(req
, tc
, translation
, mode
, tranType
);
1300 assert(translation
);
1302 translateComplete(req
, tc
, translation
, mode
, tranType
, isStage2
);
1306 TLB::translateComplete(const RequestPtr
&req
, ThreadContext
*tc
,
1307 Translation
*translation
, Mode mode
, TLB::ArmTranslationType tranType
,
1313 fault
= translateFs(req
, tc
, mode
, translation
, delay
, true, tranType
);
1315 fault
= translateSe(req
, tc
, mode
, translation
, delay
, true);
1316 DPRINTF(TLBVerbose
, "Translation returning delay=%d fault=%d\n", delay
, fault
!=
1318 // If we have a translation, and we're not in the middle of doing a stage
1319 // 2 translation tell the translation that we've either finished or its
1320 // going to take a while. By not doing this when we're in the middle of a
1321 // stage 2 translation we prevent marking the translation as delayed twice,
1322 // one when the translation starts and again when the stage 1 translation
1325 if (translation
&& (callFromS2
|| !stage2Req
|| req
->hasPaddr() ||
1326 fault
!= NoFault
)) {
1328 translation
->finish(fault
, req
, tc
, mode
);
1330 translation
->markDelayed();
1336 TLB::getTableWalkerPort()
1338 return &stage2Mmu
->getDMAPort();
1342 TLB::updateMiscReg(ThreadContext
*tc
, ArmTranslationType tranType
)
1344 // check if the regs have changed, or the translation mode is different.
1345 // NOTE: the tran type doesn't affect stage 2 TLB's as they only handle
1346 // one type of translation anyway
1347 if (miscRegValid
&& miscRegContext
== tc
->contextId() &&
1348 ((tranType
== curTranType
) || isStage2
)) {
1352 DPRINTF(TLBVerbose
, "TLB variables changed!\n");
1353 cpsr
= tc
->readMiscReg(MISCREG_CPSR
);
1355 // Dependencies: SCR/SCR_EL3, CPSR
1356 isSecure
= ArmISA::isSecure(tc
) &&
1357 !(tranType
& HypMode
) && !(tranType
& S1S2NsTran
);
1359 aarch64EL
= tranTypeEL(cpsr
, tranType
);
1360 aarch64
= isStage2
?
1362 ELIs64(tc
, aarch64EL
== EL0
? EL1
: aarch64EL
);
1364 hcr
= tc
->readMiscReg(MISCREG_HCR_EL2
);
1365 if (aarch64
) { // AArch64
1366 // determine EL we need to translate in
1367 switch (aarch64EL
) {
1369 if (HaveVirtHostExt(tc
) && hcr
.tge
== 1 && hcr
.e2h
== 1) {
1370 // VHE code for EL2&0 regime
1371 sctlr
= tc
->readMiscReg(MISCREG_SCTLR_EL2
);
1372 ttbcr
= tc
->readMiscReg(MISCREG_TCR_EL2
);
1373 uint64_t ttbr_asid
= ttbcr
.a1
?
1374 tc
->readMiscReg(MISCREG_TTBR1_EL2
) :
1375 tc
->readMiscReg(MISCREG_TTBR0_EL2
);
1376 asid
= bits(ttbr_asid
,
1377 (haveLargeAsid64
&& ttbcr
.as
) ? 63 : 55, 48);
1380 sctlr
= tc
->readMiscReg(MISCREG_SCTLR_EL1
);
1381 ttbcr
= tc
->readMiscReg(MISCREG_TCR_EL1
);
1382 uint64_t ttbr_asid
= ttbcr
.a1
?
1383 tc
->readMiscReg(MISCREG_TTBR1_EL1
) :
1384 tc
->readMiscReg(MISCREG_TTBR0_EL1
);
1385 asid
= bits(ttbr_asid
,
1386 (haveLargeAsid64
&& ttbcr
.as
) ? 63 : 55, 48);
1392 sctlr
= tc
->readMiscReg(MISCREG_SCTLR_EL1
);
1393 ttbcr
= tc
->readMiscReg(MISCREG_TCR_EL1
);
1394 uint64_t ttbr_asid
= ttbcr
.a1
?
1395 tc
->readMiscReg(MISCREG_TTBR1_EL1
) :
1396 tc
->readMiscReg(MISCREG_TTBR0_EL1
);
1397 asid
= bits(ttbr_asid
,
1398 (haveLargeAsid64
&& ttbcr
.as
) ? 63 : 55, 48);
1402 sctlr
= tc
->readMiscReg(MISCREG_SCTLR_EL2
);
1403 ttbcr
= tc
->readMiscReg(MISCREG_TCR_EL2
);
1405 // VHE code for EL2&0 regime
1406 uint64_t ttbr_asid
= ttbcr
.a1
?
1407 tc
->readMiscReg(MISCREG_TTBR1_EL2
) :
1408 tc
->readMiscReg(MISCREG_TTBR0_EL2
);
1409 asid
= bits(ttbr_asid
,
1410 (haveLargeAsid64
&& ttbcr
.as
) ? 63 : 55, 48);
1416 sctlr
= tc
->readMiscReg(MISCREG_SCTLR_EL3
);
1417 ttbcr
= tc
->readMiscReg(MISCREG_TCR_EL3
);
1422 scr
= tc
->readMiscReg(MISCREG_SCR_EL3
);
1423 isPriv
= aarch64EL
!= EL0
;
1424 if (haveVirtualization
) {
1425 vmid
= bits(tc
->readMiscReg(MISCREG_VTTBR_EL2
), 55, 48);
1426 isHyp
= aarch64EL
== EL2
;
1427 isHyp
|= tranType
& HypMode
;
1428 isHyp
&= (tranType
& S1S2NsTran
) == 0;
1429 isHyp
&= (tranType
& S1CTran
) == 0;
1431 if (HaveVirtHostExt(tc
) && hcr
.e2h
== 1 && hcr
.tge
==1) {
1435 if (hcr
.e2h
== 1 && (aarch64EL
== EL2
1436 || (hcr
.tge
==1 && aarch64EL
== EL0
))) {
1438 directToStage2
= false;
1440 stage2DescReq
= false;
1442 // Work out if we should skip the first stage of translation and go
1443 // directly to stage 2. This value is cached so we don't have to
1444 // compute it for every translation.
1445 bool sec
= !isSecure
|| (isSecure
&& IsSecureEL2Enabled(tc
));
1446 stage2Req
= isStage2
||
1447 (vm
&& !isHyp
&& sec
&&
1448 !(tranType
& S1CTran
) && (aarch64EL
< EL2
) &&
1449 !(tranType
& S1E1Tran
)); // <--- FIX THIS HACK
1450 stage2DescReq
= isStage2
|| (vm
&& !isHyp
&& sec
&&
1452 directToStage2
= !isStage2
&& stage2Req
&& !sctlr
.m
;
1457 directToStage2
= false;
1459 stage2DescReq
= false;
1462 sctlr
= tc
->readMiscReg(snsBankedIndex(MISCREG_SCTLR
, tc
,
1464 ttbcr
= tc
->readMiscReg(snsBankedIndex(MISCREG_TTBCR
, tc
,
1466 scr
= tc
->readMiscReg(MISCREG_SCR
);
1467 isPriv
= cpsr
.mode
!= MODE_USER
;
1468 if (longDescFormatInUse(tc
)) {
1469 uint64_t ttbr_asid
= tc
->readMiscReg(
1470 snsBankedIndex(ttbcr
.a1
? MISCREG_TTBR1
:
1473 asid
= bits(ttbr_asid
, 55, 48);
1474 } else { // Short-descriptor translation table format in use
1475 CONTEXTIDR context_id
= tc
->readMiscReg(snsBankedIndex(
1476 MISCREG_CONTEXTIDR
, tc
,!isSecure
));
1477 asid
= context_id
.asid
;
1479 prrr
= tc
->readMiscReg(snsBankedIndex(MISCREG_PRRR
, tc
,
1481 nmrr
= tc
->readMiscReg(snsBankedIndex(MISCREG_NMRR
, tc
,
1483 dacr
= tc
->readMiscReg(snsBankedIndex(MISCREG_DACR
, tc
,
1485 hcr
= tc
->readMiscReg(MISCREG_HCR
);
1487 if (haveVirtualization
) {
1488 vmid
= bits(tc
->readMiscReg(MISCREG_VTTBR
), 55, 48);
1489 isHyp
= cpsr
.mode
== MODE_HYP
;
1490 isHyp
|= tranType
& HypMode
;
1491 isHyp
&= (tranType
& S1S2NsTran
) == 0;
1492 isHyp
&= (tranType
& S1CTran
) == 0;
1494 sctlr
= tc
->readMiscReg(MISCREG_HSCTLR
);
1496 // Work out if we should skip the first stage of translation and go
1497 // directly to stage 2. This value is cached so we don't have to
1498 // compute it for every translation.
1499 bool sec
= !isSecure
|| (isSecure
&& IsSecureEL2Enabled(tc
));
1500 stage2Req
= hcr
.vm
&& !isStage2
&& !isHyp
&& sec
&&
1501 !(tranType
& S1CTran
);
1502 stage2DescReq
= hcr
.vm
&& !isStage2
&& !isHyp
&& sec
;
1503 directToStage2
= stage2Req
&& !sctlr
.m
;
1508 directToStage2
= false;
1509 stage2DescReq
= false;
1512 miscRegValid
= true;
1513 miscRegContext
= tc
->contextId();
1514 curTranType
= tranType
;
1518 TLB::tranTypeEL(CPSR cpsr
, ArmTranslationType type
)
1539 return currEL(cpsr
);
1542 panic("Unknown translation mode!\n");
1547 TLB::getTE(TlbEntry
**te
, const RequestPtr
&req
, ThreadContext
*tc
, Mode mode
,
1548 Translation
*translation
, bool timing
, bool functional
,
1549 bool is_secure
, TLB::ArmTranslationType tranType
)
1551 // In a 2-stage system, the IPA->PA translation can be started via this
1552 // call so make sure the miscRegs are correct.
1554 updateMiscReg(tc
, tranType
);
1556 bool is_fetch
= (mode
== Execute
);
1557 bool is_write
= (mode
== Write
);
1559 Addr vaddr_tainted
= req
->getVaddr();
1561 ExceptionLevel target_el
= aarch64
? aarch64EL
: EL1
;
1563 vaddr
= purifyTaggedAddr(vaddr_tainted
, tc
, target_el
, (TCR
)ttbcr
,
1566 vaddr
= vaddr_tainted
;
1568 *te
= lookup(vaddr
, asid
, vmid
, isHyp
, is_secure
, false, false, target_el
,
1571 if (req
->isPrefetch()) {
1572 // if the request is a prefetch don't attempt to fill the TLB or go
1573 // any further with the memory access (here we can safely use the
1574 // fault status for the short desc. format in all cases)
1576 return std::make_shared
<PrefetchAbort
>(
1577 vaddr_tainted
, ArmFault::PrefetchTLBMiss
, isStage2
);
1587 // start translation table walk, pass variables rather than
1588 // re-retreaving in table walker for speed
1589 DPRINTF(TLB
, "TLB Miss: Starting hardware table walker for %#x(%d:%d)\n",
1590 vaddr_tainted
, asid
, vmid
);
1592 fault
= tableWalker
->walk(req
, tc
, asid
, vmid
, isHyp
, mode
,
1593 translation
, timing
, functional
, is_secure
,
1594 tranType
, stage2DescReq
);
1595 // for timing mode, return and wait for table walk,
1596 if (timing
|| fault
!= NoFault
) {
1600 *te
= lookup(vaddr
, asid
, vmid
, isHyp
, is_secure
, false, false,
1617 TLB::getResultTe(TlbEntry
**te
, const RequestPtr
&req
,
1618 ThreadContext
*tc
, Mode mode
,
1619 Translation
*translation
, bool timing
, bool functional
,
1625 // We are already in the stage 2 TLB. Grab the table entry for stage
1626 // 2 only. We are here because stage 1 translation is disabled.
1627 TlbEntry
*s2Te
= NULL
;
1628 // Get the stage 2 table entry
1629 fault
= getTE(&s2Te
, req
, tc
, mode
, translation
, timing
, functional
,
1630 isSecure
, curTranType
);
1631 // Check permissions of stage 2
1632 if ((s2Te
!= NULL
) && (fault
== NoFault
)) {
1634 fault
= checkPermissions64(s2Te
, req
, mode
, tc
);
1636 fault
= checkPermissions(s2Te
, req
, mode
);
1642 TlbEntry
*s1Te
= NULL
;
1644 Addr vaddr_tainted
= req
->getVaddr();
1646 // Get the stage 1 table entry
1647 fault
= getTE(&s1Te
, req
, tc
, mode
, translation
, timing
, functional
,
1648 isSecure
, curTranType
);
1649 // only proceed if we have a valid table entry
1650 if ((s1Te
!= NULL
) && (fault
== NoFault
)) {
1651 // Check stage 1 permissions before checking stage 2
1653 fault
= checkPermissions64(s1Te
, req
, mode
, tc
);
1655 fault
= checkPermissions(s1Te
, req
, mode
);
1656 if (stage2Req
& (fault
== NoFault
)) {
1657 Stage2LookUp
*s2Lookup
= new Stage2LookUp(this, stage2Tlb
, *s1Te
,
1658 req
, translation
, mode
, timing
, functional
, !(s1Te
->ns
),
1660 fault
= s2Lookup
->getTe(tc
, mergeTe
);
1661 if (s2Lookup
->isComplete()) {
1663 // We've finished with the lookup so delete it
1666 // The lookup hasn't completed, so we can't delete it now. We
1667 // get round this by asking the object to self delete when the
1668 // translation is complete.
1669 s2Lookup
->setSelfDelete();
1672 // This case deals with an S1 hit (or bypass), followed by
1673 // an S2 hit-but-perms issue
1675 DPRINTF(TLBVerbose
, "s2TLB: reqVa %#x, reqPa %#x, fault %p\n",
1676 vaddr_tainted
, req
->hasPaddr() ? req
->getPaddr() : ~0, fault
);
1677 if (fault
!= NoFault
) {
1678 ArmFault
*armFault
= reinterpret_cast<ArmFault
*>(fault
.get());
1679 armFault
->annotate(ArmFault::S1PTW
, false);
1680 armFault
->annotate(ArmFault::OVA
, vaddr_tainted
);
1690 TLB::setTestInterface(SimObject
*_ti
)
1695 TlbTestInterface
*ti(dynamic_cast<TlbTestInterface
*>(_ti
));
1696 fatal_if(!ti
, "%s is not a valid ARM TLB tester\n", _ti
->name());
1702 TLB::testTranslation(const RequestPtr
&req
, Mode mode
,
1703 TlbEntry::DomainType domain
)
1705 if (!test
|| !req
->hasSize() || req
->getSize() == 0 ||
1706 req
->isCacheMaintenance()) {
1709 return test
->translationCheck(req
, isPriv
, mode
, domain
);
1714 TLB::testWalk(Addr pa
, Addr size
, Addr va
, bool is_secure
, Mode mode
,
1715 TlbEntry::DomainType domain
, LookupLevel lookup_level
)
1720 return test
->walkCheck(pa
, size
, va
, is_secure
, isPriv
, mode
,
1721 domain
, lookup_level
);
1727 ArmTLBParams::create()
1729 return new ArmISA::TLB(this);