arch-arm: Remove stage2 TLBI flushes from stage1 flushes

This is not needed anymore as stage2 flush is now handled by
the MMU. With this patch we are progressively removing any link
between stage1 and stage2 TLBs

Change-Id: I3e9e339a78ac972bc536214152f6c68d6a50cb5c
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/45781
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Giacomo Travaglini
2020-10-06 13:51:44 +01:00
parent 31b37a7f73
commit af1e8667e1
4 changed files with 82 additions and 38 deletions

View File

@@ -105,8 +105,29 @@ class MMU : public BaseMMU
void
flush(const OP &tlbi_op)
{
getITBPtr()->flush(tlbi_op);
getDTBPtr()->flush(tlbi_op);
if (tlbi_op.stage1Flush()) {
flushStage1(tlbi_op);
}
if (tlbi_op.stage2Flush()) {
flushStage2(tlbi_op.makeStage2());
}
}
template <typename OP>
void
flushStage1(const OP &tlbi_op)
{
iflush(tlbi_op);
dflush(tlbi_op);
}
template <typename OP>
void
flushStage2(const OP &tlbi_op)
{
itbStage2->flush(tlbi_op);
dtbStage2->flush(tlbi_op);
}
template <typename OP>

View File

@@ -283,11 +283,6 @@ TLB::flushAll()
}
stats.flushTlb++;
// If there's a second stage TLB (and we're not it) then flush it as well
if (!isStage2) {
stage2Tlb->flushAll();
}
}
void
@@ -312,12 +307,6 @@ TLB::flush(const TLBIALL& tlbi_op)
}
stats.flushTlb++;
// 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->flush(tlbi_op.makeStage2());
}
}
void
@@ -341,13 +330,6 @@ TLB::flush(const TLBIALLEL &tlbi_op)
}
stats.flushTlb++;
// If there's a second stage TLB (and we're not it)
// and if we're targeting EL1
// then flush it as well
if (!isStage2 && tlbi_op.targetEL == EL1) {
stage2Tlb->flush(tlbi_op.makeStage2());
}
}
void
@@ -372,12 +354,6 @@ TLB::flush(const TLBIVMALL &tlbi_op)
}
stats.flushTlb++;
// 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 && tlbi_op.stage2) {
stage2Tlb->flush(tlbi_op.makeStage2());
}
}
void
@@ -403,11 +379,6 @@ TLB::flush(const TLBIALLN &tlbi_op)
}
stats.flushTlb++;
// If there's a second stage TLB (and we're not it) then flush it as well
if (!isStage2 && !hyp) {
stage2Tlb->flush(tlbi_op.makeStage2());
}
}
void

View File

@@ -48,6 +48,7 @@ TLBIALL::operator()(ThreadContext* tc)
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
inHost = (hcr.tge == 1 && hcr.e2h == 1);
el2Enabled = EL2Enabled(tc);
currentEL = currEL(tc);
getMMUPtr(tc)->flush(*this);
@@ -108,10 +109,10 @@ TLBIASID::operator()(ThreadContext* tc)
inHost = (hcr.tge == 1 && hcr.e2h == 1);
el2Enabled = EL2Enabled(tc);
getMMUPtr(tc)->flush(*this);
getMMUPtr(tc)->flushStage1(*this);
CheckerCPU *checker = tc->getCheckerCpuPtr();
if (checker) {
getMMUPtr(checker)->flush(*this);
getMMUPtr(checker)->flushStage1(*this);
}
}
@@ -145,11 +146,11 @@ TLBIMVAA::operator()(ThreadContext* tc)
{
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
inHost = (hcr.tge == 1 && hcr.e2h == 1);
getMMUPtr(tc)->flush(*this);
getMMUPtr(tc)->flushStage1(*this);
CheckerCPU *checker = tc->getCheckerCpuPtr();
if (checker) {
getMMUPtr(checker)->flush(*this);
getMMUPtr(checker)->flushStage1(*this);
}
}
@@ -158,11 +159,11 @@ TLBIMVA::operator()(ThreadContext* tc)
{
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
inHost = (hcr.tge == 1 && hcr.e2h == 1);
getMMUPtr(tc)->flush(*this);
getMMUPtr(tc)->flushStage1(*this);
CheckerCPU *checker = tc->getCheckerCpuPtr();
if (checker) {
getMMUPtr(checker)->flush(*this);
getMMUPtr(checker)->flushStage1(*this);
}
}

View File

@@ -72,6 +72,28 @@ class TLBIOp
(*this)(oc);
}
/**
* Return true if the TLBI op needs to flush stage1
* entries, Defaulting to true in the TLBIOp abstract
* class
*/
virtual bool
stage1Flush() const
{
return true;
}
/**
* Return true if the TLBI op needs to flush stage2
* entries, Defaulting to false in the TLBIOp abstract
* class
*/
virtual bool
stage2Flush() const
{
return false;
}
bool secureLookup;
ExceptionLevel targetEL;
};
@@ -81,11 +103,20 @@ class TLBIALL : public TLBIOp
{
public:
TLBIALL(ExceptionLevel _targetEL, bool _secure)
: TLBIOp(_targetEL, _secure), inHost(false), el2Enabled(false)
: TLBIOp(_targetEL, _secure), inHost(false), el2Enabled(false),
currentEL(EL0)
{}
void operator()(ThreadContext* tc) override;
bool
stage2Flush() const override
{
// TLBIALL (AArch32) flushing stage2 entries if we're currently
// in hyp mode
return currentEL == EL2;
}
TLBIALL
makeStage2() const
{
@@ -94,6 +125,7 @@ class TLBIALL : public TLBIOp
bool inHost;
bool el2Enabled;
ExceptionLevel currentEL;
};
/** Instruction TLB Invalidate All */
@@ -132,6 +164,13 @@ class TLBIALLEL : public TLBIOp
void operator()(ThreadContext* tc) override;
bool
stage2Flush() const override
{
// If we're targeting EL1 then flush stage2 as well
return targetEL == EL1;
}
TLBIALLEL
makeStage2() const
{
@@ -152,6 +191,12 @@ class TLBIVMALL : public TLBIOp
void operator()(ThreadContext* tc) override;
bool
stage2Flush() const override
{
return stage2;
}
TLBIVMALL
makeStage2() const
{
@@ -215,6 +260,12 @@ class TLBIALLN : public TLBIOp
void operator()(ThreadContext* tc) override;
bool
stage2Flush() const override
{
return targetEL != EL2;
}
TLBIALLN
makeStage2() const
{