blob: 40a6ca4ce5e45458e921bae8dee88bc8a7a09dde [file] [log] [blame]
/*
* Copyright (c) 2011-2013,2017-2022 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.
*/
#include "arch/arm/insts/misc64.hh"
#include "arch/arm/isa.hh"
#include "arch/arm/tlbi_op.hh"
namespace gem5
{
using namespace ArmISA;
std::string
ImmOp64::generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss, "", false);
ccprintf(ss, "#0x%x", imm);
return ss.str();
}
std::string
RegRegImmImmOp64::generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss, "", false);
printIntReg(ss, dest);
ss << ", ";
printIntReg(ss, op1);
ccprintf(ss, ", #%d, #%d", imm1, imm2);
return ss.str();
}
std::string
RegRegRegImmOp64::generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss, "", false);
printIntReg(ss, dest);
ss << ", ";
printIntReg(ss, op1);
ss << ", ";
printIntReg(ss, op2);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
std::string
UnknownOp64::generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const
{
return csprintf("%-10s (inst %#08x)", "unknown", encoding());
}
uint32_t
MiscRegOp64::_iss(const MiscRegNum64 &misc_reg, RegIndex int_index) const
{
return _miscRead |
(misc_reg.crm << 1) |
(int_index << 5) |
(misc_reg.crn << 10) |
(misc_reg.op1 << 14) |
(misc_reg.op2 << 17) |
(misc_reg.op0 << 20);
}
Fault
MiscRegOp64::generateTrap(ExceptionLevel el) const
{
return generateTrap(el, ExceptionClass::TRAPPED_MSR_MRS_64, iss());
}
Fault
MiscRegOp64::generateTrap(ExceptionLevel el, ExceptionClass ec,
uint32_t iss) const
{
switch (el) {
case EL1:
return std::make_shared<SupervisorTrap>(getEMI(), iss, ec);
case EL2:
return std::make_shared<HypervisorTrap>(getEMI(), iss, ec);
case EL3:
return std::make_shared<SecureMonitorTrap>(getEMI(), iss, ec);
default:
panic("Invalid EL: %d\n", el);
}
}
RegVal
MiscRegImmOp64::miscRegImm() const
{
switch (dest) {
case MISCREG_SPSEL:
return imm & 0x1;
case MISCREG_PAN:
return (imm & 0x1) << 22;
case MISCREG_UAO:
return (imm & 0x1) << 23;
default:
panic("Not a valid PSTATE field register\n");
}
}
std::string
MiscRegImmOp64::generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printMiscReg(ss, dest);
ss << ", ";
ccprintf(ss, "#0x%x", imm);
return ss.str();
}
std::string
MiscRegRegImmOp64::generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printMiscReg(ss, dest);
ss << ", ";
printIntReg(ss, op1);
return ss.str();
}
uint32_t
MiscRegRegImmOp64::iss() const
{
const MiscRegNum64 &misc_reg = encodeAArch64SysReg(dest);
return _iss(misc_reg, op1);
}
std::string
RegMiscRegImmOp64::generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printIntReg(ss, dest);
ss << ", ";
printMiscReg(ss, op1);
return ss.str();
}
uint32_t
RegMiscRegImmOp64::iss() const
{
const MiscRegNum64 &misc_reg = encodeAArch64SysReg(op1);
return _iss(misc_reg, dest);
}
Fault
MiscRegImplDefined64::execute(ExecContext *xc,
trace::InstRecord *traceData) const
{
auto tc = xc->tcBase();
const CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
return checkFaultAccessAArch64SysReg(
MISCREG_IMPDEF_UNIMPL, cpsr, tc, *this);
}
std::string
MiscRegImplDefined64::generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const
{
return csprintf("%-10s (implementation defined)", fullMnemonic.c_str());
}
uint32_t
MiscRegImplDefined64::iss() const
{
return _iss(miscReg, intReg);
}
std::string
RegNone::generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printIntReg(ss, dest);
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_EL3);
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_EL3);
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_EL3);
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_EL3);
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_EL3);
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_EL3);
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_EL3);
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_EL3);
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;
}
// AArch64 TLB Invalidate by VA, EL3
case MISCREG_TLBI_VAE3_Xt:
{
TLBIMVAA tlbiOp(EL3, true,
static_cast<Addr>(bits(value, 43, 0)) << 12,
false);
tlbiOp(tc);
return;
}
// AArch64 TLB Invalidate by VA, Last Level, EL3
case MISCREG_TLBI_VALE3_Xt:
{
TLBIMVAA tlbiOp(EL3, true,
static_cast<Addr>(bits(value, 43, 0)) << 12,
true);
tlbiOp(tc);
return;
}
// AArch64 TLB Invalidate by VA, EL3, Inner Shareable
case MISCREG_TLBI_VAE3IS_Xt:
{
TLBIMVAA tlbiOp(EL3, true,
static_cast<Addr>(bits(value, 43, 0)) << 12,
false);
tlbiOp.broadcast(tc);
return;
}
// AArch64 TLB Invalidate by VA, Last Level, EL3, Inner Shareable
case MISCREG_TLBI_VALE3IS_Xt:
{
TLBIMVAA tlbiOp(EL3, true,
static_cast<Addr>(bits(value, 43, 0)) << 12,
true);
tlbiOp.broadcast(tc);
return;
}
// AArch64 TLB Invalidate by VA, EL2
case MISCREG_TLBI_VAE2_Xt:
{
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
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, false);
tlbiOp(tc);
} else {
TLBIMVAA tlbiOp(EL2, secure,
static_cast<Addr>(bits(value, 43, 0)) << 12,
false);
tlbiOp(tc);
}
return;
}
// AArch64 TLB Invalidate by VA, Last Level, EL2
case MISCREG_TLBI_VALE2_Xt:
{
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
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, true);
tlbiOp(tc);
} else {
TLBIMVAA tlbiOp(EL2, secure,
static_cast<Addr>(bits(value, 43, 0)) << 12,
true);
tlbiOp(tc);
}
return;
}
// AArch64 TLB Invalidate by VA, EL2, Inner Shareable
case MISCREG_TLBI_VAE2IS_Xt:
{
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
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, false);
tlbiOp.broadcast(tc);
} else {
TLBIMVAA tlbiOp(EL2, secure,
static_cast<Addr>(bits(value, 43, 0)) << 12,
false);
tlbiOp.broadcast(tc);
}
return;
}
// AArch64 TLB Invalidate by VA, Last Level, EL2, Inner Shareable
case MISCREG_TLBI_VALE2IS_Xt:
{
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
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, true);
tlbiOp.broadcast(tc);
} else {
TLBIMVAA tlbiOp(EL2, secure,
static_cast<Addr>(bits(value, 43, 0)) << 12,
true);
tlbiOp.broadcast(tc);
}
return;
}
// AArch64 TLB Invalidate by VA, EL1
case MISCREG_TLBI_VAE1_Xt:
{
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
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, false);
tlbiOp(tc);
return;
}
// AArch64 TLB Invalidate by VA, Last Level, EL1
case MISCREG_TLBI_VALE1_Xt:
{
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
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, true);
tlbiOp(tc);
return;
}
// AArch64 TLB Invalidate by VA, EL1, Inner Shareable
case MISCREG_TLBI_VAE1IS_Xt:
{
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
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, false);
tlbiOp.broadcast(tc);
return;
}
case MISCREG_TLBI_VALE1IS_Xt:
{
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
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, true);
tlbiOp.broadcast(tc);
return;
}
// AArch64 TLB Invalidate by ASID, EL1
case MISCREG_TLBI_ASIDE1_Xt:
{
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
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_EL3);
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;
}
// AArch64 TLB Invalidate by VA, All ASID, EL1
case MISCREG_TLBI_VAAE1_Xt:
{
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
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,
false);
tlbiOp(tc);
return;
}
// AArch64 TLB Invalidate by VA, Last Level, All ASID, EL1
case MISCREG_TLBI_VAALE1_Xt:
{
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
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,
true);
tlbiOp(tc);
return;
}
// AArch64 TLB Invalidate by VA, All ASID, EL1, Inner Shareable
case MISCREG_TLBI_VAAE1IS_Xt:
{
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
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,
false);
tlbiOp.broadcast(tc);
return;
}
// AArch64 TLB Invalidate by VA, All ASID,
// Last Level, EL1, Inner Shareable
case MISCREG_TLBI_VAALE1IS_Xt:
{
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
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,
true);
tlbiOp.broadcast(tc);
return;
}
// AArch64 TLB Invalidate by Intermediate Physical Address,
// Stage 2, EL1
case MISCREG_TLBI_IPAS2E1_Xt:
{
if (EL2Enabled(tc)) {
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
bool secure = release->has(ArmExtension::SECURITY) &&
!scr.ns && !bits(value, 63);
const int top_bit = ArmSystem::physAddrRange(tc) == 52 ?
39 : 35;
TLBIIPA tlbiOp(EL1, secure,
static_cast<Addr>(bits(value, top_bit, 0)) << 12,
false);
tlbiOp(tc);
}
return;
}
// AArch64 TLB Invalidate by Intermediate Physical Address,
// Stage 2, Last Level EL1
case MISCREG_TLBI_IPAS2LE1_Xt:
{
if (EL2Enabled(tc)) {
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
bool secure = release->has(ArmExtension::SECURITY) &&
!scr.ns && !bits(value, 63);
TLBIIPA tlbiOp(EL1, secure,
static_cast<Addr>(bits(value, 35, 0)) << 12,
true);
tlbiOp(tc);
}
return;
}
// AArch64 TLB Invalidate by Intermediate Physical Address,
// Stage 2, EL1, Inner Shareable
case MISCREG_TLBI_IPAS2E1IS_Xt:
{
if (EL2Enabled(tc)) {
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
bool secure = release->has(ArmExtension::SECURITY) &&
!scr.ns && !bits(value, 63);
const int top_bit = ArmSystem::physAddrRange(tc) == 52 ?
39 : 35;
TLBIIPA tlbiOp(EL1, secure,
static_cast<Addr>(bits(value, top_bit, 0)) << 12,
false);
tlbiOp.broadcast(tc);
}
return;
}
// AArch64 TLB Invalidate by Intermediate Physical Address,
// Stage 2, Last Level, EL1, Inner Shareable
case MISCREG_TLBI_IPAS2LE1IS_Xt:
{
if (EL2Enabled(tc)) {
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
bool secure = release->has(ArmExtension::SECURITY) &&
!scr.ns && !bits(value, 63);
TLBIIPA tlbiOp(EL1, secure,
static_cast<Addr>(bits(value, 35, 0)) << 12,
true);
tlbiOp.broadcast(tc);
}
return;
}
default:
panic("Invalid TLBI\n");
}
}
} // namespace gem5