*/
#include "arch/arm/mmu.hh"
+#include "arch/arm/tlbi_op.hh"
using namespace ArmISA;
}
}
-void
-MMU::flushAllSecurity(bool secure_lookup, ExceptionLevel target_el,
- TLBType type, bool ignore_el, bool in_host)
-{
- if (type & TLBType::I_TLBS) {
- getITBPtr()->flushAllSecurity(
- secure_lookup, target_el, ignore_el, in_host);
- }
- if (type & TLBType::D_TLBS) {
- getDTBPtr()->flushAllSecurity(
- secure_lookup, target_el, ignore_el, in_host);
- }
-}
-
-void
-MMU::flushAllNs(ExceptionLevel target_el, bool ignore_el,
- TLBType type)
-{
- if (type & TLBType::I_TLBS) {
- getITBPtr()->flushAllNs(target_el, ignore_el);
- }
- if (type & TLBType::D_TLBS) {
- getDTBPtr()->flushAllNs(target_el, ignore_el);
- }
-}
-
-void
-MMU::flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup,
- ExceptionLevel target_el, TLBType type,
- bool in_host)
-{
- if (type & TLBType::I_TLBS) {
- getITBPtr()->flushMvaAsid(
- mva, asn, secure_lookup, target_el, in_host);
- }
- if (type & TLBType::D_TLBS) {
- getDTBPtr()->flushMvaAsid(
- mva, asn, secure_lookup, target_el, in_host);
- }
-}
-
-void
-MMU::flushAsid(uint64_t asn, bool secure_lookup,
- ExceptionLevel target_el, TLBType type,
- bool in_host)
-{
- if (type & TLBType::I_TLBS) {
- getITBPtr()->flushAsid(asn, secure_lookup, target_el, in_host);
- }
- if (type & TLBType::D_TLBS) {
- getDTBPtr()->flushAsid(asn, secure_lookup, target_el, in_host);
- }
-}
-
-void
-MMU::flushMva(Addr mva, bool secure_lookup, ExceptionLevel target_el,
- TLBType type, bool in_host)
-{
- if (type & TLBType::I_TLBS) {
- getITBPtr()->flushMva(mva, secure_lookup, target_el, in_host);
- }
- if (type & TLBType::D_TLBS) {
- getDTBPtr()->flushMva(mva, secure_lookup, target_el, in_host);
- }
-}
-
-void
-MMU::flushIpaVmid(Addr ipa, bool secure_lookup, ExceptionLevel target_el,
- TLBType type)
-{
- if (type & TLBType::I_TLBS) {
- getITBPtr()->flushIpaVmid(ipa, secure_lookup, target_el);
- }
- if (type & TLBType::D_TLBS) {
- getDTBPtr()->flushIpaVmid(ipa, secure_lookup, target_el);
- }
-}
-
ArmISA::MMU *
ArmMMUParams::create() const
{
void invalidateMiscReg(TLBType type = ALL_TLBS);
- /** Reset the entire TLB
- * @param secure_lookup if the operation affects the secure world
- */
- void flushAllSecurity(bool secure_lookup, ExceptionLevel target_el,
- TLBType type = ALL_TLBS,
- bool ignore_el = false, bool in_host = false);
-
- /** Remove all entries in the non secure world, depending on whether they
- * were allocated in hyp mode or not
- */
- void flushAllNs(ExceptionLevel target_el, bool ignore_el = false,
- TLBType type = ALL_TLBS);
-
- /** Remove any entries that match both a va and asn
- * @param mva virtual address to flush
- * @param asn contextid/asn to flush on match
- * @param secure_lookup if the operation affects the secure world
- */
- void flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup,
- ExceptionLevel target_el, TLBType type = ALL_TLBS,
- bool in_host = false);
-
- /** 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,
- ExceptionLevel target_el, TLBType type = ALL_TLBS,
- bool in_host = false);
-
- /** 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, ExceptionLevel target_el,
- TLBType type = ALL_TLBS, bool in_host = false);
-
- /**
- * Invalidate all entries in the stage 2 TLB that match the given ipa
- * and the current VMID
- * @param ipa the address to invalidate
- * @param secure_lookup if the operation affects the secure world
- */
- void flushIpaVmid(Addr ipa, bool secure_lookup, ExceptionLevel target_el,
- TLBType type = ALL_TLBS);
+ template <typename OP>
+ void
+ flush(const OP &tlbi_op)
+ {
+ getITBPtr()->flush(tlbi_op);
+ getDTBPtr()->flush(tlbi_op);
+ }
+
+ template <typename OP>
+ void
+ iflush(const OP &tlbi_op)
+ {
+ getITBPtr()->flush(tlbi_op);
+ }
+
+ template <typename OP>
+ void
+ dflush(const OP &tlbi_op)
+ {
+ getDTBPtr()->flush(tlbi_op);
+ }
uint64_t
getAttr() const
{
return getDTBPtr()->getAttr();
}
-
};
template<typename T>
#include "arch/arm/stage2_mmu.hh"
#include "arch/arm/system.hh"
#include "arch/arm/table_walker.hh"
+#include "arch/arm/tlbi_op.hh"
#include "arch/arm/utility.hh"
#include "base/inifile.hh"
#include "base/str.hh"
}
void
-TLB::flushAllSecurity(bool secure_lookup, ExceptionLevel target_el,
- bool ignore_el, bool in_host)
+TLB::flush(const TLBIALL& tlbi_op)
{
DPRINTF(TLB, "Flushing all TLB entries (%s lookup)\n",
- (secure_lookup ? "secure" : "non-secure"));
+ (tlbi_op.secureLookup ? "secure" : "non-secure"));
int x = 0;
TlbEntry *te;
while (x < size) {
te = &table[x];
- const bool el_match = ignore_el ?
- true : te->checkELMatch(target_el, in_host);
- if (te->valid && secure_lookup == !te->nstid &&
- (te->vmid == vmid || secure_lookup) && el_match) {
+ const bool el_match = te->checkELMatch(
+ tlbi_op.targetEL, tlbi_op.inHost);
+ if (te->valid && tlbi_op.secureLookup == !te->nstid &&
+ (te->vmid == vmid || tlbi_op.secureLookup) && el_match) {
DPRINTF(TLB, " - %s\n", te->print());
te->valid = false;
// 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, EL1, true, false);
+ stage2Tlb->flush(tlbi_op.makeStage2());
}
}
void
-TLB::flushAllNs(ExceptionLevel target_el, bool ignore_el)
+TLB::flush(const TLBIALLN &tlbi_op)
{
- bool hyp = target_el == EL2;
+ bool hyp = tlbi_op.targetEL == EL2;
DPRINTF(TLB, "Flushing all NS TLB entries (%s lookup)\n",
(hyp ? "hyp" : "non-hyp"));
TlbEntry *te;
while (x < size) {
te = &table[x];
- const bool el_match = ignore_el ?
- true : te->checkELMatch(target_el, false);
+ const bool el_match = te->checkELMatch(tlbi_op.targetEL, false);
if (te->valid && te->nstid && te->isHyp == hyp && el_match) {
// If there's a second stage TLB (and we're not it) then flush it as well
if (!isStage2 && !hyp) {
- stage2Tlb->flushAllNs(EL1, true);
+ stage2Tlb->flush(tlbi_op.makeStage2());
}
}
void
-TLB::flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup,
- ExceptionLevel target_el, bool in_host)
+TLB::flush(const TLBIMVA &tlbi_op)
{
DPRINTF(TLB, "Flushing TLB entries with mva: %#x, asid: %#x "
- "(%s lookup)\n", mva, asn, (secure_lookup ?
- "secure" : "non-secure"));
- _flushMva(mva, asn, secure_lookup, false, target_el, in_host);
+ "(%s lookup)\n", tlbi_op.addr, tlbi_op.asid,
+ (tlbi_op.secureLookup ? "secure" : "non-secure"));
+ _flushMva(tlbi_op.addr, tlbi_op.asid, tlbi_op.secureLookup, false,
+ tlbi_op.targetEL, tlbi_op.inHost);
stats.flushTlbMvaAsid++;
}
void
-TLB::flushAsid(uint64_t asn, bool secure_lookup, ExceptionLevel target_el,
- bool in_host)
+TLB::flush(const TLBIASID &tlbi_op)
{
- DPRINTF(TLB, "Flushing TLB entries with asid: %#x (%s lookup)\n", asn,
- (secure_lookup ? "secure" : "non-secure"));
+ DPRINTF(TLB, "Flushing TLB entries with asid: %#x (%s lookup)\n",
+ tlbi_op.asid, (tlbi_op.secureLookup ? "secure" : "non-secure"));
int x = 0 ;
TlbEntry *te;
while (x < size) {
te = &table[x];
- if (te->valid && te->asid == asn && secure_lookup == !te->nstid &&
- (te->vmid == vmid || secure_lookup) &&
- te->checkELMatch(target_el, in_host)) {
+ if (te->valid && te->asid == tlbi_op.asid &&
+ tlbi_op.secureLookup == !te->nstid &&
+ (te->vmid == vmid || tlbi_op.secureLookup) &&
+ te->checkELMatch(tlbi_op.targetEL, tlbi_op.inHost)) {
te->valid = false;
DPRINTF(TLB, " - %s\n", te->print());
}
void
-TLB::flushMva(Addr mva, bool secure_lookup, ExceptionLevel target_el,
- bool in_host) {
+TLB::flush(const TLBIMVAA &tlbi_op) {
- DPRINTF(TLB, "Flushing TLB entries with mva: %#x (%s lookup)\n", mva,
- (secure_lookup ? "secure" : "non-secure"));
- _flushMva(mva, 0xbeef, secure_lookup, true, target_el, in_host);
+ DPRINTF(TLB, "Flushing TLB entries with mva: %#x (%s lookup)\n",
+ tlbi_op.addr,
+ (tlbi_op.secureLookup ? "secure" : "non-secure"));
+ _flushMva(tlbi_op.addr, 0xbeef, tlbi_op.secureLookup, true,
+ tlbi_op.targetEL, tlbi_op.inHost);
stats.flushTlbMva++;
}
}
void
-TLB::flushIpaVmid(Addr ipa, bool secure_lookup, ExceptionLevel target_el)
+TLB::flush(const TLBIIPA &tlbi_op)
{
assert(!isStage2);
- stage2Tlb->_flushMva(ipa, 0xbeef, secure_lookup, true, target_el, false);
+ stage2Tlb->_flushMva(tlbi_op.addr, 0xbeef, tlbi_op.secureLookup,
+ true, tlbi_op.targetEL, false);
}
void
class Stage2MMU;
class TLB;
+class TLBIALL;
+class TLBIALLN;
+class TLBIMVA;
+class TLBIASID;
+class TLBIMVAA;
+class TLBIIPA;
+
class TlbTestInterface
{
public:
/** Reset the entire TLB
- * @param secure_lookup if the operation affects the secure world
*/
- void flushAllSecurity(bool secure_lookup, ExceptionLevel target_el,
- bool ignore_el = false, bool in_host = false);
+ void flush(const TLBIALL& tlbi_op);
/** Remove all entries in the non secure world, depending on whether they
* were allocated in hyp mode or not
*/
- void flushAllNs(ExceptionLevel target_el, bool ignore_el = false);
-
+ void flush(const TLBIALLN &tlbi_op);
/** Remove any entries that match both a va and asn
- * @param mva virtual address to flush
- * @param asn contextid/asn to flush on match
- * @param secure_lookup if the operation affects the secure world
*/
- void flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup,
- ExceptionLevel target_el, bool in_host = false);
+ void flush(const TLBIMVA &tlbi_op);
/** 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,
- ExceptionLevel target_el, bool in_host = false);
+ void flush(const TLBIASID &tlbi_op);
/** 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, ExceptionLevel target_el,
- bool in_host = false);
+ void flush(const TLBIMVAA &tlbi_op);
/**
* Invalidate all entries in the stage 2 TLB that match the given ipa
* and the current VMID
- * @param ipa the address to invalidate
- * @param secure_lookup if the operation affects the secure world
*/
- void flushIpaVmid(Addr ipa, bool secure_lookup, ExceptionLevel target_el);
+ void flush(const TLBIIPA &tlbi_op);
Fault trickBoxCheck(const RequestPtr &req, Mode mode,
TlbEntry::DomainType domain);
/*
- * Copyright (c) 2018-2019 ARM Limited
+ * Copyright (c) 2018-2020 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
TLBIALL::operator()(ThreadContext* tc)
{
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
- bool in_host = (hcr.tge == 1 && hcr.e2h == 1);
- getMMUPtr(tc)->flushAllSecurity(secureLookup, targetEL,
- MMU::ALL_TLBS, in_host);
+ inHost = (hcr.tge == 1 && hcr.e2h == 1);
+ getMMUPtr(tc)->flush(*this);
// If CheckerCPU is connected, need to notify it of a flush
CheckerCPU *checker = tc->getCheckerCpuPtr();
if (checker) {
- getMMUPtr(checker)->flushAllSecurity(
- secureLookup, targetEL, MMU::ALL_TLBS, in_host);
+ getMMUPtr(checker)->flush(*this);
}
}
void
ITLBIALL::operator()(ThreadContext* tc)
{
- getMMUPtr(tc)->flushAllSecurity(secureLookup, targetEL, MMU::I_TLBS);
+ getMMUPtr(tc)->iflush(*this);
}
void
DTLBIALL::operator()(ThreadContext* tc)
{
- getMMUPtr(tc)->flushAllSecurity(secureLookup, targetEL, MMU::D_TLBS);
+ getMMUPtr(tc)->dflush(*this);
}
void
TLBIASID::operator()(ThreadContext* tc)
{
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
- bool in_host = (hcr.tge == 1 && hcr.e2h == 1);
- getMMUPtr(tc)->flushAsid(asid, secureLookup, targetEL,
- MMU::ALL_TLBS, in_host);
+ inHost = (hcr.tge == 1 && hcr.e2h == 1);
+ getMMUPtr(tc)->flush(*this);
CheckerCPU *checker = tc->getCheckerCpuPtr();
if (checker) {
- getMMUPtr(checker)->flushAsid(asid, secureLookup, targetEL,
- MMU::ALL_TLBS, in_host);
+ getMMUPtr(checker)->flush(*this);
}
}
void
ITLBIASID::operator()(ThreadContext* tc)
{
- getMMUPtr(tc)->flushAsid(asid, secureLookup, targetEL, MMU::I_TLBS);
+ getMMUPtr(tc)->iflush(*this);
}
void
DTLBIASID::operator()(ThreadContext* tc)
{
- getMMUPtr(tc)->flushAsid(asid, secureLookup, targetEL, MMU::D_TLBS);
+ getMMUPtr(tc)->dflush(*this);
}
void
TLBIALLN::operator()(ThreadContext* tc)
{
- getMMUPtr(tc)->flushAllNs(targetEL);
+ getMMUPtr(tc)->flush(*this);
CheckerCPU *checker = tc->getCheckerCpuPtr();
if (checker) {
- getMMUPtr(checker)->flushAllNs(targetEL);
+ getMMUPtr(checker)->flush(*this);
}
}
TLBIMVAA::operator()(ThreadContext* tc)
{
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
- bool in_host = (hcr.tge == 1 && hcr.e2h == 1);
- getMMUPtr(tc)->flushMva(addr, secureLookup, targetEL,
- MMU::ALL_TLBS, in_host);
+ inHost = (hcr.tge == 1 && hcr.e2h == 1);
+ getMMUPtr(tc)->flush(*this);
CheckerCPU *checker = tc->getCheckerCpuPtr();
if (checker) {
- getMMUPtr(checker)->flushMva(addr, secureLookup, targetEL,
- MMU::ALL_TLBS, in_host);
+ getMMUPtr(checker)->flush(*this);
}
}
TLBIMVA::operator()(ThreadContext* tc)
{
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
- bool in_host = (hcr.tge == 1 && hcr.e2h == 1);
- getMMUPtr(tc)->flushMvaAsid(addr, asid,
- secureLookup, targetEL, MMU::ALL_TLBS, in_host);
+ inHost = (hcr.tge == 1 && hcr.e2h == 1);
+ getMMUPtr(tc)->flush(*this);
CheckerCPU *checker = tc->getCheckerCpuPtr();
if (checker) {
- getMMUPtr(checker)->flushMvaAsid(
- addr, asid, secureLookup, targetEL, MMU::ALL_TLBS, in_host);
+ getMMUPtr(checker)->flush(*this);
}
}
void
ITLBIMVA::operator()(ThreadContext* tc)
{
- getMMUPtr(tc)->flushMvaAsid(
- addr, asid, secureLookup, targetEL, MMU::I_TLBS);
+ getMMUPtr(tc)->iflush(*this);
}
void
DTLBIMVA::operator()(ThreadContext* tc)
{
- getMMUPtr(tc)->flushMvaAsid(
- addr, asid, secureLookup, targetEL, MMU::D_TLBS);
+ getMMUPtr(tc)->dflush(*this);
}
void
TLBIIPA::operator()(ThreadContext* tc)
{
- getMMUPtr(tc)->flushIpaVmid(addr,
- secureLookup, targetEL);
+ getMMUPtr(tc)->flush(*this);
CheckerCPU *checker = tc->getCheckerCpuPtr();
if (checker) {
- getMMUPtr(checker)->flushIpaVmid(addr,
- secureLookup, targetEL);
+ getMMUPtr(checker)->flush(*this);
}
}
(*this)(oc);
}
- protected:
bool secureLookup;
ExceptionLevel targetEL;
};
{
public:
TLBIALL(ExceptionLevel _targetEL, bool _secure)
- : TLBIOp(_targetEL, _secure)
+ : TLBIOp(_targetEL, _secure), inHost(false)
{}
void operator()(ThreadContext* tc) override;
+
+ TLBIALL
+ makeStage2() const
+ {
+ return TLBIALL(EL1, secureLookup);
+ }
+
+ bool inHost;
};
/** Instruction TLB Invalidate All */
{
public:
TLBIASID(ExceptionLevel _targetEL, bool _secure, uint16_t _asid)
- : TLBIOp(_targetEL, _secure), asid(_asid)
+ : TLBIOp(_targetEL, _secure), asid(_asid), inHost(false)
{}
void operator()(ThreadContext* tc) override;
- protected:
uint16_t asid;
+ bool inHost;
};
/** Instruction TLB Invalidate by ASID match */
{}
void operator()(ThreadContext* tc) override;
+
+ TLBIALLN
+ makeStage2() const
+ {
+ return TLBIALLN(EL1);
+ }
};
/** TLB Invalidate by VA, All ASID */
public:
TLBIMVAA(ExceptionLevel _targetEL, bool _secure,
Addr _addr)
- : TLBIOp(_targetEL, _secure), addr(_addr)
+ : TLBIOp(_targetEL, _secure), addr(_addr), inHost(false)
{}
void operator()(ThreadContext* tc) override;
- protected:
Addr addr;
+ bool inHost;
};
/** TLB Invalidate by VA */
public:
TLBIMVA(ExceptionLevel _targetEL, bool _secure,
Addr _addr, uint16_t _asid)
- : TLBIOp(_targetEL, _secure), addr(_addr), asid(_asid)
+ : TLBIOp(_targetEL, _secure), addr(_addr), asid(_asid),
+ inHost(false)
{}
void operator()(ThreadContext* tc) override;
- protected:
Addr addr;
uint16_t asid;
+ bool inHost;
};
/** Instruction TLB Invalidate by VA */
void operator()(ThreadContext* tc) override;
- protected:
Addr addr;
};