From 4dd475c1c0db6915f811a246c9e6fce8a61a6a77 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Wed, 1 May 2019 15:21:03 +0100 Subject: [PATCH] arch-arm: Use ExceptionLevel type in TlbEntry Replacing uint8_t with ExceptionLevel type in the arm TlbEntry. The variable is representing the translation regime it is targeting. Change-Id: Ifcd6e86c5d73f752e8476a2b7fda9ea74a0c7a3b Signed-off-by: Giacomo Travaglini Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/19488 Reviewed-by: Ciro Santilli Tested-by: kokoro --- src/arch/arm/pagetable.hh | 26 ++++++++++++------- src/arch/arm/table_walker.cc | 2 +- src/arch/arm/tlb.cc | 50 +++++++++++++++--------------------- src/arch/arm/tlb.hh | 23 ++++++++--------- 4 files changed, 50 insertions(+), 51 deletions(-) diff --git a/src/arch/arm/pagetable.hh b/src/arch/arm/pagetable.hh index 856e0d545..240a1cad8 100644 --- a/src/arch/arm/pagetable.hh +++ b/src/arch/arm/pagetable.hh @@ -133,7 +133,7 @@ struct TlbEntry : public Serializable // True if the entry was brought in from a non-secure page table bool nstid; // Exception level on insert, AARCH64 EL0&1, AARCH32 -> el=1 - uint8_t el; + ExceptionLevel el; // Type of memory bool nonCacheable; // Can we wrap this in mtype? @@ -154,7 +154,7 @@ struct TlbEntry : public Serializable innerAttrs(0), outerAttrs(0), ap(read_only ? 0x3 : 0), hap(0x3), domain(DomainType::Client), mtype(MemoryType::StronglyOrdered), longDescFormat(false), isHyp(false), global(false), valid(true), - ns(true), nstid(true), el(0), nonCacheable(uncacheable), + ns(true), nstid(true), el(EL0), nonCacheable(uncacheable), shareable(false), outerShareable(false), xn(0), pxn(0) { // no restrictions by default, hap = 0x3 @@ -169,7 +169,7 @@ struct TlbEntry : public Serializable vmid(0), N(0), innerAttrs(0), outerAttrs(0), ap(0), hap(0x3), domain(DomainType::Client), mtype(MemoryType::StronglyOrdered), longDescFormat(false), isHyp(false), global(false), valid(false), - ns(true), nstid(true), el(0), nonCacheable(false), + ns(true), nstid(true), el(EL0), nonCacheable(false), shareable(false), outerShareable(false), xn(0), pxn(0) { // no restrictions by default, hap = 0x3 @@ -191,14 +191,14 @@ struct TlbEntry : public Serializable bool match(Addr va, uint8_t _vmid, bool hypLookUp, bool secure_lookup, - uint8_t target_el) const + ExceptionLevel target_el) const { return match(va, 0, _vmid, hypLookUp, secure_lookup, true, target_el); } bool match(Addr va, uint16_t asn, uint8_t _vmid, bool hypLookUp, - bool secure_lookup, bool ignore_asn, uint8_t target_el) const + bool secure_lookup, bool ignore_asn, ExceptionLevel target_el) const { bool match = false; Addr v = vpn << N; @@ -206,10 +206,8 @@ struct TlbEntry : public Serializable if (valid && va >= v && va <= v + size && (secure_lookup == !nstid) && (hypLookUp == isHyp)) { - if (target_el == 2 || target_el == 3) - match = (el == target_el); - else - match = (el == 0) || (el == 1); + match = checkELMatch(target_el); + if (match && !ignore_asn) { match = global || (asn == asid); } @@ -220,6 +218,16 @@ struct TlbEntry : public Serializable return match; } + bool + checkELMatch(ExceptionLevel target_el) const + { + if (target_el == EL2 || target_el == EL3) { + return (el == target_el); + } else { + return (el == EL0) || (el == EL1); + } + } + Addr pAddr(Addr va) const { diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc index 461194d82..3feffa928 100644 --- a/src/arch/arm/table_walker.cc +++ b/src/arch/arm/table_walker.cc @@ -2064,7 +2064,7 @@ TableWalker::insertTableEntry(DescriptorBase &descriptor, bool longDescriptor) if (currState->aarch64) te.el = currState->el; else - te.el = 1; + te.el = EL1; statPageSizes[pageSizeNtoStatBin(te.N)]++; statRequestOrigin[COMPLETED][currState->isFetch]++; diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index 2b50d4b28..872f351c6 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -150,7 +150,7 @@ TLB::finalizePhysical(const RequestPtr &req, TlbEntry* TLB::lookup(Addr va, uint16_t asn, uint8_t vmid, bool hyp, bool secure, - bool functional, bool ignore_asn, uint8_t target_el) + bool functional, bool ignore_asn, ExceptionLevel target_el) { TlbEntry *retval = NULL; @@ -236,7 +236,8 @@ TLB::printTlb() const } void -TLB::flushAllSecurity(bool secure_lookup, uint8_t target_el, bool ignore_el) +TLB::flushAllSecurity(bool secure_lookup, ExceptionLevel target_el, + bool ignore_el) { DPRINTF(TLB, "Flushing all TLB entries (%s lookup)\n", (secure_lookup ? "secure" : "non-secure")); @@ -244,9 +245,11 @@ TLB::flushAllSecurity(bool secure_lookup, uint8_t target_el, bool ignore_el) TlbEntry *te; while (x < size) { te = &table[x]; + const bool el_match = ignore_el ? + true : te->checkELMatch(target_el); + if (te->valid && secure_lookup == !te->nstid && - (te->vmid == vmid || secure_lookup) && - checkELMatch(target_el, te->el, ignore_el)) { + (te->vmid == vmid || secure_lookup) && el_match) { DPRINTF(TLB, " - %s\n", te->print()); te->valid = false; @@ -260,12 +263,12 @@ TLB::flushAllSecurity(bool secure_lookup, uint8_t target_el, bool ignore_el) // If there's a second stage TLB (and we're not it) then flush it as well // if we're currently in hyp mode if (!isStage2 && isHyp) { - stage2Tlb->flushAllSecurity(secure_lookup, true); + stage2Tlb->flushAllSecurity(secure_lookup, EL1, true); } } void -TLB::flushAllNs(uint8_t target_el, bool ignore_el) +TLB::flushAllNs(ExceptionLevel target_el, bool ignore_el) { bool hyp = target_el == EL2; @@ -275,8 +278,10 @@ TLB::flushAllNs(uint8_t target_el, bool ignore_el) TlbEntry *te; while (x < size) { te = &table[x]; - if (te->valid && te->nstid && te->isHyp == hyp && - checkELMatch(target_el, te->el, ignore_el)) { + const bool el_match = ignore_el ? + true : te->checkELMatch(target_el); + + if (te->valid && te->nstid && te->isHyp == hyp && el_match) { DPRINTF(TLB, " - %s\n", te->print()); flushedEntries++; @@ -289,12 +294,13 @@ TLB::flushAllNs(uint8_t target_el, bool ignore_el) // If there's a second stage TLB (and we're not it) then flush it as well if (!isStage2 && !hyp) { - stage2Tlb->flushAllNs(false, true); + stage2Tlb->flushAllNs(EL1, true); } } void -TLB::flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup, uint8_t target_el) +TLB::flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup, + ExceptionLevel target_el) { DPRINTF(TLB, "Flushing TLB entries with mva: %#x, asid: %#x " "(%s lookup)\n", mva, asn, (secure_lookup ? @@ -304,7 +310,7 @@ TLB::flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup, uint8_t target_el) } void -TLB::flushAsid(uint64_t asn, bool secure_lookup, uint8_t target_el) +TLB::flushAsid(uint64_t asn, bool secure_lookup, ExceptionLevel target_el) { DPRINTF(TLB, "Flushing TLB entries with asid: %#x (%s lookup)\n", asn, (secure_lookup ? "secure" : "non-secure")); @@ -316,7 +322,7 @@ TLB::flushAsid(uint64_t asn, bool secure_lookup, uint8_t target_el) te = &table[x]; if (te->valid && te->asid == asn && secure_lookup == !te->nstid && (te->vmid == vmid || secure_lookup) && - checkELMatch(target_el, te->el, false)) { + te->checkELMatch(target_el)) { te->valid = false; DPRINTF(TLB, " - %s\n", te->print()); @@ -328,7 +334,7 @@ TLB::flushAsid(uint64_t asn, bool secure_lookup, uint8_t target_el) } void -TLB::flushMva(Addr mva, bool secure_lookup, uint8_t target_el) +TLB::flushMva(Addr mva, bool secure_lookup, ExceptionLevel target_el) { DPRINTF(TLB, "Flushing TLB entries with mva: %#x (%s lookup)\n", mva, (secure_lookup ? "secure" : "non-secure")); @@ -338,7 +344,7 @@ TLB::flushMva(Addr mva, bool secure_lookup, uint8_t target_el) void TLB::_flushMva(Addr mva, uint64_t asn, bool secure_lookup, - bool ignore_asn, uint8_t target_el) + bool ignore_asn, ExceptionLevel target_el) { TlbEntry *te; // D5.7.2: Sign-extend address to 64 bits @@ -360,26 +366,12 @@ TLB::_flushMva(Addr mva, uint64_t asn, bool secure_lookup, } void -TLB::flushIpaVmid(Addr ipa, bool secure_lookup, uint8_t target_el) +TLB::flushIpaVmid(Addr ipa, bool secure_lookup, ExceptionLevel target_el) { assert(!isStage2); stage2Tlb->_flushMva(ipa, 0xbeef, secure_lookup, true, target_el); } -bool -TLB::checkELMatch(uint8_t target_el, uint8_t tentry_el, bool ignore_el) -{ - bool elMatch = true; - if (!ignore_el) { - if (target_el == 2 || target_el == 3) { - elMatch = (tentry_el == target_el); - } else { - elMatch = (tentry_el == 0) || (tentry_el == 1); - } - } - return elMatch; -} - void TLB::drainResume() { diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh index fb8d7944d..a84e945f4 100644 --- a/src/arch/arm/tlb.hh +++ b/src/arch/arm/tlb.hh @@ -212,7 +212,7 @@ class TLB : public BaseTLB */ TlbEntry *lookup(Addr vpn, uint16_t asn, uint8_t vmid, bool hyp, bool secure, bool functional, - bool ignore_asn, uint8_t target_el); + bool ignore_asn, ExceptionLevel target_el); virtual ~TLB(); @@ -249,13 +249,13 @@ class TLB : public BaseTLB /** Reset the entire TLB * @param secure_lookup if the operation affects the secure world */ - void flushAllSecurity(bool secure_lookup, uint8_t target_el, + void flushAllSecurity(bool secure_lookup, ExceptionLevel target_el, bool ignore_el = false); /** Remove all entries in the non secure world, depending on whether they * were allocated in hyp mode or not */ - void flushAllNs(uint8_t target_el, bool ignore_el = false); + void flushAllNs(ExceptionLevel target_el, bool ignore_el = false); /** Reset the entire TLB. Used for CPU switching to prevent stale @@ -263,8 +263,8 @@ class TLB : public BaseTLB */ void flushAll() override { - flushAllSecurity(false, 0, true); - flushAllSecurity(true, 0, true); + flushAllSecurity(false, EL0, true); + flushAllSecurity(true, EL0, true); } /** Remove any entries that match both a va and asn @@ -273,19 +273,20 @@ class TLB : public BaseTLB * @param secure_lookup if the operation affects the secure world */ void flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup, - uint8_t target_el); + ExceptionLevel target_el); /** Remove any entries that match the asn * @param asn contextid/asn to flush on match * @param secure_lookup if the operation affects the secure world */ - void flushAsid(uint64_t asn, bool secure_lookup, uint8_t target_el); + void flushAsid(uint64_t asn, bool secure_lookup, + ExceptionLevel target_el); /** Remove all entries that match the va regardless of asn * @param mva address to flush from cache * @param secure_lookup if the operation affects the secure world */ - void flushMva(Addr mva, bool secure_lookup, uint8_t target_el); + void flushMva(Addr mva, bool secure_lookup, ExceptionLevel target_el); /** * Invalidate all entries in the stage 2 TLB that match the given ipa @@ -293,7 +294,7 @@ class TLB : public BaseTLB * @param ipa the address to invalidate * @param secure_lookup if the operation affects the secure world */ - void flushIpaVmid(Addr ipa, bool secure_lookup, uint8_t target_el); + void flushIpaVmid(Addr ipa, bool secure_lookup, ExceptionLevel target_el); Fault trickBoxCheck(const RequestPtr &req, Mode mode, TlbEntry::DomainType domain); @@ -450,9 +451,7 @@ private: * @param ignore_asn if the flush should ignore the asn */ void _flushMva(Addr mva, uint64_t asn, bool secure_lookup, - bool ignore_asn, uint8_t target_el); - - bool checkELMatch(uint8_t target_el, uint8_t tentry_el, bool ignore_el); + bool ignore_asn, ExceptionLevel target_el); public: /* Testing */ Fault testTranslation(const RequestPtr &req, Mode mode, -- 2.30.2