arch-arm: Implement TLBI instructions with a separate class
This is an initial step towards making TLBI shareable issue memory operations (generating DVM messages) JIRA: https://gem5.atlassian.net/browse/GEM5-1097 Change-Id: I90d4ec6f57f98860d082b393080290cd245af64f Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/56595 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
*/
|
||||
|
||||
#include "arch/arm/insts/misc.hh"
|
||||
#include "arch/arm/tlbi_op.hh"
|
||||
|
||||
#include "cpu/reg_class.hh"
|
||||
|
||||
@@ -397,4 +398,287 @@ McrMrcImplDefined::generateDisassembly(
|
||||
return csprintf("%-10s (implementation defined)", mnemonic);
|
||||
}
|
||||
|
||||
void
|
||||
TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
ThreadContext* tc = xc->tcBase();
|
||||
auto isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
|
||||
auto release = isa->getRelease();
|
||||
|
||||
switch (dest_idx) {
|
||||
case MISCREG_TLBIALL: // TLBI all entries, EL0&1,
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIALL tlbiOp(EL1, secure);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate All, Inner Shareable
|
||||
case MISCREG_TLBIALLIS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIALL tlbiOp(EL1, secure);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// Instruction TLB Invalidate All
|
||||
case MISCREG_ITLBIALL:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
ITLBIALL tlbiOp(EL1, secure);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// Data TLB Invalidate All
|
||||
case MISCREG_DTLBIALL:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
DTLBIALL tlbiOp(EL1, secure);
|
||||
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:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVA tlbiOp(EL1,
|
||||
secure,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7,0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, Inner Shareable
|
||||
case MISCREG_TLBIMVAIS:
|
||||
case MISCREG_TLBIMVALIS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVA tlbiOp(EL1,
|
||||
secure,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7,0));
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by ASID match
|
||||
case MISCREG_TLBIASID:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIASID tlbiOp(EL1,
|
||||
secure,
|
||||
bits(value, 7,0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by ASID match, Inner Shareable
|
||||
case MISCREG_TLBIASIDIS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIASID tlbiOp(EL1,
|
||||
secure,
|
||||
bits(value, 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:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL1, secure,
|
||||
mbits(value, 31,12));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, All ASID, Inner Shareable
|
||||
case MISCREG_TLBIMVAAIS:
|
||||
case MISCREG_TLBIMVAALIS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL1, secure,
|
||||
mbits(value, 31,12));
|
||||
|
||||
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:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
mbits(value, 31,12));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, Hyp mode, Inner Shareable
|
||||
case MISCREG_TLBIMVAHIS:
|
||||
case MISCREG_TLBIMVALHIS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
mbits(value, 31,12));
|
||||
|
||||
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:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIIPA tlbiOp(EL1,
|
||||
secure,
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by Intermediate Physical Address, Stage 2,
|
||||
// Inner Shareable
|
||||
case MISCREG_TLBIIPAS2IS:
|
||||
case MISCREG_TLBIIPAS2LIS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIIPA tlbiOp(EL1,
|
||||
secure,
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// Instruction TLB Invalidate by VA
|
||||
case MISCREG_ITLBIMVA:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
ITLBIMVA tlbiOp(EL1,
|
||||
secure,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7,0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// Data TLB Invalidate by VA
|
||||
case MISCREG_DTLBIMVA:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
DTLBIMVA tlbiOp(EL1,
|
||||
secure,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7,0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// Instruction TLB Invalidate by ASID match
|
||||
case MISCREG_ITLBIASID:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
ITLBIASID tlbiOp(EL1,
|
||||
secure,
|
||||
bits(value, 7,0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// Data TLB Invalidate by ASID match
|
||||
case MISCREG_DTLBIASID:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
DTLBIASID tlbiOp(EL1,
|
||||
secure,
|
||||
bits(value, 7,0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate All, Non-Secure Non-Hyp
|
||||
case MISCREG_TLBIALLNSNH:
|
||||
{
|
||||
TLBIALLN tlbiOp(EL1);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate All, Non-Secure Non-Hyp, Inner Shareable
|
||||
case MISCREG_TLBIALLNSNHIS:
|
||||
{
|
||||
TLBIALLN tlbiOp(EL1);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate All, Hyp mode
|
||||
case MISCREG_TLBIALLH:
|
||||
{
|
||||
TLBIALLN tlbiOp(EL2);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate All, Hyp mode, Inner Shareable
|
||||
case MISCREG_TLBIALLHIS:
|
||||
{
|
||||
TLBIALLN tlbiOp(EL2);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
panic("Unrecognized TLBIOp\n");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gem5
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2012-2013, 2017-2018 ARM Limited
|
||||
* Copyright (c) 2010, 2012-2013, 2017-2018, 2021 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -439,6 +439,19 @@ class McrMrcImplDefined : public McrMrcMiscInst
|
||||
|
||||
};
|
||||
|
||||
class TlbiOp : public MiscRegRegImmOp
|
||||
{
|
||||
protected:
|
||||
TlbiOp(const char *mnem, ArmISA::ExtMachInst _machInst,
|
||||
OpClass __opClass, ArmISA::MiscRegIndex _dest,
|
||||
ArmISA::IntRegIndex _op1, uint64_t _imm) :
|
||||
MiscRegRegImmOp(mnem, _machInst, __opClass, _dest, _op1, _imm)
|
||||
{}
|
||||
|
||||
void performTlbi(ExecContext *xc,
|
||||
ArmISA::MiscRegIndex dest_idx, RegVal value) const;
|
||||
};
|
||||
|
||||
} // namespace gem5
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2013,2017-2020 ARM Limited
|
||||
* Copyright (c) 2011-2013,2017-2021 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -38,6 +38,8 @@
|
||||
#include "arch/arm/insts/misc64.hh"
|
||||
#include "arch/arm/isa.hh"
|
||||
|
||||
#include "arch/arm/tlbi_op.hh"
|
||||
|
||||
namespace gem5
|
||||
{
|
||||
|
||||
@@ -888,4 +890,358 @@ RegNone::generateDisassembly(
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void
|
||||
TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
ThreadContext* tc = xc->tcBase();
|
||||
auto isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
|
||||
auto release = isa->getRelease();
|
||||
|
||||
bool asid_16bits = ArmSystem::haveLargeAsid64(tc);
|
||||
|
||||
switch (dest_idx) {
|
||||
// AArch64 TLB Invalidate All, EL3
|
||||
case MISCREG_TLBI_ALLE3:
|
||||
{
|
||||
TLBIALLEL tlbiOp(EL3, true);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate All, EL3, Inner Shareable
|
||||
case MISCREG_TLBI_ALLE3IS:
|
||||
{
|
||||
TLBIALLEL tlbiOp(EL3, true);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate All, EL2
|
||||
case MISCREG_TLBI_ALLE2:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIALLEL tlbiOp(EL2, secure);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate All, EL2, Inner Shareable
|
||||
case MISCREG_TLBI_ALLE2IS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIALLEL tlbiOp(EL2, secure);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate All, EL1
|
||||
case MISCREG_TLBI_ALLE1:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIALLEL tlbiOp(EL1, secure);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate All, EL1, Inner Shareable
|
||||
case MISCREG_TLBI_ALLE1IS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIALLEL tlbiOp(EL1, secure);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_VMALLS12E1:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIVMALL tlbiOp(EL1, secure, true);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_VMALLE1:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIVMALL tlbiOp(target_el, secure, false);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_VMALLS12E1IS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIVMALL tlbiOp(EL1, secure, true);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_VMALLE1IS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIVMALL tlbiOp(target_el, secure, false);
|
||||
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
|
||||
// AArch64 TLB Invalidate by VA, EL3
|
||||
case MISCREG_TLBI_VAE3_Xt:
|
||||
case MISCREG_TLBI_VALE3_Xt:
|
||||
{
|
||||
|
||||
TLBIMVAA tlbiOp(EL3, true,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, EL3, Inner Shareable
|
||||
case MISCREG_TLBI_VAE3IS_Xt:
|
||||
case MISCREG_TLBI_VALE3IS_Xt:
|
||||
{
|
||||
TLBIMVAA tlbiOp(EL3, true,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, EL2
|
||||
case MISCREG_TLBI_VAE2_Xt:
|
||||
case MISCREG_TLBI_VALE2_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
|
||||
if (hcr.e2h) {
|
||||
// The asid will only be used when e2h == 1
|
||||
auto asid = asid_16bits ? bits(value, 63, 48) :
|
||||
bits(value, 55, 48);
|
||||
|
||||
TLBIMVA tlbiOp(EL2, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
asid);
|
||||
tlbiOp(tc);
|
||||
} else {
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12);
|
||||
tlbiOp(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, EL2, Inner Shareable
|
||||
case MISCREG_TLBI_VAE2IS_Xt:
|
||||
case MISCREG_TLBI_VALE2IS_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
|
||||
if (hcr.e2h) {
|
||||
// The asid will only be used when e2h == 1
|
||||
auto asid = asid_16bits ? bits(value, 63, 48) :
|
||||
bits(value, 55, 48);
|
||||
|
||||
TLBIMVA tlbiOp(EL2, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
asid);
|
||||
tlbiOp.broadcast(tc);
|
||||
} else {
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12);
|
||||
tlbiOp.broadcast(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, EL1
|
||||
case MISCREG_TLBI_VAE1_Xt:
|
||||
case MISCREG_TLBI_VALE1_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
auto asid = asid_16bits ? bits(value, 63, 48) :
|
||||
bits(value, 55, 48);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVA tlbiOp(target_el, secure,
|
||||
static_cast<Addr>(bits(value, 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:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
auto asid = asid_16bits ? bits(value, 63, 48) :
|
||||
bits(value, 55, 48);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVA tlbiOp(target_el, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
asid);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by ASID, EL1
|
||||
case MISCREG_TLBI_ASIDE1_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
auto asid = asid_16bits ? bits(value, 63, 48) :
|
||||
bits(value, 55, 48);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIASID tlbiOp(target_el, secure, asid);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by ASID, EL1, Inner Shareable
|
||||
case MISCREG_TLBI_ASIDE1IS_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
auto asid = asid_16bits ? bits(value, 63, 48) :
|
||||
bits(value, 55, 48);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIASID tlbiOp(target_el, secure, 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
|
||||
// AArch64 TLB Invalidate by VA, All ASID, EL1
|
||||
case MISCREG_TLBI_VAAE1_Xt:
|
||||
case MISCREG_TLBI_VAALE1_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(target_el, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, All ASID, EL1, Inner Shareable
|
||||
case MISCREG_TLBI_VAAE1IS_Xt:
|
||||
case MISCREG_TLBI_VAALE1IS_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(target_el, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by Intermediate Physical Address,
|
||||
// Stage 2, EL1
|
||||
case MISCREG_TLBI_IPAS2E1_Xt:
|
||||
case MISCREG_TLBI_IPAS2LE1_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIIPA tlbiOp(EL1, secure,
|
||||
static_cast<Addr>(bits(value, 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_IPAS2LE1IS_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIIPA tlbiOp(EL1, secure,
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
panic("Invalid TLBI\n");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gem5
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2013,2017-2019 ARM Limited
|
||||
* Copyright (c) 2011-2013,2017-2019, 2021 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -252,6 +252,19 @@ class RegNone : public ArmISA::ArmStaticInst
|
||||
Addr pc, const loader::SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
class TlbiOp64 : public MiscRegRegImmOp64
|
||||
{
|
||||
protected:
|
||||
TlbiOp64(const char *mnem, ArmISA::ExtMachInst _machInst,
|
||||
OpClass __opClass, ArmISA::MiscRegIndex _dest,
|
||||
ArmISA::IntRegIndex _op1, uint32_t _imm) :
|
||||
MiscRegRegImmOp64(mnem, _machInst, __opClass, _dest, _op1, _imm)
|
||||
{}
|
||||
|
||||
void performTlbi(ExecContext *xc,
|
||||
ArmISA::MiscRegIndex idx, RegVal value) const;
|
||||
};
|
||||
|
||||
} // namespace gem5
|
||||
|
||||
#endif
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
#include "arch/arm/regs/misc.hh"
|
||||
#include "arch/arm/self_debug.hh"
|
||||
#include "arch/arm/system.hh"
|
||||
#include "arch/arm/tlbi_op.hh"
|
||||
#include "arch/arm/utility.hh"
|
||||
#include "arch/generic/decoder.hh"
|
||||
#include "base/cprintf.hh"
|
||||
@@ -1560,666 +1559,6 @@ ISA::setMiscReg(int misc_reg, RegVal val)
|
||||
return;
|
||||
|
||||
// TLB Invalidate All
|
||||
case MISCREG_TLBIALL: // TLBI all entries, EL0&1,
|
||||
{
|
||||
assert32();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIALL tlbiOp(EL1, secure);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate All, Inner Shareable
|
||||
case MISCREG_TLBIALLIS:
|
||||
{
|
||||
assert32();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIALL tlbiOp(EL1, secure);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// Instruction TLB Invalidate All
|
||||
case MISCREG_ITLBIALL:
|
||||
{
|
||||
assert32();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
ITLBIALL tlbiOp(EL1, secure);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// Data TLB Invalidate All
|
||||
case MISCREG_DTLBIALL:
|
||||
{
|
||||
assert32();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
DTLBIALL tlbiOp(EL1, secure);
|
||||
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();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVA tlbiOp(EL1,
|
||||
secure,
|
||||
mbits(newVal, 31, 12),
|
||||
bits(newVal, 7,0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, Inner Shareable
|
||||
case MISCREG_TLBIMVAIS:
|
||||
case MISCREG_TLBIMVALIS:
|
||||
{
|
||||
assert32();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVA tlbiOp(EL1,
|
||||
secure,
|
||||
mbits(newVal, 31, 12),
|
||||
bits(newVal, 7,0));
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by ASID match
|
||||
case MISCREG_TLBIASID:
|
||||
{
|
||||
assert32();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIASID tlbiOp(EL1,
|
||||
secure,
|
||||
bits(newVal, 7,0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by ASID match, Inner Shareable
|
||||
case MISCREG_TLBIASIDIS:
|
||||
{
|
||||
assert32();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIASID tlbiOp(EL1,
|
||||
secure,
|
||||
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();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL1, secure,
|
||||
mbits(newVal, 31,12));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, All ASID, Inner Shareable
|
||||
case MISCREG_TLBIMVAAIS:
|
||||
case MISCREG_TLBIMVAALIS:
|
||||
{
|
||||
assert32();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL1, secure,
|
||||
mbits(newVal, 31,12));
|
||||
|
||||
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();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
mbits(newVal, 31,12));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, Hyp mode, Inner Shareable
|
||||
case MISCREG_TLBIMVAHIS:
|
||||
case MISCREG_TLBIMVALHIS:
|
||||
{
|
||||
assert32();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
mbits(newVal, 31,12));
|
||||
|
||||
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();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIIPA tlbiOp(EL1,
|
||||
secure,
|
||||
static_cast<Addr>(bits(newVal, 35, 0)) << 12);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by Intermediate Physical Address, Stage 2,
|
||||
// Inner Shareable
|
||||
case MISCREG_TLBIIPAS2IS:
|
||||
case MISCREG_TLBIIPAS2LIS:
|
||||
{
|
||||
assert32();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIIPA tlbiOp(EL1,
|
||||
secure,
|
||||
static_cast<Addr>(bits(newVal, 35, 0)) << 12);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// Instruction TLB Invalidate by VA
|
||||
case MISCREG_ITLBIMVA:
|
||||
{
|
||||
assert32();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
ITLBIMVA tlbiOp(EL1,
|
||||
secure,
|
||||
mbits(newVal, 31, 12),
|
||||
bits(newVal, 7,0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// Data TLB Invalidate by VA
|
||||
case MISCREG_DTLBIMVA:
|
||||
{
|
||||
assert32();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
DTLBIMVA tlbiOp(EL1,
|
||||
secure,
|
||||
mbits(newVal, 31, 12),
|
||||
bits(newVal, 7,0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// Instruction TLB Invalidate by ASID match
|
||||
case MISCREG_ITLBIASID:
|
||||
{
|
||||
assert32();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
ITLBIASID tlbiOp(EL1,
|
||||
secure,
|
||||
bits(newVal, 7,0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// Data TLB Invalidate by ASID match
|
||||
case MISCREG_DTLBIASID:
|
||||
{
|
||||
assert32();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
DTLBIASID tlbiOp(EL1,
|
||||
secure,
|
||||
bits(newVal, 7,0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate All, Non-Secure Non-Hyp
|
||||
case MISCREG_TLBIALLNSNH:
|
||||
{
|
||||
assert32();
|
||||
|
||||
TLBIALLN tlbiOp(EL1);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate All, Non-Secure Non-Hyp, Inner Shareable
|
||||
case MISCREG_TLBIALLNSNHIS:
|
||||
{
|
||||
assert32();
|
||||
|
||||
TLBIALLN tlbiOp(EL1);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate All, Hyp mode
|
||||
case MISCREG_TLBIALLH:
|
||||
{
|
||||
assert32();
|
||||
|
||||
TLBIALLN tlbiOp(EL2);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate All, Hyp mode, Inner Shareable
|
||||
case MISCREG_TLBIALLHIS:
|
||||
{
|
||||
assert32();
|
||||
|
||||
TLBIALLN tlbiOp(EL2);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate All, EL3
|
||||
case MISCREG_TLBI_ALLE3:
|
||||
{
|
||||
assert64();
|
||||
|
||||
TLBIALLEL tlbiOp(EL3, true);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate All, EL3, Inner Shareable
|
||||
case MISCREG_TLBI_ALLE3IS:
|
||||
{
|
||||
assert64();
|
||||
|
||||
TLBIALLEL tlbiOp(EL3, true);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate All, EL2
|
||||
case MISCREG_TLBI_ALLE2:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIALLEL tlbiOp(EL2, secure);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate All, EL2, Inner Shareable
|
||||
case MISCREG_TLBI_ALLE2IS:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIALLEL tlbiOp(EL2, secure);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate All, EL1
|
||||
case MISCREG_TLBI_ALLE1:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIALLEL tlbiOp(EL1, secure);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate All, EL1, Inner Shareable
|
||||
case MISCREG_TLBI_ALLE1IS:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIALLEL tlbiOp(EL1, secure);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_VMALLS12E1:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIVMALL tlbiOp(EL1, secure, true);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_VMALLE1:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIVMALL tlbiOp(target_el, secure, false);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_VMALLS12E1IS:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIVMALL tlbiOp(EL1, secure, true);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_VMALLE1IS:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIVMALL tlbiOp(target_el, secure, false);
|
||||
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
|
||||
// AArch64 TLB Invalidate by VA, EL3
|
||||
case MISCREG_TLBI_VAE3_Xt:
|
||||
case MISCREG_TLBI_VALE3_Xt:
|
||||
{
|
||||
assert64();
|
||||
|
||||
TLBIMVAA tlbiOp(EL3, true,
|
||||
static_cast<Addr>(bits(newVal, 43, 0)) << 12);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, EL3, Inner Shareable
|
||||
case MISCREG_TLBI_VAE3IS_Xt:
|
||||
case MISCREG_TLBI_VALE3IS_Xt:
|
||||
{
|
||||
assert64();
|
||||
|
||||
TLBIMVAA tlbiOp(EL3, true,
|
||||
static_cast<Addr>(bits(newVal, 43, 0)) << 12);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, EL2
|
||||
case MISCREG_TLBI_VAE2_Xt:
|
||||
case MISCREG_TLBI_VALE2_Xt:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
HCR hcr = readMiscReg(MISCREG_HCR_EL2);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
|
||||
if (hcr.e2h) {
|
||||
// The asid will only be used when e2h == 1
|
||||
auto asid = haveLargeAsid64 ? bits(newVal, 63, 48) :
|
||||
bits(newVal, 55, 48);
|
||||
|
||||
TLBIMVA tlbiOp(EL2, secure,
|
||||
static_cast<Addr>(bits(newVal, 43, 0)) << 12,
|
||||
asid);
|
||||
tlbiOp(tc);
|
||||
} else {
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
static_cast<Addr>(bits(newVal, 43, 0)) << 12);
|
||||
tlbiOp(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, EL2, Inner Shareable
|
||||
case MISCREG_TLBI_VAE2IS_Xt:
|
||||
case MISCREG_TLBI_VALE2IS_Xt:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
HCR hcr = readMiscReg(MISCREG_HCR_EL2);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
|
||||
if (hcr.e2h) {
|
||||
// The asid will only be used when e2h == 1
|
||||
auto asid = haveLargeAsid64 ? bits(newVal, 63, 48) :
|
||||
bits(newVal, 55, 48);
|
||||
|
||||
TLBIMVA tlbiOp(EL2, secure,
|
||||
static_cast<Addr>(bits(newVal, 43, 0)) << 12,
|
||||
asid);
|
||||
tlbiOp.broadcast(tc);
|
||||
} else {
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
static_cast<Addr>(bits(newVal, 43, 0)) << 12);
|
||||
tlbiOp.broadcast(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, EL1
|
||||
case MISCREG_TLBI_VAE1_Xt:
|
||||
case MISCREG_TLBI_VALE1_Xt:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
auto asid = haveLargeAsid64 ? bits(newVal, 63, 48) :
|
||||
bits(newVal, 55, 48);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVA tlbiOp(target_el, secure,
|
||||
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();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
auto asid = haveLargeAsid64 ? bits(newVal, 63, 48) :
|
||||
bits(newVal, 55, 48);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVA tlbiOp(target_el, secure,
|
||||
static_cast<Addr>(bits(newVal, 43, 0)) << 12,
|
||||
asid);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by ASID, EL1
|
||||
case MISCREG_TLBI_ASIDE1_Xt:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
auto asid = haveLargeAsid64 ? bits(newVal, 63, 48) :
|
||||
bits(newVal, 55, 48);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIASID tlbiOp(target_el, secure, asid);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by ASID, EL1, Inner Shareable
|
||||
case MISCREG_TLBI_ASIDE1IS_Xt:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
auto asid = haveLargeAsid64 ? bits(newVal, 63, 48) :
|
||||
bits(newVal, 55, 48);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIASID tlbiOp(target_el, secure, 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
|
||||
// AArch64 TLB Invalidate by VA, All ASID, EL1
|
||||
case MISCREG_TLBI_VAAE1_Xt:
|
||||
case MISCREG_TLBI_VAALE1_Xt:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(target_el, secure,
|
||||
static_cast<Addr>(bits(newVal, 43, 0)) << 12);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, All ASID, EL1, Inner Shareable
|
||||
case MISCREG_TLBI_VAAE1IS_Xt:
|
||||
case MISCREG_TLBI_VAALE1IS_Xt:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
ExceptionLevel target_el = EL1;
|
||||
if (EL2Enabled(tc)) {
|
||||
HCR hcr = readMiscReg(MISCREG_HCR_EL2);
|
||||
if (hcr.tge && hcr.e2h) {
|
||||
target_el = EL2;
|
||||
}
|
||||
}
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(target_el, secure,
|
||||
static_cast<Addr>(bits(newVal, 43, 0)) << 12);
|
||||
|
||||
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();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIIPA tlbiOp(EL1, secure,
|
||||
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_IPAS2LE1IS_Xt:
|
||||
{
|
||||
assert64();
|
||||
scr = readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIIPA tlbiOp(EL1, secure,
|
||||
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;
|
||||
|
||||
@@ -610,10 +610,6 @@ namespace ArmISA
|
||||
BaseISADevice &getGenericTimer();
|
||||
BaseISADevice &getGICv3CPUInterface();
|
||||
|
||||
private:
|
||||
void assert32() { assert(((CPSR)readMiscReg(MISCREG_CPSR)).width); }
|
||||
void assert64() { assert(!((CPSR)readMiscReg(MISCREG_CPSR)).width); }
|
||||
|
||||
public:
|
||||
void clear();
|
||||
|
||||
@@ -642,6 +638,8 @@ namespace ArmISA
|
||||
return arm_isa->getSelfDebug();
|
||||
}
|
||||
|
||||
const ArmRelease* getRelease() const { return release; }
|
||||
|
||||
RegVal readMiscRegNoEffect(int misc_reg) const;
|
||||
RegVal readMiscReg(int misc_reg);
|
||||
void setMiscRegNoEffect(int misc_reg, RegVal val);
|
||||
|
||||
@@ -514,6 +514,44 @@ namespace Aarch64
|
||||
return new Dccivac(machInst, rt, miscReg, iss);
|
||||
case MISCREG_DC_IVAC_Xt:
|
||||
return new Dcivac(machInst, rt, miscReg, iss);
|
||||
// 64-bit TLBIs split into "Local"
|
||||
// and "Shareable"
|
||||
case MISCREG_TLBI_ALLE3:
|
||||
case MISCREG_TLBI_ALLE2:
|
||||
case MISCREG_TLBI_ALLE1:
|
||||
case MISCREG_TLBI_VMALLS12E1:
|
||||
case MISCREG_TLBI_VMALLE1:
|
||||
case MISCREG_TLBI_VAE3_Xt:
|
||||
case MISCREG_TLBI_VALE3_Xt:
|
||||
case MISCREG_TLBI_VAE2_Xt:
|
||||
case MISCREG_TLBI_VALE2_Xt:
|
||||
case MISCREG_TLBI_VAE1_Xt:
|
||||
case MISCREG_TLBI_VALE1_Xt:
|
||||
case MISCREG_TLBI_ASIDE1_Xt:
|
||||
case MISCREG_TLBI_VAAE1_Xt:
|
||||
case MISCREG_TLBI_VAALE1_Xt:
|
||||
case MISCREG_TLBI_IPAS2E1_Xt:
|
||||
case MISCREG_TLBI_IPAS2LE1_Xt:
|
||||
return new Tlbi64LocalHub(
|
||||
machInst, miscReg, rt, iss);
|
||||
case MISCREG_TLBI_ALLE3IS:
|
||||
case MISCREG_TLBI_ALLE2IS:
|
||||
case MISCREG_TLBI_ALLE1IS:
|
||||
case MISCREG_TLBI_VMALLS12E1IS:
|
||||
case MISCREG_TLBI_VMALLE1IS:
|
||||
case MISCREG_TLBI_VAE3IS_Xt:
|
||||
case MISCREG_TLBI_VALE3IS_Xt:
|
||||
case MISCREG_TLBI_VAE2IS_Xt:
|
||||
case MISCREG_TLBI_VALE2IS_Xt:
|
||||
case MISCREG_TLBI_VAE1IS_Xt:
|
||||
case MISCREG_TLBI_VALE1IS_Xt:
|
||||
case MISCREG_TLBI_ASIDE1IS_Xt:
|
||||
case MISCREG_TLBI_VAAE1IS_Xt:
|
||||
case MISCREG_TLBI_VAALE1IS_Xt:
|
||||
case MISCREG_TLBI_IPAS2E1IS_Xt:
|
||||
case MISCREG_TLBI_IPAS2LE1IS_Xt:
|
||||
return new Tlbi64ShareableHub(
|
||||
machInst, miscReg, rt, iss);
|
||||
default:
|
||||
return new Msr64(machInst, miscReg, rt, iss);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// Copyright (c) 2010-2013,2016-2018 ARM Limited
|
||||
// Copyright (c) 2010-2013,2016-2018, 2021 Arm Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// The license below extends only to copyright in the software and shall
|
||||
@@ -247,6 +247,37 @@ let {{
|
||||
return new McrDccmvau(machInst, miscReg, rt, iss);
|
||||
case MISCREG_DCCIMVAC:
|
||||
return new McrDccimvac(machInst, miscReg, rt, iss);
|
||||
case MISCREG_TLBIALL:
|
||||
case MISCREG_TLBIALLIS:
|
||||
case MISCREG_ITLBIALL:
|
||||
case MISCREG_DTLBIALL:
|
||||
case MISCREG_TLBIMVA:
|
||||
case MISCREG_TLBIMVAL:
|
||||
case MISCREG_TLBIMVAIS:
|
||||
case MISCREG_TLBIMVALIS:
|
||||
case MISCREG_TLBIASID:
|
||||
case MISCREG_TLBIASIDIS:
|
||||
case MISCREG_TLBIMVAA:
|
||||
case MISCREG_TLBIMVAAL:
|
||||
case MISCREG_TLBIMVAAIS:
|
||||
case MISCREG_TLBIMVAALIS:
|
||||
case MISCREG_TLBIMVAH:
|
||||
case MISCREG_TLBIMVALH:
|
||||
case MISCREG_TLBIMVAHIS:
|
||||
case MISCREG_TLBIMVALHIS:
|
||||
case MISCREG_TLBIIPAS2:
|
||||
case MISCREG_TLBIIPAS2L:
|
||||
case MISCREG_TLBIIPAS2IS:
|
||||
case MISCREG_TLBIIPAS2LIS:
|
||||
case MISCREG_ITLBIMVA:
|
||||
case MISCREG_DTLBIMVA:
|
||||
case MISCREG_ITLBIASID:
|
||||
case MISCREG_DTLBIASID:
|
||||
case MISCREG_TLBIALLNSNH:
|
||||
case MISCREG_TLBIALLNSNHIS:
|
||||
case MISCREG_TLBIALLH:
|
||||
case MISCREG_TLBIALLHIS:
|
||||
return new Tlbi(machInst, miscReg, rt, iss);
|
||||
default:
|
||||
if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) {
|
||||
std::string full_mnem = csprintf("%s %s",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// Copyright (c) 2011-2013, 2016-2020 ARM Limited
|
||||
// Copyright (c) 2011-2013, 2016-2021 Arm Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// The license below extends only to copyright in the software and shall
|
||||
@@ -368,6 +368,22 @@ let {{
|
||||
decoder_output += MiscRegRegOp64Constructor.subst(msrIop)
|
||||
exec_output += BasicExecute.subst(msrIop)
|
||||
|
||||
tlbiCode = msr_check_code + '''
|
||||
performTlbi(xc, flat_idx, XOp1);
|
||||
'''
|
||||
msrTlbiIop = ArmInstObjParams("msr", "Tlbi64LocalHub", "TlbiOp64",
|
||||
tlbiCode,
|
||||
["IsSerializeAfter", "IsNonSpeculative"])
|
||||
header_output += MiscRegRegOp64Declare.subst(msrTlbiIop)
|
||||
decoder_output += MiscRegRegOp64Constructor.subst(msrTlbiIop)
|
||||
exec_output += BasicExecute.subst(msrTlbiIop)
|
||||
|
||||
msrTlbiSIop = ArmInstObjParams("msr", "Tlbi64ShareableHub", "TlbiOp64",
|
||||
tlbiCode,
|
||||
["IsSerializeAfter", "IsNonSpeculative"])
|
||||
header_output += MiscRegRegOp64Declare.subst(msrTlbiSIop)
|
||||
decoder_output += MiscRegRegOp64Constructor.subst(msrTlbiSIop)
|
||||
exec_output += BasicExecute.subst(msrTlbiSIop)
|
||||
|
||||
buildDataXRegInst("msrNZCV", 1, '''
|
||||
CPSR cpsr = XOp1;
|
||||
|
||||
@@ -1001,6 +1001,17 @@ let {{
|
||||
decoder_output += MiscRegRegImmOpConstructor.subst(mcr15Iop)
|
||||
exec_output += PredOpExecute.subst(mcr15Iop)
|
||||
|
||||
mcrTlbiCode = mcr15CheckCode + '''
|
||||
performTlbi(xc, miscReg, Op1);
|
||||
'''
|
||||
mcrTlbiIop = ArmInstObjParams("mcr", "Tlbi", "TlbiOp",
|
||||
{ "code": mcrTlbiCode,
|
||||
"predicate_test": predicateTest },
|
||||
["IsSerializeAfter","IsNonSpeculative"])
|
||||
header_output += MiscRegRegImmOpDeclare.subst(mcrTlbiIop)
|
||||
decoder_output += MiscRegRegImmOpConstructor.subst(mcrTlbiIop)
|
||||
exec_output += PredOpExecute.subst(mcrTlbiIop)
|
||||
|
||||
|
||||
mrrc15code = '''
|
||||
int preFlatOp1 = snsBankedIndex(op1, xc->tcBase());
|
||||
|
||||
Reference in New Issue
Block a user