#include "arch/arm/pmu.hh"
#include "arch/arm/system.hh"
#include "arch/arm/tlb.hh"
+#include "arch/arm/tlbi_op.hh"
#include "cpu/base.hh"
#include "cpu/checker/cpu.hh"
#include "debug/Arm.hh"
}
}
-namespace {
-
-template<typename T>
-TLB *
-getITBPtr(T *tc)
-{
- auto tlb = dynamic_cast<TLB *>(tc->getITBPtr());
- assert(tlb);
- return tlb;
-}
-
-template<typename T>
-TLB *
-getDTBPtr(T *tc)
-{
- auto tlb = dynamic_cast<TLB *>(tc->getDTBPtr());
- assert(tlb);
- return tlb;
-}
-
-} // anonymous namespace
-
void
ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
{
MiscReg newVal = val;
bool secure_lookup;
- bool hyp;
- uint8_t target_el;
- uint16_t asid;
SCR scr;
if (misc_reg == MISCREG_CPSR) {
// ID registers are constants.
return;
- // TLBI all entries, EL0&1 inner sharable (ignored)
- case MISCREG_TLBIALLIS:
+ // TLB Invalidate All
case MISCREG_TLBIALL: // TLBI all entries, EL0&1,
- assert32(tc);
- target_el = 1; // el 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- tlbiALL(tc, secure_lookup, target_el);
- return;
- // TLBI all entries, EL0&1, instruction side
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIALL tlbiOp(EL1, haveSecurity && !scr.ns);
+ tlbiOp(tc);
+ return;
+ }
+ // TLB Invalidate All, Inner Shareable
+ case MISCREG_TLBIALLIS:
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIALL tlbiOp(EL1, haveSecurity && !scr.ns);
+ tlbiOp.broadcast(tc);
+ return;
+ }
+ // Instruction TLB Invalidate All
case MISCREG_ITLBIALL:
- assert32(tc);
- target_el = 1; // el 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- getITBPtr(tc)->flushAllSecurity(secure_lookup, target_el);
- return;
- // TLBI all entries, EL0&1, data side
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ ITLBIALL tlbiOp(EL1, haveSecurity && !scr.ns);
+ tlbiOp(tc);
+ return;
+ }
+ // Data TLB Invalidate All
case MISCREG_DTLBIALL:
- assert32(tc);
- target_el = 1; // el 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- getDTBPtr(tc)->flushAllSecurity(secure_lookup, target_el);
- return;
- // TLBI based on VA, EL0&1 inner sharable (ignored)
- case MISCREG_TLBIMVAL:
- case MISCREG_TLBIMVALIS:
- // mcr tlbimval(is) is invalidating all matching entries
- // regardless of the level of lookup, since in gem5 we cache
- // in the tlb the last level of lookup only.
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ DTLBIALL tlbiOp(EL1, haveSecurity && !scr.ns);
+ tlbiOp(tc);
+ return;
+ }
+ // TLB Invalidate by VA
+ // mcr tlbimval(is) is invalidating all matching entries
+ // regardless of the level of lookup, since in gem5 we cache
+ // in the tlb the last level of lookup only.
case MISCREG_TLBIMVA:
+ case MISCREG_TLBIMVAL:
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIMVA tlbiOp(EL1,
+ haveSecurity && !scr.ns,
+ mbits(newVal, 31, 12),
+ bits(newVal, 7,0));
+
+ tlbiOp(tc);
+ return;
+ }
+ // TLB Invalidate by VA, Inner Shareable
case MISCREG_TLBIMVAIS:
- assert32(tc);
- target_el = 1; // el 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- tlbiVA(tc, mbits(newVal, 31, 12), bits(newVal, 7,0),
- secure_lookup, target_el);
- return;
- // TLBI by ASID, EL0&1, inner sharable
- case MISCREG_TLBIASIDIS:
+ case MISCREG_TLBIMVALIS:
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIMVA tlbiOp(EL1,
+ haveSecurity && !scr.ns,
+ mbits(newVal, 31, 12),
+ bits(newVal, 7,0));
+
+ tlbiOp.broadcast(tc);
+ return;
+ }
+ // TLB Invalidate by ASID match
case MISCREG_TLBIASID:
- assert32(tc);
- target_el = 1; // el 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- asid = bits(newVal, 7,0);
- tlbiASID(tc, asid, secure_lookup, target_el);
- return;
- // TLBI by address, EL0&1, inner sharable (ignored)
- case MISCREG_TLBIMVAAL:
- case MISCREG_TLBIMVAALIS:
- // mcr tlbimvaal(is) is invalidating all matching entries
- // regardless of the level of lookup, since in gem5 we cache
- // in the tlb the last level of lookup only.
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIASID tlbiOp(EL1,
+ haveSecurity && !scr.ns,
+ bits(newVal, 7,0));
+
+ tlbiOp(tc);
+ return;
+ }
+ // TLB Invalidate by ASID match, Inner Shareable
+ case MISCREG_TLBIASIDIS:
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIASID tlbiOp(EL1,
+ haveSecurity && !scr.ns,
+ bits(newVal, 7,0));
+
+ tlbiOp.broadcast(tc);
+ return;
+ }
+ // mcr tlbimvaal(is) is invalidating all matching entries
+ // regardless of the level of lookup, since in gem5 we cache
+ // in the tlb the last level of lookup only.
+ // TLB Invalidate by VA, All ASID
case MISCREG_TLBIMVAA:
+ case MISCREG_TLBIMVAAL:
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIMVAA tlbiOp(EL1, haveSecurity && !scr.ns,
+ mbits(newVal, 31,12), false);
+
+ tlbiOp(tc);
+ return;
+ }
+ // TLB Invalidate by VA, All ASID, Inner Shareable
case MISCREG_TLBIMVAAIS:
- assert32(tc);
- target_el = 1; // el 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- hyp = 0;
- tlbiMVA(tc, mbits(newVal, 31,12), secure_lookup, hyp, target_el);
- return;
- // TLBI by address, EL2, hypervisor mode
- case MISCREG_TLBIMVALH:
- case MISCREG_TLBIMVALHIS:
- // mcr tlbimvalh(is) is invalidating all matching entries
- // regardless of the level of lookup, since in gem5 we cache
- // in the tlb the last level of lookup only.
+ case MISCREG_TLBIMVAALIS:
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIMVAA tlbiOp(EL1, haveSecurity && !scr.ns,
+ mbits(newVal, 31,12), false);
+
+ tlbiOp.broadcast(tc);
+ return;
+ }
+ // mcr tlbimvalh(is) is invalidating all matching entries
+ // regardless of the level of lookup, since in gem5 we cache
+ // in the tlb the last level of lookup only.
+ // TLB Invalidate by VA, Hyp mode
case MISCREG_TLBIMVAH:
+ case MISCREG_TLBIMVALH:
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIMVAA tlbiOp(EL1, haveSecurity && !scr.ns,
+ mbits(newVal, 31,12), true);
+
+ tlbiOp(tc);
+ return;
+ }
+ // TLB Invalidate by VA, Hyp mode, Inner Shareable
case MISCREG_TLBIMVAHIS:
- assert32(tc);
- target_el = 1; // aarch32, use hyp bit
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- hyp = 1;
- tlbiMVA(tc, mbits(newVal, 31,12), secure_lookup, hyp, target_el);
- return;
- case MISCREG_TLBIIPAS2L:
- case MISCREG_TLBIIPAS2LIS:
- // mcr tlbiipas2l(is) is invalidating all matching entries
- // regardless of the level of lookup, since in gem5 we cache
- // in the tlb the last level of lookup only.
+ case MISCREG_TLBIMVALHIS:
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIMVAA tlbiOp(EL1, haveSecurity && !scr.ns,
+ mbits(newVal, 31,12), true);
+
+ tlbiOp.broadcast(tc);
+ return;
+ }
+ // mcr tlbiipas2l(is) is invalidating all matching entries
+ // regardless of the level of lookup, since in gem5 we cache
+ // in the tlb the last level of lookup only.
+ // TLB Invalidate by Intermediate Physical Address, Stage 2
case MISCREG_TLBIIPAS2:
+ case MISCREG_TLBIIPAS2L:
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIIPA tlbiOp(EL1,
+ haveSecurity && !scr.ns,
+ static_cast<Addr>(bits(newVal, 35, 0)) << 12);
+
+ tlbiOp(tc);
+ return;
+ }
+ // TLB Invalidate by Intermediate Physical Address, Stage 2,
+ // Inner Shareable
case MISCREG_TLBIIPAS2IS:
- assert32(tc);
- target_el = 1; // EL 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- tlbiIPA(tc, newVal, secure_lookup, target_el);
- return;
- // TLBI by address and asid, EL0&1, instruction side only
+ case MISCREG_TLBIIPAS2LIS:
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIIPA tlbiOp(EL1,
+ haveSecurity && !scr.ns,
+ static_cast<Addr>(bits(newVal, 35, 0)) << 12);
+
+ tlbiOp.broadcast(tc);
+ return;
+ }
+ // Instruction TLB Invalidate by VA
case MISCREG_ITLBIMVA:
- assert32(tc);
- target_el = 1; // el 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- getITBPtr(tc)->flushMvaAsid(mbits(newVal, 31, 12),
- bits(newVal, 7,0), secure_lookup, target_el);
- return;
- // TLBI by address and asid, EL0&1, data side only
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ ITLBIMVA tlbiOp(EL1,
+ haveSecurity && !scr.ns,
+ mbits(newVal, 31, 12),
+ bits(newVal, 7,0));
+
+ tlbiOp(tc);
+ return;
+ }
+ // Data TLB Invalidate by VA
case MISCREG_DTLBIMVA:
- assert32(tc);
- target_el = 1; // el 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- getDTBPtr(tc)->flushMvaAsid(mbits(newVal, 31, 12),
- bits(newVal, 7,0), secure_lookup, target_el);
- return;
- // TLBI by ASID, EL0&1, instrution side only
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ DTLBIMVA tlbiOp(EL1,
+ haveSecurity && !scr.ns,
+ mbits(newVal, 31, 12),
+ bits(newVal, 7,0));
+
+ tlbiOp(tc);
+ return;
+ }
+ // Instruction TLB Invalidate by ASID match
case MISCREG_ITLBIASID:
- assert32(tc);
- target_el = 1; // el 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- getITBPtr(tc)->flushAsid(bits(newVal, 7,0), secure_lookup,
- target_el);
- return;
- // TLBI by ASID EL0&1 data size only
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ ITLBIASID tlbiOp(EL1,
+ haveSecurity && !scr.ns,
+ bits(newVal, 7,0));
+
+ tlbiOp(tc);
+ return;
+ }
+ // Data TLB Invalidate by ASID match
case MISCREG_DTLBIASID:
- assert32(tc);
- target_el = 1; // el 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- getDTBPtr(tc)->flushAsid(bits(newVal, 7,0), secure_lookup,
- target_el);
- return;
- // Invalidate entire Non-secure Hyp/Non-Hyp Unified TLB
+ {
+ assert32(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ DTLBIASID tlbiOp(EL1,
+ haveSecurity && !scr.ns,
+ bits(newVal, 7,0));
+
+ tlbiOp(tc);
+ return;
+ }
+ // TLB Invalidate All, Non-Secure Non-Hyp
case MISCREG_TLBIALLNSNH:
+ {
+ assert32(tc);
+
+ TLBIALLN tlbiOp(EL1, false);
+ tlbiOp(tc);
+ return;
+ }
+ // TLB Invalidate All, Non-Secure Non-Hyp, Inner Shareable
case MISCREG_TLBIALLNSNHIS:
- assert32(tc);
- target_el = 1; // el 0 and 1 are handled together
- hyp = 0;
- tlbiALLN(tc, hyp, target_el);
- return;
- // TLBI all entries, EL2, hyp,
+ {
+ assert32(tc);
+
+ TLBIALLN tlbiOp(EL1, false);
+ tlbiOp.broadcast(tc);
+ return;
+ }
+ // TLB Invalidate All, Hyp mode
case MISCREG_TLBIALLH:
+ {
+ assert32(tc);
+
+ TLBIALLN tlbiOp(EL1, true);
+ tlbiOp(tc);
+ return;
+ }
+ // TLB Invalidate All, Hyp mode, Inner Shareable
case MISCREG_TLBIALLHIS:
- assert32(tc);
- target_el = 1; // aarch32, use hyp bit
- hyp = 1;
- tlbiALLN(tc, hyp, target_el);
- return;
- // AArch64 TLBI: invalidate all entries EL3
- case MISCREG_TLBI_ALLE3IS:
+ {
+ assert32(tc);
+
+ TLBIALLN tlbiOp(EL1, true);
+ tlbiOp.broadcast(tc);
+ return;
+ }
+ // AArch64 TLB Invalidate All, EL3
case MISCREG_TLBI_ALLE3:
- assert64(tc);
- target_el = 3;
- secure_lookup = true;
- tlbiALL(tc, secure_lookup, target_el);
- return;
+ {
+ assert64(tc);
+
+ TLBIALL tlbiOp(EL3, true);
+ tlbiOp(tc);
+ return;
+ }
+ // AArch64 TLB Invalidate All, EL3, Inner Shareable
+ case MISCREG_TLBI_ALLE3IS:
+ {
+ assert64(tc);
+
+ TLBIALL tlbiOp(EL3, true);
+ tlbiOp.broadcast(tc);
+ return;
+ }
// @todo: uncomment this to enable Virtualization
// case MISCREG_TLBI_ALLE2IS:
// case MISCREG_TLBI_ALLE2:
- // TLBI all entries, EL0&1
- case MISCREG_TLBI_ALLE1IS:
+ // AArch64 TLB Invalidate All, EL1
case MISCREG_TLBI_ALLE1:
- // AArch64 TLBI: invalidate all entries, stage 1, current VMID
- case MISCREG_TLBI_VMALLE1IS:
case MISCREG_TLBI_VMALLE1:
- // AArch64 TLBI: invalidate all entries, stages 1 & 2, current VMID
- case MISCREG_TLBI_VMALLS12E1IS:
case MISCREG_TLBI_VMALLS12E1:
// @todo: handle VMID and stage 2 to enable Virtualization
- assert64(tc);
- target_el = 1; // el 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- tlbiALL(tc, secure_lookup, target_el);
- return;
- // AArch64 TLBI: invalidate by VA and ASID, stage 1, current VMID
- // VAEx(IS) and VALEx(IS) are the same because TLBs only store entries
+ {
+ assert64(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIALL tlbiOp(EL1, haveSecurity && !scr.ns);
+ tlbiOp(tc);
+ return;
+ }
+ // AArch64 TLB Invalidate All, EL1, Inner Shareable
+ case MISCREG_TLBI_ALLE1IS:
+ case MISCREG_TLBI_VMALLE1IS:
+ case MISCREG_TLBI_VMALLS12E1IS:
+ // @todo: handle VMID and stage 2 to enable Virtualization
+ {
+ assert64(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIALL tlbiOp(EL1, haveSecurity && !scr.ns);
+ tlbiOp.broadcast(tc);
+ return;
+ }
+ // VAEx(IS) and VALEx(IS) are the same because TLBs
+ // only store entries
// from the last level of translation table walks
// @todo: handle VMID to enable Virtualization
- // TLBI all entries, EL0&1
- case MISCREG_TLBI_VAE3IS_Xt:
+ // AArch64 TLB Invalidate by VA, EL3
case MISCREG_TLBI_VAE3_Xt:
- // TLBI by VA, EL3 regime stage 1, last level walk
- case MISCREG_TLBI_VALE3IS_Xt:
case MISCREG_TLBI_VALE3_Xt:
- assert64(tc);
- target_el = 3;
- asid = 0xbeef; // does not matter, tlbi is global
- secure_lookup = true;
- tlbiVA(tc, ((Addr) bits(newVal, 43, 0)) << 12,
- asid, secure_lookup, target_el);
- return;
- // TLBI by VA, EL2
- case MISCREG_TLBI_VAE2IS_Xt:
+ {
+ assert64(tc);
+
+ TLBIMVA tlbiOp(EL3, true,
+ static_cast<Addr>(bits(newVal, 43, 0)) << 12,
+ 0xbeef);
+ tlbiOp(tc);
+ return;
+ }
+ // AArch64 TLB Invalidate by VA, EL3, Inner Shareable
+ case MISCREG_TLBI_VAE3IS_Xt:
+ case MISCREG_TLBI_VALE3IS_Xt:
+ {
+ assert64(tc);
+
+ TLBIMVA tlbiOp(EL3, true,
+ static_cast<Addr>(bits(newVal, 43, 0)) << 12,
+ 0xbeef);
+
+ tlbiOp.broadcast(tc);
+ return;
+ }
+ // AArch64 TLB Invalidate by VA, EL2
case MISCREG_TLBI_VAE2_Xt:
- // TLBI by VA, EL2, stage1 last level walk
- case MISCREG_TLBI_VALE2IS_Xt:
case MISCREG_TLBI_VALE2_Xt:
- assert64(tc);
- target_el = 2;
- asid = 0xbeef; // does not matter, tlbi is global
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- tlbiVA(tc, ((Addr) bits(newVal, 43, 0)) << 12,
- asid, secure_lookup, target_el);
- return;
- // TLBI by VA EL1 & 0, stage1, ASID, current VMID
- case MISCREG_TLBI_VAE1IS_Xt:
+ {
+ assert64(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIMVA tlbiOp(EL2, haveSecurity && !scr.ns,
+ static_cast<Addr>(bits(newVal, 43, 0)) << 12,
+ 0xbeef);
+ tlbiOp(tc);
+ return;
+ }
+ // AArch64 TLB Invalidate by VA, EL2, Inner Shareable
+ case MISCREG_TLBI_VAE2IS_Xt:
+ case MISCREG_TLBI_VALE2IS_Xt:
+ {
+ assert64(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIMVA tlbiOp(EL2, haveSecurity && !scr.ns,
+ static_cast<Addr>(bits(newVal, 43, 0)) << 12,
+ 0xbeef);
+
+ tlbiOp.broadcast(tc);
+ return;
+ }
+ // AArch64 TLB Invalidate by VA, EL1
case MISCREG_TLBI_VAE1_Xt:
- case MISCREG_TLBI_VALE1IS_Xt:
case MISCREG_TLBI_VALE1_Xt:
- assert64(tc);
- asid = bits(newVal, 63, 48);
- target_el = 1; // el 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- tlbiVA(tc, ((Addr) bits(newVal, 43, 0)) << 12,
- asid, secure_lookup, target_el);
- return;
- // AArch64 TLBI: invalidate by ASID, stage 1, current VMID
+ {
+ assert64(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+ auto asid = haveLargeAsid64 ? bits(newVal, 63, 48) :
+ bits(newVal, 55, 48);
+
+ TLBIMVA tlbiOp(EL1, haveSecurity && !scr.ns,
+ static_cast<Addr>(bits(newVal, 43, 0)) << 12,
+ asid);
+
+ tlbiOp(tc);
+ return;
+ }
+ // AArch64 TLB Invalidate by VA, EL1, Inner Shareable
+ case MISCREG_TLBI_VAE1IS_Xt:
+ case MISCREG_TLBI_VALE1IS_Xt:
+ {
+ assert64(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+ auto asid = haveLargeAsid64 ? bits(newVal, 63, 48) :
+ bits(newVal, 55, 48);
+
+ TLBIMVA tlbiOp(EL1, haveSecurity && !scr.ns,
+ static_cast<Addr>(bits(newVal, 43, 0)) << 12,
+ asid);
+
+ tlbiOp.broadcast(tc);
+ return;
+ }
+ // AArch64 TLB Invalidate by ASID, EL1
// @todo: handle VMID to enable Virtualization
- case MISCREG_TLBI_ASIDE1IS_Xt:
case MISCREG_TLBI_ASIDE1_Xt:
- assert64(tc);
- target_el = 1; // el 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- asid = bits(newVal, 63, 48);
- tlbiASID(tc, asid, secure_lookup, target_el);
- return;
- // AArch64 TLBI: invalidate by VA, ASID, stage 1, current VMID
+ {
+ assert64(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+ auto asid = haveLargeAsid64 ? bits(newVal, 63, 48) :
+ bits(newVal, 55, 48);
+
+ TLBIASID tlbiOp(EL1, haveSecurity && !scr.ns, asid);
+ tlbiOp(tc);
+ return;
+ }
+ // AArch64 TLB Invalidate by ASID, EL1, Inner Shareable
+ case MISCREG_TLBI_ASIDE1IS_Xt:
+ {
+ assert64(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+ auto asid = haveLargeAsid64 ? bits(newVal, 63, 48) :
+ bits(newVal, 55, 48);
+
+ TLBIASID tlbiOp(EL1, haveSecurity && !scr.ns, asid);
+ tlbiOp.broadcast(tc);
+ return;
+ }
// VAAE1(IS) and VAALE1(IS) are the same because TLBs only store
// entries from the last level of translation table walks
- // @todo: handle VMID to enable Virtualization
- case MISCREG_TLBI_VAAE1IS_Xt:
+ // AArch64 TLB Invalidate by VA, All ASID, EL1
case MISCREG_TLBI_VAAE1_Xt:
- case MISCREG_TLBI_VAALE1IS_Xt:
case MISCREG_TLBI_VAALE1_Xt:
- assert64(tc);
- target_el = 1; // el 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- tlbiMVA(tc,
- ((Addr)bits(newVal, 43, 0)) << 12,
- secure_lookup, false, target_el);
- return;
- // AArch64 TLBI: invalidate by IPA, stage 2, current VMID
- case MISCREG_TLBI_IPAS2LE1IS_Xt:
+ {
+ assert64(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIMVAA tlbiOp(EL1, haveSecurity && !scr.ns,
+ static_cast<Addr>(bits(newVal, 43, 0)) << 12, false);
+
+ tlbiOp(tc);
+ return;
+ }
+ // AArch64 TLB Invalidate by VA, All ASID, EL1, Inner Shareable
+ case MISCREG_TLBI_VAAE1IS_Xt:
+ case MISCREG_TLBI_VAALE1IS_Xt:
+ {
+ assert64(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIMVAA tlbiOp(EL1, haveSecurity && !scr.ns,
+ static_cast<Addr>(bits(newVal, 43, 0)) << 12, false);
+
+ tlbiOp.broadcast(tc);
+ return;
+ }
+ // AArch64 TLB Invalidate by Intermediate Physical Address,
+ // Stage 2, EL1
+ case MISCREG_TLBI_IPAS2E1_Xt:
case MISCREG_TLBI_IPAS2LE1_Xt:
+ {
+ assert64(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIIPA tlbiOp(EL1, haveSecurity && !scr.ns,
+ static_cast<Addr>(bits(newVal, 35, 0)) << 12);
+
+ tlbiOp(tc);
+ return;
+ }
+ // AArch64 TLB Invalidate by Intermediate Physical Address,
+ // Stage 2, EL1, Inner Shareable
case MISCREG_TLBI_IPAS2E1IS_Xt:
- case MISCREG_TLBI_IPAS2E1_Xt:
- assert64(tc);
- target_el = 1; // EL 0 and 1 are handled together
- scr = readMiscReg(MISCREG_SCR, tc);
- secure_lookup = haveSecurity && !scr.ns;
- tlbiIPA(tc, newVal, secure_lookup, target_el);
- return;
+ case MISCREG_TLBI_IPAS2LE1IS_Xt:
+ {
+ assert64(tc);
+ scr = readMiscReg(MISCREG_SCR, tc);
+
+ TLBIIPA tlbiOp(EL1, haveSecurity && !scr.ns,
+ static_cast<Addr>(bits(newVal, 35, 0)) << 12);
+
+ tlbiOp.broadcast(tc);
+ return;
+ }
case MISCREG_ACTLR:
warn("Not doing anything for write of miscreg ACTLR\n");
break;
setMiscRegNoEffect(misc_reg, newVal);
}
-void
-ISA::tlbiVA(ThreadContext *tc, Addr va, uint16_t asid,
- bool secure_lookup, uint8_t target_el)
-{
- if (!haveLargeAsid64)
- asid &= mask(8);
- System *sys = tc->getSystemPtr();
- for (int x = 0; x < sys->numContexts(); x++) {
- ThreadContext *oc = sys->getThreadContext(x);
- getITBPtr(oc)->flushMvaAsid(va, asid,
- secure_lookup, target_el);
- getDTBPtr(oc)->flushMvaAsid(va, asid,
- secure_lookup, target_el);
-
- CheckerCPU *checker = oc->getCheckerCpuPtr();
- if (checker) {
- getITBPtr(checker)->flushMvaAsid(
- va, asid, secure_lookup, target_el);
- getDTBPtr(checker)->flushMvaAsid(
- va, asid, secure_lookup, target_el);
- }
- }
-}
-
-void
-ISA::tlbiALL(ThreadContext *tc, bool secure_lookup, uint8_t target_el)
-{
- System *sys = tc->getSystemPtr();
- for (int x = 0; x < sys->numContexts(); x++) {
- ThreadContext *oc = sys->getThreadContext(x);
- getITBPtr(oc)->flushAllSecurity(secure_lookup, target_el);
- getDTBPtr(oc)->flushAllSecurity(secure_lookup, target_el);
-
- // If CheckerCPU is connected, need to notify it of a flush
- CheckerCPU *checker = oc->getCheckerCpuPtr();
- if (checker) {
- getITBPtr(checker)->flushAllSecurity(secure_lookup,
- target_el);
- getDTBPtr(checker)->flushAllSecurity(secure_lookup,
- target_el);
- }
- }
-}
-
-void
-ISA::tlbiALLN(ThreadContext *tc, bool hyp, uint8_t target_el)
-{
- System *sys = tc->getSystemPtr();
- for (int x = 0; x < sys->numContexts(); x++) {
- ThreadContext *oc = sys->getThreadContext(x);
- getITBPtr(oc)->flushAllNs(hyp, target_el);
- getDTBPtr(oc)->flushAllNs(hyp, target_el);
-
- CheckerCPU *checker = oc->getCheckerCpuPtr();
- if (checker) {
- getITBPtr(checker)->flushAllNs(hyp, target_el);
- getDTBPtr(checker)->flushAllNs(hyp, target_el);
- }
- }
-}
-
-void
-ISA::tlbiMVA(ThreadContext *tc, Addr va, bool secure_lookup, bool hyp,
- uint8_t target_el)
-{
- System *sys = tc->getSystemPtr();
- for (int x = 0; x < sys->numContexts(); x++) {
- ThreadContext *oc = sys->getThreadContext(x);
- getITBPtr(oc)->flushMva(va, secure_lookup, hyp, target_el);
- getDTBPtr(oc)->flushMva(va, secure_lookup, hyp, target_el);
-
- CheckerCPU *checker = oc->getCheckerCpuPtr();
- if (checker) {
- getITBPtr(checker)->flushMva(va, secure_lookup, hyp, target_el);
- getDTBPtr(checker)->flushMva(va, secure_lookup, hyp, target_el);
- }
- }
-}
-
-void
-ISA::tlbiIPA(ThreadContext *tc, MiscReg newVal, bool secure_lookup,
- uint8_t target_el)
-{
- System *sys = tc->getSystemPtr();
- for (auto x = 0; x < sys->numContexts(); x++) {
- tc = sys->getThreadContext(x);
- Addr ipa = ((Addr) bits(newVal, 35, 0)) << 12;
- getITBPtr(tc)->flushIpaVmid(ipa,
- secure_lookup, false, target_el);
- getDTBPtr(tc)->flushIpaVmid(ipa,
- secure_lookup, false, target_el);
-
- CheckerCPU *checker = tc->getCheckerCpuPtr();
- if (checker) {
- getITBPtr(checker)->flushIpaVmid(ipa,
- secure_lookup, false, target_el);
- getDTBPtr(checker)->flushIpaVmid(ipa,
- secure_lookup, false, target_el);
- }
- }
-}
-
-void
-ISA::tlbiASID(ThreadContext *tc, uint16_t asid, bool secure_lookup,
- uint8_t target_el)
-{
- if (!haveLargeAsid64)
- asid &= mask(8);
-
- System *sys = tc->getSystemPtr();
- for (auto x = 0; x < sys->numContexts(); x++) {
- tc = sys->getThreadContext(x);
- getITBPtr(tc)->flushAsid(asid, secure_lookup, target_el);
- getDTBPtr(tc)->flushAsid(asid, secure_lookup, target_el);
- CheckerCPU *checker = tc->getCheckerCpuPtr();
- if (checker) {
- getITBPtr(checker)->flushAsid(asid, secure_lookup, target_el);
- getDTBPtr(checker)->flushAsid(asid, secure_lookup, target_el);
- }
- }
-}
-
BaseISADevice &
ISA::getGenericTimer(ThreadContext *tc)
{
--- /dev/null
+/*
+ * Copyright (c) 2018 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Giacomo Travaglini
+ */
+
+#include "arch/arm/tlbi_op.hh"
+
+#include "arch/arm/tlb.hh"
+#include "cpu/checker/cpu.hh"
+
+namespace ArmISA {
+
+void
+TLBIALL::operator()(ThreadContext* tc)
+{
+ getITBPtr(tc)->flushAllSecurity(secureLookup, targetEL);
+ getDTBPtr(tc)->flushAllSecurity(secureLookup, targetEL);
+
+ // If CheckerCPU is connected, need to notify it of a flush
+ CheckerCPU *checker = tc->getCheckerCpuPtr();
+ if (checker) {
+ getITBPtr(checker)->flushAllSecurity(secureLookup,
+ targetEL);
+ getDTBPtr(checker)->flushAllSecurity(secureLookup,
+ targetEL);
+ }
+}
+
+void
+ITLBIALL::operator()(ThreadContext* tc)
+{
+ getITBPtr(tc)->flushAllSecurity(secureLookup, targetEL);
+}
+
+void
+DTLBIALL::operator()(ThreadContext* tc)
+{
+ getDTBPtr(tc)->flushAllSecurity(secureLookup, targetEL);
+}
+
+void
+TLBIASID::operator()(ThreadContext* tc)
+{
+ getITBPtr(tc)->flushAsid(asid, secureLookup, targetEL);
+ getDTBPtr(tc)->flushAsid(asid, secureLookup, targetEL);
+ CheckerCPU *checker = tc->getCheckerCpuPtr();
+ if (checker) {
+ getITBPtr(checker)->flushAsid(asid, secureLookup, targetEL);
+ getDTBPtr(checker)->flushAsid(asid, secureLookup, targetEL);
+ }
+}
+
+void
+ITLBIASID::operator()(ThreadContext* tc)
+{
+ getITBPtr(tc)->flushAsid(asid, secureLookup, targetEL);
+}
+
+void
+DTLBIASID::operator()(ThreadContext* tc)
+{
+ getDTBPtr(tc)->flushAsid(asid, secureLookup, targetEL);
+}
+
+void
+TLBIALLN::operator()(ThreadContext* tc)
+{
+ getITBPtr(tc)->flushAllNs(hyp, targetEL);
+ getDTBPtr(tc)->flushAllNs(hyp, targetEL);
+
+ CheckerCPU *checker = tc->getCheckerCpuPtr();
+ if (checker) {
+ getITBPtr(checker)->flushAllNs(hyp, targetEL);
+ getDTBPtr(checker)->flushAllNs(hyp, targetEL);
+ }
+}
+
+void
+TLBIMVAA::operator()(ThreadContext* tc)
+{
+ getITBPtr(tc)->flushMva(addr, secureLookup, hyp, targetEL);
+ getDTBPtr(tc)->flushMva(addr, secureLookup, hyp, targetEL);
+
+ CheckerCPU *checker = tc->getCheckerCpuPtr();
+ if (checker) {
+ getITBPtr(checker)->flushMva(addr, secureLookup, hyp, targetEL);
+ getDTBPtr(checker)->flushMva(addr, secureLookup, hyp, targetEL);
+ }
+}
+
+void
+TLBIMVA::operator()(ThreadContext* tc)
+{
+ getITBPtr(tc)->flushMvaAsid(addr, asid,
+ secureLookup, targetEL);
+ getDTBPtr(tc)->flushMvaAsid(addr, asid,
+ secureLookup, targetEL);
+
+ CheckerCPU *checker = tc->getCheckerCpuPtr();
+ if (checker) {
+ getITBPtr(checker)->flushMvaAsid(
+ addr, asid, secureLookup, targetEL);
+ getDTBPtr(checker)->flushMvaAsid(
+ addr, asid, secureLookup, targetEL);
+ }
+}
+
+void
+ITLBIMVA::operator()(ThreadContext* tc)
+{
+ getITBPtr(tc)->flushMvaAsid(
+ addr, asid, secureLookup, targetEL);
+}
+
+void
+DTLBIMVA::operator()(ThreadContext* tc)
+{
+ getDTBPtr(tc)->flushMvaAsid(
+ addr, asid, secureLookup, targetEL);
+}
+
+void
+TLBIIPA::operator()(ThreadContext* tc)
+{
+ getITBPtr(tc)->flushIpaVmid(addr,
+ secureLookup, false, targetEL);
+ getDTBPtr(tc)->flushIpaVmid(addr,
+ secureLookup, false, targetEL);
+
+ CheckerCPU *checker = tc->getCheckerCpuPtr();
+ if (checker) {
+ getITBPtr(checker)->flushIpaVmid(addr,
+ secureLookup, false, targetEL);
+ getDTBPtr(checker)->flushIpaVmid(addr,
+ secureLookup, false, targetEL);
+ }
+}
+
+} // namespace ArmISA
--- /dev/null
+/*
+ * Copyright (c) 2018 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Giacomo Travaglini
+ */
+
+#ifndef __ARCH_ARM_TLBI_HH__
+#define __ARCH_ARM_TLBI_HH__
+
+#include "arch/arm/system.hh"
+#include "arch/arm/tlb.hh"
+#include "cpu/thread_context.hh"
+
+/**
+ * @file
+ * The file contains the definition of a set of TLB Invalidate
+ * Instructions. Those are the ISA interface for TLB flushing
+ * operations.
+ */
+namespace ArmISA {
+
+class TLBIOp
+{
+ public:
+ TLBIOp(ExceptionLevel _targetEL, bool _secure)
+ : secureLookup(_secure), targetEL(_targetEL)
+ {}
+
+ virtual ~TLBIOp() {}
+ virtual void operator()(ThreadContext* tc) {}
+
+ /**
+ * Broadcast the TLB Invalidate operation to all
+ * TLBs in the Arm system.
+ * @param tc Thread Context
+ */
+ void
+ broadcast(ThreadContext *tc)
+ {
+ System *sys = tc->getSystemPtr();
+ for (int x = 0; x < sys->numContexts(); x++) {
+ ThreadContext *oc = sys->getThreadContext(x);
+ (*this)(oc);
+ }
+ }
+
+ protected:
+ bool secureLookup;
+ ExceptionLevel targetEL;
+};
+
+/** TLB Invalidate All */
+class TLBIALL : public TLBIOp
+{
+ public:
+ TLBIALL(ExceptionLevel _targetEL, bool _secure)
+ : TLBIOp(_targetEL, _secure)
+ {}
+
+ void operator()(ThreadContext* tc) override;
+};
+
+/** Instruction TLB Invalidate All */
+class ITLBIALL : public TLBIOp
+{
+ public:
+ ITLBIALL(ExceptionLevel _targetEL, bool _secure)
+ : TLBIOp(_targetEL, _secure)
+ {}
+
+ void broadcast(ThreadContext *tc) = delete;
+
+ void operator()(ThreadContext* tc) override;
+};
+
+/** Data TLB Invalidate All */
+class DTLBIALL : public TLBIOp
+{
+ public:
+ DTLBIALL(ExceptionLevel _targetEL, bool _secure)
+ : TLBIOp(_targetEL, _secure)
+ {}
+
+ void broadcast(ThreadContext *tc) = delete;
+
+ void operator()(ThreadContext* tc) override;
+};
+
+/** TLB Invalidate by ASID match */
+class TLBIASID : public TLBIOp
+{
+ public:
+ TLBIASID(ExceptionLevel _targetEL, bool _secure, uint16_t _asid)
+ : TLBIOp(_targetEL, _secure), asid(_asid)
+ {}
+
+ void operator()(ThreadContext* tc) override;
+
+ protected:
+ uint16_t asid;
+};
+
+/** Instruction TLB Invalidate by ASID match */
+class ITLBIASID : public TLBIOp
+{
+ public:
+ ITLBIASID(ExceptionLevel _targetEL, bool _secure, uint16_t _asid)
+ : TLBIOp(_targetEL, _secure), asid(_asid)
+ {}
+
+ void broadcast(ThreadContext *tc) = delete;
+
+ void operator()(ThreadContext* tc) override;
+
+ protected:
+ uint16_t asid;
+};
+
+/** Data TLB Invalidate by ASID match */
+class DTLBIASID : public TLBIOp
+{
+ public:
+ DTLBIASID(ExceptionLevel _targetEL, bool _secure, uint16_t _asid)
+ : TLBIOp(_targetEL, _secure), asid(_asid)
+ {}
+
+ void broadcast(ThreadContext *tc) = delete;
+
+ void operator()(ThreadContext* tc) override;
+
+ protected:
+ uint16_t asid;
+};
+
+/** TLB Invalidate All, Non-Secure */
+class TLBIALLN : public TLBIOp
+{
+ public:
+ TLBIALLN(ExceptionLevel _targetEL, bool _hyp)
+ : TLBIOp(_targetEL, false), hyp(_hyp)
+ {}
+
+ void operator()(ThreadContext* tc) override;
+
+ protected:
+ bool hyp;
+};
+
+/** TLB Invalidate by VA, All ASID */
+class TLBIMVAA : public TLBIOp
+{
+ public:
+ TLBIMVAA(ExceptionLevel _targetEL, bool _secure,
+ Addr _addr, bool _hyp)
+ : TLBIOp(_targetEL, _secure), addr(_addr), hyp(_hyp)
+ {}
+
+ void operator()(ThreadContext* tc) override;
+
+ protected:
+ Addr addr;
+ bool hyp;
+};
+
+/** TLB Invalidate by VA */
+class TLBIMVA : public TLBIOp
+{
+ public:
+ TLBIMVA(ExceptionLevel _targetEL, bool _secure,
+ Addr _addr, uint16_t _asid)
+ : TLBIOp(_targetEL, _secure), addr(_addr), asid(_asid)
+ {}
+
+ void operator()(ThreadContext* tc) override;
+
+ protected:
+ Addr addr;
+ uint16_t asid;
+};
+
+/** Instruction TLB Invalidate by VA */
+class ITLBIMVA : public TLBIOp
+{
+ public:
+ ITLBIMVA(ExceptionLevel _targetEL, bool _secure,
+ Addr _addr, uint16_t _asid)
+ : TLBIOp(_targetEL, _secure), addr(_addr), asid(_asid)
+ {}
+
+ void broadcast(ThreadContext *tc) = delete;
+
+ void operator()(ThreadContext* tc) override;
+
+ protected:
+ Addr addr;
+ uint16_t asid;
+};
+
+/** Data TLB Invalidate by VA */
+class DTLBIMVA : public TLBIOp
+{
+ public:
+ DTLBIMVA(ExceptionLevel _targetEL, bool _secure,
+ Addr _addr, uint16_t _asid)
+ : TLBIOp(_targetEL, _secure), addr(_addr), asid(_asid)
+ {}
+
+ void broadcast(ThreadContext *tc) = delete;
+
+ void operator()(ThreadContext* tc) override;
+
+ protected:
+ Addr addr;
+ uint16_t asid;
+};
+
+/** TLB Invalidate by Intermediate Physical Address */
+class TLBIIPA : public TLBIOp
+{
+ public:
+ TLBIIPA(ExceptionLevel _targetEL, bool _secure, Addr _addr)
+ : TLBIOp(_targetEL, _secure), addr(_addr)
+ {}
+
+ void operator()(ThreadContext* tc) override;
+
+ protected:
+ Addr addr;
+};
+
+} // namespace ArmISA
+
+#endif //__ARCH_ARM_TLBI_HH__