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:
Giacomo Travaglini
2021-10-25 15:01:11 +01:00
parent f36c5d778b
commit a00f6d67d4
10 changed files with 769 additions and 670 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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",

View File

@@ -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;

View File

@@ -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());