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 <giacomo.travaglini@arm.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/19488 Reviewed-by: Ciro Santilli <ciro.santilli@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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]++;
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user