2 * Copyright (c) 2010-2013, 2016-2020 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/tlbi_op.hh"
56 #include "arch/arm/utility.hh"
57 #include "base/inifile.hh"
58 #include "base/str.hh"
59 #include "base/trace.hh"
60 #include "cpu/base.hh"
61 #include "cpu/thread_context.hh"
62 #include "debug/Checkpoint.hh"
63 #include "debug/TLB.hh"
64 #include "debug/TLBVerbose.hh"
65 #include "mem/packet_access.hh"
66 #include "mem/page_table.hh"
67 #include "mem/request.hh"
68 #include "params/ArmTLB.hh"
69 #include "sim/full_system.hh"
70 #include "sim/process.hh"
71 #include "sim/pseudo_inst.hh"
74 using namespace ArmISA
;
76 TLB::TLB(const ArmTLBParams
&p
)
77 : BaseTLB(p
), table(new TlbEntry
[p
.size
]), size(p
.size
),
78 isStage2(p
.is_stage2
), stage2Req(false), stage2DescReq(false), _attr(0),
79 directToStage2(false), tableWalker(p
.walker
), stage2Tlb(NULL
),
80 stage2Mmu(NULL
), test(nullptr), stats(this), rangeMRU(1),
81 aarch64(false), aarch64EL(EL0
), isPriv(false), isSecure(false),
82 isHyp(false), asid(0), vmid(0), hcr(0), dacr(0),
83 miscRegValid(false), miscRegContext(0), curTranType(NormalTran
)
85 const ArmSystem
*sys
= dynamic_cast<const ArmSystem
*>(p
.sys
);
87 tableWalker
->setTlb(this);
89 // Cache system-level properties
90 haveLPAE
= tableWalker
->haveLPAE();
91 haveVirtualization
= tableWalker
->haveVirtualization();
92 haveLargeAsid64
= tableWalker
->haveLargeAsid64();
93 physAddrRange
= tableWalker
->physAddrRange();
96 m5opRange
= sys
->m5opRange();
107 if (stage2Mmu
&& !isStage2
)
108 stage2Tlb
= stage2Mmu
->stage2Tlb();
112 TLB::setMMU(Stage2MMU
*m
, RequestorID requestor_id
)
115 tableWalker
->setMMU(m
, requestor_id
);
119 TLB::translateFunctional(ThreadContext
*tc
, Addr va
, Addr
&pa
)
123 if (directToStage2
) {
125 return stage2Tlb
->translateFunctional(tc
, va
, pa
);
128 TlbEntry
*e
= lookup(va
, asid
, vmid
, isHyp
, isSecure
, true, false,
129 aarch64
? aarch64EL
: EL1
, false);
137 TLB::finalizePhysical(const RequestPtr
&req
,
138 ThreadContext
*tc
, Mode mode
) const
140 const Addr paddr
= req
->getPaddr();
142 if (m5opRange
.contains(paddr
)) {
144 PseudoInst::decodeAddrOffset(paddr
- m5opRange
.start(), func
);
145 req
->setLocalAccessor(
146 [func
, mode
](ThreadContext
*tc
, PacketPtr pkt
) -> Cycles
149 PseudoInst::pseudoInst
<PseudoInstABI
>(tc
, func
, ret
);
161 TLB::lookup(Addr va
, uint16_t asn
, uint8_t vmid
, bool hyp
, bool secure
,
162 bool functional
, bool ignore_asn
, ExceptionLevel target_el
,
166 TlbEntry
*retval
= NULL
;
168 // Maintaining LRU array
170 while (retval
== NULL
&& x
< size
) {
171 if ((!ignore_asn
&& table
[x
].match(va
, asn
, vmid
, hyp
, secure
, false,
172 target_el
, in_host
)) ||
173 (ignore_asn
&& table
[x
].match(va
, vmid
, hyp
, secure
, target_el
,
175 // We only move the hit entry ahead when the position is higher
177 if (x
> rangeMRU
&& !functional
) {
178 TlbEntry tmp_entry
= table
[x
];
179 for (int i
= x
; i
> 0; i
--)
180 table
[i
] = table
[i
- 1];
181 table
[0] = tmp_entry
;
191 DPRINTF(TLBVerbose
, "Lookup %#x, asn %#x -> %s vmn 0x%x hyp %d secure %d "
192 "ppn %#x size: %#x pa: %#x ap:%d ns:%d nstid:%d g:%d asid: %d "
194 va
, asn
, retval
? "hit" : "miss", vmid
, hyp
, secure
,
195 retval
? retval
->pfn
: 0, retval
? retval
->size
: 0,
196 retval
? retval
->pAddr(va
) : 0, retval
? retval
->ap
: 0,
197 retval
? retval
->ns
: 0, retval
? retval
->nstid
: 0,
198 retval
? retval
->global
: 0, retval
? retval
->asid
: 0,
199 retval
? retval
->el
: 0);
204 // insert a new TLB entry
206 TLB::insert(Addr addr
, TlbEntry
&entry
)
208 DPRINTF(TLB
, "Inserting entry into TLB with pfn:%#x size:%#x vpn: %#x"
209 " asid:%d vmid:%d N:%d global:%d valid:%d nc:%d xn:%d"
210 " ap:%#x domain:%#x ns:%d nstid:%d isHyp:%d\n", entry
.pfn
,
211 entry
.size
, entry
.vpn
, entry
.asid
, entry
.vmid
, entry
.N
,
212 entry
.global
, entry
.valid
, entry
.nonCacheable
, entry
.xn
,
213 entry
.ap
, static_cast<uint8_t>(entry
.domain
), entry
.ns
, entry
.nstid
,
216 if (table
[size
- 1].valid
)
217 DPRINTF(TLB
, " - Replacing Valid entry %#x, asn %d vmn %d ppn %#x "
218 "size: %#x ap:%d ns:%d nstid:%d g:%d isHyp:%d el: %d\n",
219 table
[size
-1].vpn
<< table
[size
-1].N
, table
[size
-1].asid
,
220 table
[size
-1].vmid
, table
[size
-1].pfn
<< table
[size
-1].N
,
221 table
[size
-1].size
, table
[size
-1].ap
, table
[size
-1].ns
,
222 table
[size
-1].nstid
, table
[size
-1].global
, table
[size
-1].isHyp
,
225 //inserting to MRU position and evicting the LRU one
227 for (int i
= size
- 1; i
> 0; --i
)
228 table
[i
] = table
[i
-1];
232 ppRefills
->notify(1);
236 TLB::printTlb() const
240 DPRINTF(TLB
, "Current TLB contents:\n");
244 DPRINTF(TLB
, " * %s\n", te
->print());
252 DPRINTF(TLB
, "Flushing all TLB entries\n");
258 DPRINTF(TLB
, " - %s\n", te
->print());
260 stats
.flushedEntries
++;
266 // If there's a second stage TLB (and we're not it) then flush it as well
268 stage2Tlb
->flushAll();
273 TLB::flush(const TLBIALL
& tlbi_op
)
275 DPRINTF(TLB
, "Flushing all TLB entries (%s lookup)\n",
276 (tlbi_op
.secureLookup
? "secure" : "non-secure"));
281 const bool el_match
= te
->checkELMatch(
282 tlbi_op
.targetEL
, tlbi_op
.inHost
);
283 if (te
->valid
&& tlbi_op
.secureLookup
== !te
->nstid
&&
284 (te
->vmid
== vmid
|| tlbi_op
.el2Enabled
) && el_match
) {
286 DPRINTF(TLB
, " - %s\n", te
->print());
288 stats
.flushedEntries
++;
295 // If there's a second stage TLB (and we're not it) then flush it as well
296 // if we're currently in hyp mode
297 if (!isStage2
&& isHyp
) {
298 stage2Tlb
->flush(tlbi_op
.makeStage2());
303 TLB::flush(const TLBIALLEL
&tlbi_op
)
305 DPRINTF(TLB
, "Flushing all TLB entries (%s lookup)\n",
306 (tlbi_op
.secureLookup
? "secure" : "non-secure"));
311 const bool el_match
= te
->checkELMatch(
312 tlbi_op
.targetEL
, tlbi_op
.inHost
);
313 if (te
->valid
&& tlbi_op
.secureLookup
== !te
->nstid
&& el_match
) {
315 DPRINTF(TLB
, " - %s\n", te
->print());
317 stats
.flushedEntries
++;
324 // If there's a second stage TLB (and we're not it)
325 // and if we're targeting EL1
326 // then flush it as well
327 if (!isStage2
&& tlbi_op
.targetEL
== EL1
) {
328 stage2Tlb
->flush(tlbi_op
.makeStage2());
333 TLB::flush(const TLBIVMALL
&tlbi_op
)
335 DPRINTF(TLB
, "Flushing all TLB entries (%s lookup)\n",
336 (tlbi_op
.secureLookup
? "secure" : "non-secure"));
341 const bool el_match
= te
->checkELMatch(
342 tlbi_op
.targetEL
, tlbi_op
.inHost
);
343 if (te
->valid
&& tlbi_op
.secureLookup
== !te
->nstid
&&
344 (te
->vmid
== vmid
|| !tlbi_op
.el2Enabled
) && el_match
) {
346 DPRINTF(TLB
, " - %s\n", te
->print());
348 stats
.flushedEntries
++;
355 // If there's a second stage TLB (and we're not it) then flush it as well
356 // if we're currently in hyp mode
357 if (!isStage2
&& tlbi_op
.stage2
) {
358 stage2Tlb
->flush(tlbi_op
.makeStage2());
363 TLB::flush(const TLBIALLN
&tlbi_op
)
365 bool hyp
= tlbi_op
.targetEL
== EL2
;
367 DPRINTF(TLB
, "Flushing all NS TLB entries (%s lookup)\n",
368 (hyp
? "hyp" : "non-hyp"));
373 const bool el_match
= te
->checkELMatch(tlbi_op
.targetEL
, false);
375 if (te
->valid
&& te
->nstid
&& te
->isHyp
== hyp
&& el_match
) {
377 DPRINTF(TLB
, " - %s\n", te
->print());
378 stats
.flushedEntries
++;
386 // If there's a second stage TLB (and we're not it) then flush it as well
387 if (!isStage2
&& !hyp
) {
388 stage2Tlb
->flush(tlbi_op
.makeStage2());
393 TLB::flush(const TLBIMVA
&tlbi_op
)
395 DPRINTF(TLB
, "Flushing TLB entries with mva: %#x, asid: %#x "
396 "(%s lookup)\n", tlbi_op
.addr
, tlbi_op
.asid
,
397 (tlbi_op
.secureLookup
? "secure" : "non-secure"));
398 _flushMva(tlbi_op
.addr
, tlbi_op
.asid
, tlbi_op
.secureLookup
, false,
399 tlbi_op
.targetEL
, tlbi_op
.inHost
);
400 stats
.flushTlbMvaAsid
++;
404 TLB::flush(const TLBIASID
&tlbi_op
)
406 DPRINTF(TLB
, "Flushing TLB entries with asid: %#x (%s lookup)\n",
407 tlbi_op
.asid
, (tlbi_op
.secureLookup
? "secure" : "non-secure"));
414 if (te
->valid
&& te
->asid
== tlbi_op
.asid
&&
415 tlbi_op
.secureLookup
== !te
->nstid
&&
416 (te
->vmid
== vmid
|| tlbi_op
.el2Enabled
) &&
417 te
->checkELMatch(tlbi_op
.targetEL
, tlbi_op
.inHost
)) {
420 DPRINTF(TLB
, " - %s\n", te
->print());
421 stats
.flushedEntries
++;
425 stats
.flushTlbAsid
++;
429 TLB::flush(const TLBIMVAA
&tlbi_op
) {
431 DPRINTF(TLB
, "Flushing TLB entries with mva: %#x (%s lookup)\n",
433 (tlbi_op
.secureLookup
? "secure" : "non-secure"));
434 _flushMva(tlbi_op
.addr
, 0xbeef, tlbi_op
.secureLookup
, true,
435 tlbi_op
.targetEL
, tlbi_op
.inHost
);
440 TLB::_flushMva(Addr mva
, uint64_t asn
, bool secure_lookup
,
441 bool ignore_asn
, ExceptionLevel target_el
, bool in_host
)
444 // D5.7.2: Sign-extend address to 64 bits
447 bool hyp
= target_el
== EL2
;
449 te
= lookup(mva
, asn
, vmid
, hyp
, secure_lookup
, true, ignore_asn
,
452 if (secure_lookup
== !te
->nstid
) {
453 DPRINTF(TLB
, " - %s\n", te
->print());
455 stats
.flushedEntries
++;
457 te
= lookup(mva
, asn
, vmid
, hyp
, secure_lookup
, true, ignore_asn
,
463 TLB::flush(const TLBIIPA
&tlbi_op
)
467 // Note, TLBIIPA::makeStage2 will generare a TLBIMVAA
468 stage2Tlb
->flush(tlbi_op
.makeStage2());
474 // We might have unserialized something or switched CPUs, so make
475 // sure to re-read the misc regs.
476 miscRegValid
= false;
480 TLB::takeOverFrom(BaseTLB
*_otlb
)
482 TLB
*otlb
= dynamic_cast<TLB
*>(_otlb
);
483 /* Make sure we actually have a valid type */
486 haveLPAE
= otlb
->haveLPAE
;
487 directToStage2
= otlb
->directToStage2
;
488 stage2Req
= otlb
->stage2Req
;
489 stage2DescReq
= otlb
->stage2DescReq
;
491 /* Sync the stage2 MMU if they exist in both
492 * the old CPU and the new
495 stage2Tlb
&& otlb
->stage2Tlb
) {
496 stage2Tlb
->takeOverFrom(otlb
->stage2Tlb
);
499 panic("Incompatible TLB type!");
503 TLB::TlbStats::TlbStats(Stats::Group
*parent
)
504 : Stats::Group(parent
),
505 ADD_STAT(instHits
,"ITB inst hits"),
506 ADD_STAT(instMisses
, "ITB inst misses"),
507 ADD_STAT(readHits
, "DTB read hits"),
508 ADD_STAT(readMisses
, "DTB read misses"),
509 ADD_STAT(writeHits
, "DTB write hits"),
510 ADD_STAT(writeMisses
, "DTB write misses"),
511 ADD_STAT(inserts
, "Number of times an entry is inserted into the TLB"),
512 ADD_STAT(flushTlb
, "Number of times complete TLB was flushed"),
513 ADD_STAT(flushTlbMva
, "Number of times TLB was flushed by MVA"),
514 ADD_STAT(flushTlbMvaAsid
, "Number of times TLB was flushed by MVA & ASID"),
515 ADD_STAT(flushTlbAsid
, "Number of times TLB was flushed by ASID"),
516 ADD_STAT(flushedEntries
, "Number of entries that have been flushed"
518 ADD_STAT(alignFaults
, "Number of TLB faults due to alignment"
520 ADD_STAT(prefetchFaults
, "Number of TLB faults due to prefetch"),
521 ADD_STAT(domainFaults
, "Number of TLB faults due to domain restrictions"),
522 ADD_STAT(permsFaults
, "Number of TLB faults due to permissions"
524 ADD_STAT(readAccesses
, "DTB read accesses", readHits
+ readMisses
),
525 ADD_STAT(writeAccesses
, "DTB write accesses", writeHits
+ writeMisses
),
526 ADD_STAT(instAccesses
, "ITB inst accesses", instHits
+ instMisses
),
527 ADD_STAT(hits
, "Total TLB (inst and data) hits",
528 readHits
+ writeHits
+ instHits
),
529 ADD_STAT(misses
, "Total TLB (inst and data) misses",
530 readMisses
+ writeMisses
+ instMisses
),
531 ADD_STAT(accesses
, "Total TLB (inst and data) accesses",
532 readAccesses
+ writeAccesses
+ instAccesses
)
537 TLB::regProbePoints()
539 ppRefills
.reset(new ProbePoints::PMU(getProbeManager(), "Refills"));
543 TLB::translateSe(const RequestPtr
&req
, ThreadContext
*tc
, Mode mode
,
544 Translation
*translation
, bool &delay
, bool timing
)
547 Addr vaddr_tainted
= req
->getVaddr();
550 vaddr
= purifyTaggedAddr(vaddr_tainted
, tc
, aarch64EL
, (TCR
)ttbcr
,
553 vaddr
= vaddr_tainted
;
554 Request::Flags flags
= req
->getFlags();
556 bool is_fetch
= (mode
== Execute
);
557 bool is_write
= (mode
== Write
);
560 if (sctlr
.a
|| !(flags
& AllowUnaligned
)) {
561 if (vaddr
& mask(flags
& AlignmentMask
)) {
562 // LPAE is always disabled in SE mode
563 return std::make_shared
<DataAbort
>(
565 TlbEntry::DomainType::NoAccess
, is_write
,
566 ArmFault::AlignmentFault
, isStage2
,
573 Process
*p
= tc
->getProcessPtr();
575 if (!p
->pTable
->translate(vaddr
, paddr
))
576 return std::make_shared
<GenericPageTableFault
>(vaddr_tainted
);
577 req
->setPaddr(paddr
);
579 return finalizePhysical(req
, tc
, mode
);
583 TLB::checkPermissions(TlbEntry
*te
, const RequestPtr
&req
, Mode mode
)
585 // a data cache maintenance instruction that operates by MVA does
586 // not generate a Data Abort exeception due to a Permission fault
587 if (req
->isCacheMaintenance()) {
591 Addr vaddr
= req
->getVaddr(); // 32-bit don't have to purify
592 Request::Flags flags
= req
->getFlags();
593 bool is_fetch
= (mode
== Execute
);
594 bool is_write
= (mode
== Write
);
595 bool is_priv
= isPriv
&& !(flags
& UserMode
);
597 // Get the translation type from the actuall table entry
598 ArmFault::TranMethod tranMethod
= te
->longDescFormat
? ArmFault::LpaeTran
599 : ArmFault::VmsaTran
;
601 // If this is the second stage of translation and the request is for a
602 // stage 1 page table walk then we need to check the HCR.PTW bit. This
603 // allows us to generate a fault if the request targets an area marked
604 // as a device or strongly ordered.
605 if (isStage2
&& req
->isPTWalk() && hcr
.ptw
&&
606 (te
->mtype
!= TlbEntry::MemoryType::Normal
)) {
607 return std::make_shared
<DataAbort
>(
608 vaddr
, te
->domain
, is_write
,
609 ArmFault::PermissionLL
+ te
->lookupLevel
,
610 isStage2
, tranMethod
);
613 // Generate an alignment fault for unaligned data accesses to device or
614 // strongly ordered memory
616 if (te
->mtype
!= TlbEntry::MemoryType::Normal
) {
617 if (vaddr
& mask(flags
& AlignmentMask
)) {
619 return std::make_shared
<DataAbort
>(
620 vaddr
, TlbEntry::DomainType::NoAccess
, is_write
,
621 ArmFault::AlignmentFault
, isStage2
,
627 if (te
->nonCacheable
) {
628 // Prevent prefetching from I/O devices.
629 if (req
->isPrefetch()) {
630 // Here we can safely use the fault status for the short
631 // desc. format in all cases
632 return std::make_shared
<PrefetchAbort
>(
633 vaddr
, ArmFault::PrefetchUncacheable
,
634 isStage2
, tranMethod
);
638 if (!te
->longDescFormat
) {
639 switch ((dacr
>> (static_cast<uint8_t>(te
->domain
) * 2)) & 0x3) {
641 stats
.domainFaults
++;
642 DPRINTF(TLB
, "TLB Fault: Data abort on domain. DACR: %#x"
643 " domain: %#x write:%d\n", dacr
,
644 static_cast<uint8_t>(te
->domain
), is_write
);
646 // Use PC value instead of vaddr because vaddr might
647 // be aligned to cache line and should not be the
648 // address reported in FAR
649 return std::make_shared
<PrefetchAbort
>(
651 ArmFault::DomainLL
+ te
->lookupLevel
,
652 isStage2
, tranMethod
);
654 return std::make_shared
<DataAbort
>(
655 vaddr
, te
->domain
, is_write
,
656 ArmFault::DomainLL
+ te
->lookupLevel
,
657 isStage2
, tranMethod
);
659 // Continue with permissions check
662 panic("UNPRED domain\n");
668 // The 'ap' variable is AP[2:0] or {AP[2,1],1b'0}, i.e. always three bits
669 uint8_t ap
= te
->longDescFormat
? te
->ap
<< 1 : te
->ap
;
670 uint8_t hap
= te
->hap
;
672 if (sctlr
.afe
== 1 || te
->longDescFormat
)
676 bool isWritable
= true;
677 // If this is a stage 2 access (eg for reading stage 1 page table entries)
678 // then don't perform the AP permissions check, we stil do the HAP check
685 DPRINTF(TLB
, "Access permissions 0, checking rs:%#x\n",
688 switch ((int)sctlr
.rs
) {
693 abt
= is_write
|| !is_priv
;
709 abt
= !is_priv
&& is_write
;
710 isWritable
= is_priv
;
716 panic("UNPRED premissions\n");
718 abt
= !is_priv
|| is_write
;
727 panic("Unknown permissions %#x\n", ap
);
731 bool hapAbt
= is_write
? !(hap
& 2) : !(hap
& 1);
732 bool xn
= te
->xn
|| (isWritable
&& sctlr
.wxn
) ||
733 (ap
== 3 && sctlr
.uwxn
&& is_priv
);
734 if (is_fetch
&& (abt
|| xn
||
735 (te
->longDescFormat
&& te
->pxn
&& is_priv
) ||
736 (isSecure
&& te
->ns
&& scr
.sif
))) {
738 DPRINTF(TLB
, "TLB Fault: Prefetch abort on permission check. AP:%d "
739 "priv:%d write:%d ns:%d sif:%d sctlr.afe: %d \n",
740 ap
, is_priv
, is_write
, te
->ns
, scr
.sif
,sctlr
.afe
);
741 // Use PC value instead of vaddr because vaddr might be aligned to
742 // cache line and should not be the address reported in FAR
743 return std::make_shared
<PrefetchAbort
>(
745 ArmFault::PermissionLL
+ te
->lookupLevel
,
746 isStage2
, tranMethod
);
747 } else if (abt
| hapAbt
) {
749 DPRINTF(TLB
, "TLB Fault: Data abort on permission check. AP:%d priv:%d"
750 " write:%d\n", ap
, is_priv
, is_write
);
751 return std::make_shared
<DataAbort
>(
752 vaddr
, te
->domain
, is_write
,
753 ArmFault::PermissionLL
+ te
->lookupLevel
,
754 isStage2
| !abt
, tranMethod
);
761 TLB::checkPermissions64(TlbEntry
*te
, const RequestPtr
&req
, Mode mode
,
766 // A data cache maintenance instruction that operates by VA does
767 // not generate a Permission fault unless:
768 // * It is a data cache invalidate (dc ivac) which requires write
769 // permissions to the VA, or
770 // * It is executed from EL0
771 if (req
->isCacheClean() && aarch64EL
!= EL0
&& !isStage2
) {
775 Addr vaddr_tainted
= req
->getVaddr();
776 Addr vaddr
= purifyTaggedAddr(vaddr_tainted
, tc
, aarch64EL
, (TCR
)ttbcr
,
779 Request::Flags flags
= req
->getFlags();
780 bool is_fetch
= (mode
== Execute
);
781 // Cache clean operations require read permissions to the specified VA
782 bool is_write
= !req
->isCacheClean() && mode
== Write
;
783 bool is_atomic
= req
->isAtomic();
784 M5_VAR_USED
bool is_priv
= isPriv
&& !(flags
& UserMode
);
786 updateMiscReg(tc
, curTranType
);
788 // If this is the second stage of translation and the request is for a
789 // stage 1 page table walk then we need to check the HCR.PTW bit. This
790 // allows us to generate a fault if the request targets an area marked
791 // as a device or strongly ordered.
792 if (isStage2
&& req
->isPTWalk() && hcr
.ptw
&&
793 (te
->mtype
!= TlbEntry::MemoryType::Normal
)) {
794 return std::make_shared
<DataAbort
>(
795 vaddr_tainted
, te
->domain
, is_write
,
796 ArmFault::PermissionLL
+ te
->lookupLevel
,
797 isStage2
, ArmFault::LpaeTran
);
800 // Generate an alignment fault for unaligned accesses to device or
801 // strongly ordered memory
803 if (te
->mtype
!= TlbEntry::MemoryType::Normal
) {
804 if (vaddr
& mask(flags
& AlignmentMask
)) {
806 return std::make_shared
<DataAbort
>(
808 TlbEntry::DomainType::NoAccess
,
809 is_atomic
? false : is_write
,
810 ArmFault::AlignmentFault
, isStage2
,
816 if (te
->nonCacheable
) {
817 // Prevent prefetching from I/O devices.
818 if (req
->isPrefetch()) {
819 // Here we can safely use the fault status for the short
820 // desc. format in all cases
821 return std::make_shared
<PrefetchAbort
>(
823 ArmFault::PrefetchUncacheable
,
824 isStage2
, ArmFault::LpaeTran
);
828 uint8_t ap
= 0x3 & (te
->ap
); // 2-bit access protection field
831 bool wxn
= sctlr
.wxn
;
833 uint8_t pxn
= te
->pxn
;
834 bool r
= (!is_write
&& !is_fetch
);
838 if (ArmSystem::haveEL(tc
, EL3
) && isSecure
&& te
->ns
&& scr
.sif
)
841 // grant_read is used for faults from an atomic instruction that
842 // both reads and writes from a memory location. From a ISS point
843 // of view they count as read if a read to that address would have
844 // generated the fault; they count as writes otherwise
845 bool grant_read
= true;
846 DPRINTF(TLBVerbose
, "Checking permissions: ap:%d, xn:%d, pxn:%d, r:%d, "
847 "w:%d, x:%d, is_priv: %d, wxn: %d\n", ap
, xn
,
848 pxn
, r
, w
, x
, is_priv
, wxn
);
851 assert(ArmSystem::haveVirtualization(tc
) && aarch64EL
!= EL2
);
852 // In stage 2 we use the hypervisor access permission bits.
853 // The following permissions are described in ARM DDI 0487A.f
855 uint8_t hap
= 0x3 & te
->hap
;
856 grant_read
= hap
& 0x1;
858 // sctlr.wxn overrides the xn bit
860 } else if (is_atomic
) {
863 } else if (is_write
) {
872 grant_read
= ap
& 0x1;
873 uint8_t perm
= (ap
<< 2) | (xn
<< 1) | pxn
;
883 grant
= r
|| w
|| (x
&& !wxn
);
904 if (checkPAN(tc
, ap
, req
, mode
)) {
910 uint8_t perm
= (ap
<< 2) | (xn
<< 1) | pxn
;
914 grant
= r
|| w
|| (x
&& !wxn
);
922 // regions that are writeable at EL0 should not be
944 if (hcr
.e2h
&& checkPAN(tc
, ap
, req
, mode
)) {
952 uint8_t perm
= (ap
& 0x2) | xn
;
955 grant
= r
|| w
|| (x
&& !wxn
);
977 DPRINTF(TLB
, "TLB Fault: Prefetch abort on permission check. "
978 "AP:%d priv:%d write:%d ns:%d sif:%d "
980 ap
, is_priv
, is_write
, te
->ns
, scr
.sif
, sctlr
.afe
);
981 // Use PC value instead of vaddr because vaddr might be aligned to
982 // cache line and should not be the address reported in FAR
983 return std::make_shared
<PrefetchAbort
>(
985 ArmFault::PermissionLL
+ te
->lookupLevel
,
986 isStage2
, ArmFault::LpaeTran
);
989 DPRINTF(TLB
, "TLB Fault: Data abort on permission check. AP:%d "
990 "priv:%d write:%d\n", ap
, is_priv
, is_write
);
991 return std::make_shared
<DataAbort
>(
992 vaddr_tainted
, te
->domain
,
993 (is_atomic
&& !grant_read
) ? false : is_write
,
994 ArmFault::PermissionLL
+ te
->lookupLevel
,
995 isStage2
, ArmFault::LpaeTran
);
1003 TLB::checkPAN(ThreadContext
*tc
, uint8_t ap
, const RequestPtr
&req
, Mode mode
)
1005 // The PAN bit has no effect on:
1006 // 1) Instruction accesses.
1007 // 2) Data Cache instructions other than DC ZVA
1008 // 3) Address translation instructions, other than ATS1E1RP and
1009 // ATS1E1WP when ARMv8.2-ATS1E1 is implemented. (Unimplemented in
1011 // 4) Unprivileged instructions (Unimplemented in gem5)
1012 AA64MMFR1 mmfr1
= tc
->readMiscReg(MISCREG_ID_AA64MMFR1_EL1
);
1013 if (mmfr1
.pan
&& cpsr
.pan
&& (ap
& 0x1) && mode
!= Execute
&&
1014 (!req
->isCacheMaintenance() ||
1015 (req
->getFlags() & Request::CACHE_BLOCK_ZERO
))) {
1023 TLB::translateMmuOff(ThreadContext
*tc
, const RequestPtr
&req
, Mode mode
,
1024 TLB::ArmTranslationType tranType
, Addr vaddr
, bool long_desc_format
)
1026 bool is_fetch
= (mode
== Execute
);
1027 bool is_atomic
= req
->isAtomic();
1028 req
->setPaddr(vaddr
);
1029 // When the MMU is off the security attribute corresponds to the
1030 // security state of the processor
1032 req
->setFlags(Request::SECURE
);
1035 bool selbit
= bits(vaddr
, 55);
1036 TCR tcr1
= tc
->readMiscReg(MISCREG_TCR_EL1
);
1037 int topbit
= computeAddrTop(tc
, selbit
, is_fetch
, tcr1
, currEL(tc
));
1038 int addr_sz
= bits(vaddr
, topbit
, physAddrRange
);
1042 f
= std::make_shared
<PrefetchAbort
>(vaddr
,
1043 ArmFault::AddressSizeLL
, isStage2
, ArmFault::LpaeTran
);
1045 f
= std::make_shared
<DataAbort
>( vaddr
,
1046 TlbEntry::DomainType::NoAccess
,
1047 is_atomic
? false : mode
==Write
,
1048 ArmFault::AddressSizeLL
, isStage2
, ArmFault::LpaeTran
);
1053 // @todo: double check this (ARM ARM issue C B3.2.1)
1054 if (long_desc_format
|| sctlr
.tre
== 0 || nmrr
.ir0
== 0 ||
1055 nmrr
.or0
== 0 || prrr
.tr0
!= 0x2) {
1056 if (!req
->isCacheMaintenance()) {
1057 req
->setFlags(Request::UNCACHEABLE
);
1059 req
->setFlags(Request::STRICT_ORDER
);
1062 // Set memory attributes
1064 temp_te
.ns
= !isSecure
;
1065 bool dc
= (HaveVirtHostExt(tc
)
1066 && hcr
.e2h
== 1 && hcr
.tge
== 1) ? 0: hcr
.dc
;
1067 bool i_cacheability
= sctlr
.i
&& !sctlr
.m
;
1068 if (isStage2
|| !dc
|| isSecure
||
1069 (isHyp
&& !(tranType
& S1CTran
))) {
1071 temp_te
.mtype
= is_fetch
? TlbEntry::MemoryType::Normal
1072 : TlbEntry::MemoryType::StronglyOrdered
;
1073 temp_te
.innerAttrs
= i_cacheability
? 0x2: 0x0;
1074 temp_te
.outerAttrs
= i_cacheability
? 0x2: 0x0;
1075 temp_te
.shareable
= true;
1076 temp_te
.outerShareable
= true;
1078 temp_te
.mtype
= TlbEntry::MemoryType::Normal
;
1079 temp_te
.innerAttrs
= 0x3;
1080 temp_te
.outerAttrs
= 0x3;
1081 temp_te
.shareable
= false;
1082 temp_te
.outerShareable
= false;
1084 temp_te
.setAttributes(long_desc_format
);
1085 DPRINTF(TLBVerbose
, "(No MMU) setting memory attributes: shareable: "
1086 "%d, innerAttrs: %d, outerAttrs: %d, isStage2: %d\n",
1087 temp_te
.shareable
, temp_te
.innerAttrs
, temp_te
.outerAttrs
,
1089 setAttr(temp_te
.attributes
);
1091 return testTranslation(req
, mode
, TlbEntry::DomainType::NoAccess
);
1095 TLB::translateMmuOn(ThreadContext
* tc
, const RequestPtr
&req
, Mode mode
,
1096 Translation
*translation
, bool &delay
, bool timing
,
1097 bool functional
, Addr vaddr
,
1098 ArmFault::TranMethod tranMethod
)
1100 TlbEntry
*te
= NULL
;
1101 bool is_fetch
= (mode
== Execute
);
1104 Request::Flags flags
= req
->getFlags();
1105 Addr vaddr_tainted
= req
->getVaddr();
1107 Fault fault
= getResultTe(&te
, req
, tc
, mode
, translation
, timing
,
1108 functional
, &mergeTe
);
1109 // only proceed if we have a valid table entry
1110 if ((te
== NULL
) && (fault
== NoFault
)) delay
= true;
1112 // If we have the table entry transfer some of the attributes to the
1113 // request that triggered the translation
1115 // Set memory attributes
1117 "Setting memory attributes: shareable: %d, innerAttrs: %d, "
1118 "outerAttrs: %d, mtype: %d, isStage2: %d\n",
1119 te
->shareable
, te
->innerAttrs
, te
->outerAttrs
,
1120 static_cast<uint8_t>(te
->mtype
), isStage2
);
1121 setAttr(te
->attributes
);
1123 if (te
->nonCacheable
&& !req
->isCacheMaintenance())
1124 req
->setFlags(Request::UNCACHEABLE
);
1126 // Require requests to be ordered if the request goes to
1127 // strongly ordered or device memory (i.e., anything other
1128 // than normal memory requires strict order).
1129 if (te
->mtype
!= TlbEntry::MemoryType::Normal
)
1130 req
->setFlags(Request::STRICT_ORDER
);
1132 Addr pa
= te
->pAddr(vaddr
);
1135 if (isSecure
&& !te
->ns
) {
1136 req
->setFlags(Request::SECURE
);
1138 if (!is_fetch
&& fault
== NoFault
&&
1139 (vaddr
& mask(flags
& AlignmentMask
)) &&
1140 (te
->mtype
!= TlbEntry::MemoryType::Normal
)) {
1141 // Unaligned accesses to Device memory should always cause an
1142 // abort regardless of sctlr.a
1143 stats
.alignFaults
++;
1144 bool is_write
= (mode
== Write
);
1145 return std::make_shared
<DataAbort
>(
1147 TlbEntry::DomainType::NoAccess
, is_write
,
1148 ArmFault::AlignmentFault
, isStage2
,
1152 // Check for a trickbox generated address fault
1153 if (fault
== NoFault
)
1154 fault
= testTranslation(req
, mode
, te
->domain
);
1157 if (fault
== NoFault
) {
1158 // Don't try to finalize a physical address unless the
1159 // translation has completed (i.e., there is a table entry).
1160 return te
? finalizePhysical(req
, tc
, mode
) : NoFault
;
1167 TLB::translateFs(const RequestPtr
&req
, ThreadContext
*tc
, Mode mode
,
1168 Translation
*translation
, bool &delay
, bool timing
,
1169 TLB::ArmTranslationType tranType
, bool functional
)
1171 // No such thing as a functional timing access
1172 assert(!(timing
&& functional
));
1174 updateMiscReg(tc
, tranType
);
1176 Addr vaddr_tainted
= req
->getVaddr();
1179 vaddr
= purifyTaggedAddr(vaddr_tainted
, tc
, aarch64EL
, (TCR
)ttbcr
,
1182 vaddr
= vaddr_tainted
;
1183 Request::Flags flags
= req
->getFlags();
1185 bool is_fetch
= (mode
== Execute
);
1186 bool is_write
= (mode
== Write
);
1187 bool long_desc_format
= aarch64
|| longDescFormatInUse(tc
);
1188 ArmFault::TranMethod tranMethod
= long_desc_format
? ArmFault::LpaeTran
1189 : ArmFault::VmsaTran
;
1192 "CPSR is priv:%d UserMode:%d secure:%d S1S2NsTran:%d\n",
1193 isPriv
, flags
& UserMode
, isSecure
, tranType
& S1S2NsTran
);
1195 DPRINTF(TLB
, "translateFs addr %#x, mode %d, st2 %d, scr %#x sctlr %#x "
1196 "flags %#lx tranType 0x%x\n", vaddr_tainted
, mode
, isStage2
,
1197 scr
, sctlr
, flags
, tranType
);
1199 if ((req
->isInstFetch() && (!sctlr
.i
)) ||
1200 ((!req
->isInstFetch()) && (!sctlr
.c
))){
1201 if (!req
->isCacheMaintenance()) {
1202 req
->setFlags(Request::UNCACHEABLE
);
1204 req
->setFlags(Request::STRICT_ORDER
);
1207 if (sctlr
.a
|| !(flags
& AllowUnaligned
)) {
1208 if (vaddr
& mask(flags
& AlignmentMask
)) {
1209 stats
.alignFaults
++;
1210 return std::make_shared
<DataAbort
>(
1212 TlbEntry::DomainType::NoAccess
, is_write
,
1213 ArmFault::AlignmentFault
, isStage2
,
1220 if (HaveVirtHostExt(tc
) && hcr
.e2h
== 1 && hcr
.tge
==1)
1222 else if (hcr
.dc
== 1)
1225 Fault fault
= NoFault
;
1226 // If guest MMU is off or hcr.vm=0 go straight to stage2
1227 if ((isStage2
&& !vm
) || (!isStage2
&& !sctlr
.m
)) {
1228 fault
= translateMmuOff(tc
, req
, mode
, tranType
, vaddr
,
1231 DPRINTF(TLBVerbose
, "Translating %s=%#x context=%d\n",
1232 isStage2
? "IPA" : "VA", vaddr_tainted
, asid
);
1233 // Translation enabled
1234 fault
= translateMmuOn(tc
, req
, mode
, translation
, delay
, timing
,
1235 functional
, vaddr
, tranMethod
);
1238 // Check for Debug Exceptions
1239 SelfDebug
*sd
= ArmISA::ISA::getSelfDebug(tc
);
1241 if (sd
->enabled() && fault
== NoFault
) {
1242 fault
= sd
->testDebug(tc
, req
, mode
);
1249 TLB::translateAtomic(const RequestPtr
&req
, ThreadContext
*tc
, Mode mode
,
1250 TLB::ArmTranslationType tranType
)
1252 updateMiscReg(tc
, tranType
);
1254 if (directToStage2
) {
1256 return stage2Tlb
->translateAtomic(req
, tc
, mode
, tranType
);
1262 fault
= translateFs(req
, tc
, mode
, NULL
, delay
, false, tranType
);
1264 fault
= translateSe(req
, tc
, mode
, NULL
, delay
, false);
1270 TLB::translateFunctional(const RequestPtr
&req
, ThreadContext
*tc
, Mode mode
,
1271 TLB::ArmTranslationType tranType
)
1273 updateMiscReg(tc
, tranType
);
1275 if (directToStage2
) {
1277 return stage2Tlb
->translateFunctional(req
, tc
, mode
, tranType
);
1283 fault
= translateFs(req
, tc
, mode
, NULL
, delay
, false, tranType
, true);
1285 fault
= translateSe(req
, tc
, mode
, NULL
, delay
, false);
1291 TLB::translateTiming(const RequestPtr
&req
, ThreadContext
*tc
,
1292 Translation
*translation
, Mode mode
, TLB::ArmTranslationType tranType
)
1294 updateMiscReg(tc
, tranType
);
1296 if (directToStage2
) {
1298 stage2Tlb
->translateTiming(req
, tc
, translation
, mode
, tranType
);
1302 assert(translation
);
1304 translateComplete(req
, tc
, translation
, mode
, tranType
, isStage2
);
1308 TLB::translateComplete(const RequestPtr
&req
, ThreadContext
*tc
,
1309 Translation
*translation
, Mode mode
, TLB::ArmTranslationType tranType
,
1315 fault
= translateFs(req
, tc
, mode
, translation
, delay
, true, tranType
);
1317 fault
= translateSe(req
, tc
, mode
, translation
, delay
, true);
1318 DPRINTF(TLBVerbose
, "Translation returning delay=%d fault=%d\n", delay
, fault
!=
1320 // If we have a translation, and we're not in the middle of doing a stage
1321 // 2 translation tell the translation that we've either finished or its
1322 // going to take a while. By not doing this when we're in the middle of a
1323 // stage 2 translation we prevent marking the translation as delayed twice,
1324 // one when the translation starts and again when the stage 1 translation
1327 if (translation
&& (callFromS2
|| !stage2Req
|| req
->hasPaddr() ||
1328 fault
!= NoFault
)) {
1330 translation
->finish(fault
, req
, tc
, mode
);
1332 translation
->markDelayed();
1338 TLB::getTableWalkerPort()
1340 return &stage2Mmu
->getDMAPort();
1344 TLB::updateMiscReg(ThreadContext
*tc
, ArmTranslationType tranType
)
1346 // check if the regs have changed, or the translation mode is different.
1347 // NOTE: the tran type doesn't affect stage 2 TLB's as they only handle
1348 // one type of translation anyway
1349 if (miscRegValid
&& miscRegContext
== tc
->contextId() &&
1350 ((tranType
== curTranType
) || isStage2
)) {
1354 DPRINTF(TLBVerbose
, "TLB variables changed!\n");
1355 cpsr
= tc
->readMiscReg(MISCREG_CPSR
);
1357 // Dependencies: SCR/SCR_EL3, CPSR
1358 isSecure
= ArmISA::isSecure(tc
) &&
1359 !(tranType
& HypMode
) && !(tranType
& S1S2NsTran
);
1361 aarch64EL
= tranTypeEL(cpsr
, tranType
);
1362 aarch64
= isStage2
?
1364 ELIs64(tc
, aarch64EL
== EL0
? EL1
: aarch64EL
);
1366 hcr
= tc
->readMiscReg(MISCREG_HCR_EL2
);
1367 if (aarch64
) { // AArch64
1368 // determine EL we need to translate in
1369 switch (aarch64EL
) {
1371 if (HaveVirtHostExt(tc
) && hcr
.tge
== 1 && hcr
.e2h
== 1) {
1372 // VHE code for EL2&0 regime
1373 sctlr
= tc
->readMiscReg(MISCREG_SCTLR_EL2
);
1374 ttbcr
= tc
->readMiscReg(MISCREG_TCR_EL2
);
1375 uint64_t ttbr_asid
= ttbcr
.a1
?
1376 tc
->readMiscReg(MISCREG_TTBR1_EL2
) :
1377 tc
->readMiscReg(MISCREG_TTBR0_EL2
);
1378 asid
= bits(ttbr_asid
,
1379 (haveLargeAsid64
&& ttbcr
.as
) ? 63 : 55, 48);
1382 sctlr
= tc
->readMiscReg(MISCREG_SCTLR_EL1
);
1383 ttbcr
= tc
->readMiscReg(MISCREG_TCR_EL1
);
1384 uint64_t ttbr_asid
= ttbcr
.a1
?
1385 tc
->readMiscReg(MISCREG_TTBR1_EL1
) :
1386 tc
->readMiscReg(MISCREG_TTBR0_EL1
);
1387 asid
= bits(ttbr_asid
,
1388 (haveLargeAsid64
&& ttbcr
.as
) ? 63 : 55, 48);
1394 sctlr
= tc
->readMiscReg(MISCREG_SCTLR_EL1
);
1395 ttbcr
= tc
->readMiscReg(MISCREG_TCR_EL1
);
1396 uint64_t ttbr_asid
= ttbcr
.a1
?
1397 tc
->readMiscReg(MISCREG_TTBR1_EL1
) :
1398 tc
->readMiscReg(MISCREG_TTBR0_EL1
);
1399 asid
= bits(ttbr_asid
,
1400 (haveLargeAsid64
&& ttbcr
.as
) ? 63 : 55, 48);
1404 sctlr
= tc
->readMiscReg(MISCREG_SCTLR_EL2
);
1405 ttbcr
= tc
->readMiscReg(MISCREG_TCR_EL2
);
1407 // VHE code for EL2&0 regime
1408 uint64_t ttbr_asid
= ttbcr
.a1
?
1409 tc
->readMiscReg(MISCREG_TTBR1_EL2
) :
1410 tc
->readMiscReg(MISCREG_TTBR0_EL2
);
1411 asid
= bits(ttbr_asid
,
1412 (haveLargeAsid64
&& ttbcr
.as
) ? 63 : 55, 48);
1418 sctlr
= tc
->readMiscReg(MISCREG_SCTLR_EL3
);
1419 ttbcr
= tc
->readMiscReg(MISCREG_TCR_EL3
);
1424 scr
= tc
->readMiscReg(MISCREG_SCR_EL3
);
1425 isPriv
= aarch64EL
!= EL0
;
1426 if (haveVirtualization
) {
1427 vmid
= bits(tc
->readMiscReg(MISCREG_VTTBR_EL2
), 55, 48);
1428 isHyp
= aarch64EL
== EL2
;
1429 isHyp
|= tranType
& HypMode
;
1430 isHyp
&= (tranType
& S1S2NsTran
) == 0;
1431 isHyp
&= (tranType
& S1CTran
) == 0;
1433 if (HaveVirtHostExt(tc
) && hcr
.e2h
== 1 && hcr
.tge
==1) {
1437 if (hcr
.e2h
== 1 && (aarch64EL
== EL2
1438 || (hcr
.tge
==1 && aarch64EL
== EL0
))) {
1440 directToStage2
= false;
1442 stage2DescReq
= false;
1444 // Work out if we should skip the first stage of translation and go
1445 // directly to stage 2. This value is cached so we don't have to
1446 // compute it for every translation.
1447 bool sec
= !isSecure
|| (isSecure
&& IsSecureEL2Enabled(tc
));
1448 stage2Req
= isStage2
||
1449 (vm
&& !isHyp
&& sec
&&
1450 !(tranType
& S1CTran
) && (aarch64EL
< EL2
) &&
1451 !(tranType
& S1E1Tran
)); // <--- FIX THIS HACK
1452 stage2DescReq
= isStage2
|| (vm
&& !isHyp
&& sec
&&
1454 directToStage2
= !isStage2
&& stage2Req
&& !sctlr
.m
;
1459 directToStage2
= false;
1461 stage2DescReq
= false;
1464 sctlr
= tc
->readMiscReg(snsBankedIndex(MISCREG_SCTLR
, tc
,
1466 ttbcr
= tc
->readMiscReg(snsBankedIndex(MISCREG_TTBCR
, tc
,
1468 scr
= tc
->readMiscReg(MISCREG_SCR
);
1469 isPriv
= cpsr
.mode
!= MODE_USER
;
1470 if (longDescFormatInUse(tc
)) {
1471 uint64_t ttbr_asid
= tc
->readMiscReg(
1472 snsBankedIndex(ttbcr
.a1
? MISCREG_TTBR1
:
1475 asid
= bits(ttbr_asid
, 55, 48);
1476 } else { // Short-descriptor translation table format in use
1477 CONTEXTIDR context_id
= tc
->readMiscReg(snsBankedIndex(
1478 MISCREG_CONTEXTIDR
, tc
,!isSecure
));
1479 asid
= context_id
.asid
;
1481 prrr
= tc
->readMiscReg(snsBankedIndex(MISCREG_PRRR
, tc
,
1483 nmrr
= tc
->readMiscReg(snsBankedIndex(MISCREG_NMRR
, tc
,
1485 dacr
= tc
->readMiscReg(snsBankedIndex(MISCREG_DACR
, tc
,
1487 hcr
= tc
->readMiscReg(MISCREG_HCR
);
1489 if (haveVirtualization
) {
1490 vmid
= bits(tc
->readMiscReg(MISCREG_VTTBR
), 55, 48);
1491 isHyp
= cpsr
.mode
== MODE_HYP
;
1492 isHyp
|= tranType
& HypMode
;
1493 isHyp
&= (tranType
& S1S2NsTran
) == 0;
1494 isHyp
&= (tranType
& S1CTran
) == 0;
1496 sctlr
= tc
->readMiscReg(MISCREG_HSCTLR
);
1498 // Work out if we should skip the first stage of translation and go
1499 // directly to stage 2. This value is cached so we don't have to
1500 // compute it for every translation.
1501 bool sec
= !isSecure
|| (isSecure
&& IsSecureEL2Enabled(tc
));
1502 stage2Req
= hcr
.vm
&& !isStage2
&& !isHyp
&& sec
&&
1503 !(tranType
& S1CTran
);
1504 stage2DescReq
= hcr
.vm
&& !isStage2
&& !isHyp
&& sec
;
1505 directToStage2
= stage2Req
&& !sctlr
.m
;
1510 directToStage2
= false;
1511 stage2DescReq
= false;
1514 miscRegValid
= true;
1515 miscRegContext
= tc
->contextId();
1516 curTranType
= tranType
;
1520 TLB::tranTypeEL(CPSR cpsr
, ArmTranslationType type
)
1541 return currEL(cpsr
);
1544 panic("Unknown translation mode!\n");
1549 TLB::getTE(TlbEntry
**te
, const RequestPtr
&req
, ThreadContext
*tc
, Mode mode
,
1550 Translation
*translation
, bool timing
, bool functional
,
1551 bool is_secure
, TLB::ArmTranslationType tranType
)
1553 // In a 2-stage system, the IPA->PA translation can be started via this
1554 // call so make sure the miscRegs are correct.
1556 updateMiscReg(tc
, tranType
);
1558 bool is_fetch
= (mode
== Execute
);
1559 bool is_write
= (mode
== Write
);
1561 Addr vaddr_tainted
= req
->getVaddr();
1563 ExceptionLevel target_el
= aarch64
? aarch64EL
: EL1
;
1565 vaddr
= purifyTaggedAddr(vaddr_tainted
, tc
, target_el
, (TCR
)ttbcr
,
1568 vaddr
= vaddr_tainted
;
1570 *te
= lookup(vaddr
, asid
, vmid
, isHyp
, is_secure
, false, false, target_el
,
1573 if (req
->isPrefetch()) {
1574 // if the request is a prefetch don't attempt to fill the TLB or go
1575 // any further with the memory access (here we can safely use the
1576 // fault status for the short desc. format in all cases)
1577 stats
.prefetchFaults
++;
1578 return std::make_shared
<PrefetchAbort
>(
1579 vaddr_tainted
, ArmFault::PrefetchTLBMiss
, isStage2
);
1585 stats
.writeMisses
++;
1589 // start translation table walk, pass variables rather than
1590 // re-retreaving in table walker for speed
1591 DPRINTF(TLB
, "TLB Miss: Starting hardware table walker for %#x(%d:%d)\n",
1592 vaddr_tainted
, asid
, vmid
);
1594 fault
= tableWalker
->walk(req
, tc
, asid
, vmid
, isHyp
, mode
,
1595 translation
, timing
, functional
, is_secure
,
1596 tranType
, stage2DescReq
);
1597 // for timing mode, return and wait for table walk,
1598 if (timing
|| fault
!= NoFault
) {
1602 *te
= lookup(vaddr
, asid
, vmid
, isHyp
, is_secure
, false, false,
1619 TLB::getResultTe(TlbEntry
**te
, const RequestPtr
&req
,
1620 ThreadContext
*tc
, Mode mode
,
1621 Translation
*translation
, bool timing
, bool functional
,
1627 // We are already in the stage 2 TLB. Grab the table entry for stage
1628 // 2 only. We are here because stage 1 translation is disabled.
1629 TlbEntry
*s2Te
= NULL
;
1630 // Get the stage 2 table entry
1631 fault
= getTE(&s2Te
, req
, tc
, mode
, translation
, timing
, functional
,
1632 isSecure
, curTranType
);
1633 // Check permissions of stage 2
1634 if ((s2Te
!= NULL
) && (fault
== NoFault
)) {
1636 fault
= checkPermissions64(s2Te
, req
, mode
, tc
);
1638 fault
= checkPermissions(s2Te
, req
, mode
);
1644 TlbEntry
*s1Te
= NULL
;
1646 Addr vaddr_tainted
= req
->getVaddr();
1648 // Get the stage 1 table entry
1649 fault
= getTE(&s1Te
, req
, tc
, mode
, translation
, timing
, functional
,
1650 isSecure
, curTranType
);
1651 // only proceed if we have a valid table entry
1652 if ((s1Te
!= NULL
) && (fault
== NoFault
)) {
1653 // Check stage 1 permissions before checking stage 2
1655 fault
= checkPermissions64(s1Te
, req
, mode
, tc
);
1657 fault
= checkPermissions(s1Te
, req
, mode
);
1658 if (stage2Req
& (fault
== NoFault
)) {
1659 Stage2LookUp
*s2Lookup
= new Stage2LookUp(this, stage2Tlb
, *s1Te
,
1660 req
, translation
, mode
, timing
, functional
, isSecure
,
1662 fault
= s2Lookup
->getTe(tc
, mergeTe
);
1663 if (s2Lookup
->isComplete()) {
1665 // We've finished with the lookup so delete it
1668 // The lookup hasn't completed, so we can't delete it now. We
1669 // get round this by asking the object to self delete when the
1670 // translation is complete.
1671 s2Lookup
->setSelfDelete();
1674 // This case deals with an S1 hit (or bypass), followed by
1675 // an S2 hit-but-perms issue
1677 DPRINTF(TLBVerbose
, "s2TLB: reqVa %#x, reqPa %#x, fault %p\n",
1678 vaddr_tainted
, req
->hasPaddr() ? req
->getPaddr() : ~0, fault
);
1679 if (fault
!= NoFault
) {
1680 ArmFault
*armFault
= reinterpret_cast<ArmFault
*>(fault
.get());
1681 armFault
->annotate(ArmFault::S1PTW
, false);
1682 armFault
->annotate(ArmFault::OVA
, vaddr_tainted
);
1692 TLB::setTestInterface(SimObject
*_ti
)
1697 TlbTestInterface
*ti(dynamic_cast<TlbTestInterface
*>(_ti
));
1698 fatal_if(!ti
, "%s is not a valid ARM TLB tester\n", _ti
->name());
1704 TLB::testTranslation(const RequestPtr
&req
, Mode mode
,
1705 TlbEntry::DomainType domain
)
1707 if (!test
|| !req
->hasSize() || req
->getSize() == 0 ||
1708 req
->isCacheMaintenance()) {
1711 return test
->translationCheck(req
, isPriv
, mode
, domain
);
1716 TLB::testWalk(Addr pa
, Addr size
, Addr va
, bool is_secure
, Mode mode
,
1717 TlbEntry::DomainType domain
, LookupLevel lookup_level
)
1722 return test
->walkCheck(pa
, size
, va
, is_secure
, isPriv
, mode
,
1723 domain
, lookup_level
);