arch-arm: Implement FEAT_TLBIRANGE extension (#414)
This commit is contained in:
@@ -89,6 +89,7 @@ class ArmExtension(ScopedEnum):
|
||||
# Armv8.4
|
||||
"FEAT_SEL2",
|
||||
"FEAT_TLBIOS",
|
||||
"FEAT_TLBIRANGE",
|
||||
"FEAT_FLAGM",
|
||||
"FEAT_IDST",
|
||||
# Armv8.5
|
||||
@@ -183,6 +184,7 @@ class ArmDefaultRelease(Armv8):
|
||||
# Armv8.4
|
||||
"FEAT_SEL2",
|
||||
"FEAT_TLBIOS",
|
||||
"FEAT_TLBIRANGE",
|
||||
"FEAT_FLAGM",
|
||||
"FEAT_IDST",
|
||||
# Armv8.5
|
||||
@@ -229,6 +231,7 @@ class Armv84(Armv83):
|
||||
extensions = Armv83.extensions + [
|
||||
"FEAT_SEL2",
|
||||
"FEAT_TLBIOS",
|
||||
"FEAT_TLBIRANGE",
|
||||
"FEAT_FLAGM",
|
||||
"FEAT_IDST",
|
||||
]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2013,2017-2022 Arm Limited
|
||||
* Copyright (c) 2011-2013,2017-2023 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -852,6 +852,354 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons
|
||||
}
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVAE1_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;
|
||||
TLBIRMVA tlbiOp(target_el, secure, value, asid, false);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVAE1IS_Xt:
|
||||
case MISCREG_TLBI_RVAE1OS_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;
|
||||
TLBIRMVA tlbiOp(target_el, secure, value, asid, false);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVAAE1_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;
|
||||
TLBIRMVAA tlbiOp(target_el, secure, value, false);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVAAE1IS_Xt:
|
||||
case MISCREG_TLBI_RVAAE1OS_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;
|
||||
TLBIRMVAA tlbiOp(target_el, secure, value, false);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVALE1_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;
|
||||
TLBIRMVA tlbiOp(target_el, secure, value, asid, true);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVALE1IS_Xt:
|
||||
case MISCREG_TLBI_RVALE1OS_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;
|
||||
TLBIRMVA tlbiOp(target_el, secure, value, asid, true);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVAALE1_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;
|
||||
TLBIRMVAA tlbiOp(target_el, secure, value, true);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVAALE1IS_Xt:
|
||||
case MISCREG_TLBI_RVAALE1OS_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;
|
||||
TLBIRMVAA tlbiOp(target_el, secure, value, true);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RIPAS2E1_Xt:
|
||||
{
|
||||
if (EL2Enabled(tc)) {
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) &&
|
||||
!scr.ns && !bits(value, 63);
|
||||
|
||||
TLBIRIPA tlbiOp(EL1, secure, value, false);
|
||||
|
||||
tlbiOp(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RIPAS2E1IS_Xt:
|
||||
{
|
||||
if (EL2Enabled(tc)) {
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) &&
|
||||
!scr.ns && !bits(value, 63);
|
||||
|
||||
TLBIRIPA tlbiOp(EL1, secure, value, false);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RIPAS2LE1_Xt:
|
||||
{
|
||||
if (EL2Enabled(tc)) {
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) &&
|
||||
!scr.ns && !bits(value, 63);
|
||||
|
||||
TLBIRIPA tlbiOp(EL1, secure, value, true);
|
||||
|
||||
tlbiOp(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RIPAS2LE1IS_Xt:
|
||||
{
|
||||
if (EL2Enabled(tc)) {
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) &&
|
||||
!scr.ns && !bits(value, 63);
|
||||
|
||||
TLBIRIPA tlbiOp(EL1, secure, value, true);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVAE2_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);
|
||||
|
||||
TLBIRMVA tlbiOp(EL2, secure, value, asid, false);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp(tc);
|
||||
} else {
|
||||
TLBIRMVAA tlbiOp(EL2, secure, value, false);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVAE2IS_Xt:
|
||||
case MISCREG_TLBI_RVAE2OS_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);
|
||||
|
||||
TLBIRMVA tlbiOp(EL2, secure, value, asid, false);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp.broadcast(tc);
|
||||
} else {
|
||||
TLBIRMVAA tlbiOp(EL2, secure, value, false);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp.broadcast(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVALE2_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);
|
||||
|
||||
TLBIRMVA tlbiOp(EL2, secure, value, asid, true);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp(tc);
|
||||
} else {
|
||||
TLBIRMVAA tlbiOp(EL2, secure, value, true);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVALE2IS_Xt:
|
||||
case MISCREG_TLBI_RVALE2OS_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);
|
||||
|
||||
TLBIRMVA tlbiOp(EL2, secure, value, asid, true);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp.broadcast(tc);
|
||||
} else {
|
||||
TLBIRMVAA tlbiOp(EL2, secure, value, true);
|
||||
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp.broadcast(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVAE3_Xt:
|
||||
{
|
||||
TLBIRMVAA tlbiOp(EL3, true, value, false);
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVAE3IS_Xt:
|
||||
case MISCREG_TLBI_RVAE3OS_Xt:
|
||||
{
|
||||
TLBIRMVAA tlbiOp(EL3, true, value, false);
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVALE3_Xt:
|
||||
{
|
||||
TLBIRMVAA tlbiOp(EL3, true, value, true);
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_RVALE3IS_Xt:
|
||||
case MISCREG_TLBI_RVALE3OS_Xt:
|
||||
{
|
||||
TLBIRMVAA tlbiOp(EL3, true, value, true);
|
||||
if (tlbiOp.valid())
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
panic("Invalid TLBI\n");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2022 Arm Limited
|
||||
// Copyright (c) 2011-2023 Arm Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// The license below extends only to copyright in the software and shall
|
||||
@@ -542,6 +542,16 @@ namespace Aarch64
|
||||
case MISCREG_TLBI_VAALE1_Xt:
|
||||
case MISCREG_TLBI_IPAS2E1_Xt:
|
||||
case MISCREG_TLBI_IPAS2LE1_Xt:
|
||||
case MISCREG_TLBI_RVAE1_Xt:
|
||||
case MISCREG_TLBI_RVAAE1_Xt:
|
||||
case MISCREG_TLBI_RVALE1_Xt:
|
||||
case MISCREG_TLBI_RVAALE1_Xt:
|
||||
case MISCREG_TLBI_RIPAS2E1_Xt:
|
||||
case MISCREG_TLBI_RIPAS2LE1_Xt:
|
||||
case MISCREG_TLBI_RVAE2_Xt:
|
||||
case MISCREG_TLBI_RVALE2_Xt:
|
||||
case MISCREG_TLBI_RVAE3_Xt:
|
||||
case MISCREG_TLBI_RVALE3_Xt:
|
||||
return new Tlbi64LocalHub(
|
||||
machInst, miscReg, rt);
|
||||
case MISCREG_TLBI_ALLE3IS:
|
||||
@@ -576,6 +586,26 @@ namespace Aarch64
|
||||
case MISCREG_TLBI_IPAS2E1OS_Xt:
|
||||
case MISCREG_TLBI_IPAS2LE1IS_Xt:
|
||||
case MISCREG_TLBI_IPAS2LE1OS_Xt:
|
||||
case MISCREG_TLBI_RVAE1IS_Xt:
|
||||
case MISCREG_TLBI_RVAE1OS_Xt:
|
||||
case MISCREG_TLBI_RVAAE1IS_Xt:
|
||||
case MISCREG_TLBI_RVAAE1OS_Xt:
|
||||
case MISCREG_TLBI_RVALE1IS_Xt:
|
||||
case MISCREG_TLBI_RVALE1OS_Xt:
|
||||
case MISCREG_TLBI_RVAALE1IS_Xt:
|
||||
case MISCREG_TLBI_RVAALE1OS_Xt:
|
||||
case MISCREG_TLBI_RIPAS2E1IS_Xt:
|
||||
case MISCREG_TLBI_RIPAS2E1OS_Xt:
|
||||
case MISCREG_TLBI_RIPAS2LE1IS_Xt:
|
||||
case MISCREG_TLBI_RIPAS2LE1OS_Xt:
|
||||
case MISCREG_TLBI_RVAE2IS_Xt:
|
||||
case MISCREG_TLBI_RVAE2OS_Xt:
|
||||
case MISCREG_TLBI_RVALE2IS_Xt:
|
||||
case MISCREG_TLBI_RVALE2OS_Xt:
|
||||
case MISCREG_TLBI_RVAE3IS_Xt:
|
||||
case MISCREG_TLBI_RVAE3OS_Xt:
|
||||
case MISCREG_TLBI_RVALE3IS_Xt:
|
||||
case MISCREG_TLBI_RVALE3OS_Xt:
|
||||
return new Tlbi64ShareableHub(
|
||||
machInst, miscReg, rt, dec.dvmEnabled);
|
||||
default:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2012-2013, 2021 Arm Limited
|
||||
* Copyright (c) 2010, 2012-2013, 2021, 2023 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -186,6 +186,12 @@ struct TlbEntry : public Serializable
|
||||
{
|
||||
// virtual address
|
||||
Addr va = 0;
|
||||
// lookup size:
|
||||
// * != 0 -> this is a range based lookup.
|
||||
// end_address = va + size
|
||||
// * == 0 -> This is a normal lookup. size should
|
||||
// be ignored
|
||||
Addr size = 0;
|
||||
// context id/address space id to use
|
||||
uint16_t asn = 0;
|
||||
// if on lookup asn should be ignored
|
||||
@@ -219,6 +225,7 @@ struct TlbEntry : public Serializable
|
||||
|
||||
uint16_t asid; // Address Space Identifier
|
||||
vmid_t vmid; // Virtual machine Identifier
|
||||
GrainSize tg; // Translation Granule Size
|
||||
uint8_t N; // Number of bits in pagesize
|
||||
uint8_t innerAttrs;
|
||||
uint8_t outerAttrs;
|
||||
@@ -263,7 +270,7 @@ struct TlbEntry : public Serializable
|
||||
bool uncacheable, bool read_only) :
|
||||
pfn(_paddr >> PageShift), size(PageBytes - 1), vpn(_vaddr >> PageShift),
|
||||
attributes(0), lookupLevel(LookupLevel::L1),
|
||||
asid(_asn), vmid(0), N(0),
|
||||
asid(_asn), vmid(0), tg(Grain4KB), N(0),
|
||||
innerAttrs(0), outerAttrs(0), ap(read_only ? 0x3 : 0), hap(0x3),
|
||||
domain(DomainType::Client), mtype(MemoryType::StronglyOrdered),
|
||||
longDescFormat(false), isHyp(false), global(false), valid(true),
|
||||
@@ -281,7 +288,7 @@ struct TlbEntry : public Serializable
|
||||
|
||||
TlbEntry() :
|
||||
pfn(0), size(0), vpn(0), attributes(0), lookupLevel(LookupLevel::L1),
|
||||
asid(0), vmid(0), N(0),
|
||||
asid(0), vmid(0), tg(ReservedGrain), N(0),
|
||||
innerAttrs(0), outerAttrs(0), ap(0), hap(0x3),
|
||||
domain(DomainType::Client), mtype(MemoryType::StronglyOrdered),
|
||||
longDescFormat(false), isHyp(false), global(false), valid(false),
|
||||
@@ -306,12 +313,25 @@ struct TlbEntry : public Serializable
|
||||
return pfn << PageShift;
|
||||
}
|
||||
|
||||
bool
|
||||
matchAddress(const Lookup &lookup) const
|
||||
{
|
||||
Addr page_addr = vpn << N;
|
||||
if (lookup.size) {
|
||||
// This is a range based loookup
|
||||
return lookup.va <= page_addr + size &&
|
||||
lookup.va + lookup.size > page_addr;
|
||||
} else {
|
||||
// This is a normal lookup
|
||||
return lookup.va >= page_addr && lookup.va <= page_addr + size;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
match(const Lookup &lookup) const
|
||||
{
|
||||
bool match = false;
|
||||
Addr v = vpn << N;
|
||||
if (valid && lookup.va >= v && lookup.va <= v + size &&
|
||||
if (valid && matchAddress(lookup) &&
|
||||
(lookup.secure == !nstid) && (lookup.hyp == isHyp))
|
||||
{
|
||||
match = checkELMatch(lookup.targetEL, lookup.inHost);
|
||||
@@ -319,8 +339,8 @@ struct TlbEntry : public Serializable
|
||||
if (match && !lookup.ignoreAsn) {
|
||||
match = global || (lookup.asn == asid);
|
||||
}
|
||||
if (match && nstid) {
|
||||
match = isHyp || (lookup.vmid == vmid);
|
||||
if (match && useVMID(lookup.targetEL, lookup.inHost)) {
|
||||
match = lookup.vmid == vmid;
|
||||
}
|
||||
}
|
||||
return match;
|
||||
|
||||
@@ -759,12 +759,24 @@ std::unordered_map<MiscRegNum64, MiscRegIndex> miscRegNumToIdx{
|
||||
{ MiscRegNum64(1, 0, 8, 1, 3), MISCREG_TLBI_VAAE1OS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 1, 5), MISCREG_TLBI_VALE1OS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 1, 7), MISCREG_TLBI_VAALE1OS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 2, 1), MISCREG_TLBI_RVAE1IS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 2, 3), MISCREG_TLBI_RVAAE1IS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 2, 5), MISCREG_TLBI_RVALE1IS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 2, 7), MISCREG_TLBI_RVAALE1IS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 3, 0), MISCREG_TLBI_VMALLE1IS },
|
||||
{ MiscRegNum64(1, 0, 8, 3, 1), MISCREG_TLBI_VAE1IS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 3, 2), MISCREG_TLBI_ASIDE1IS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 3, 3), MISCREG_TLBI_VAAE1IS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 3, 5), MISCREG_TLBI_VALE1IS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 3, 7), MISCREG_TLBI_VAALE1IS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 5, 1), MISCREG_TLBI_RVAE1OS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 5, 3), MISCREG_TLBI_RVAAE1OS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 5, 5), MISCREG_TLBI_RVALE1OS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 5, 7), MISCREG_TLBI_RVAALE1OS_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 6, 1), MISCREG_TLBI_RVAE1_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 6, 3), MISCREG_TLBI_RVAAE1_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 6, 5), MISCREG_TLBI_RVALE1_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 6, 7), MISCREG_TLBI_RVAALE1_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 7, 0), MISCREG_TLBI_VMALLE1 },
|
||||
{ MiscRegNum64(1, 0, 8, 7, 1), MISCREG_TLBI_VAE1_Xt },
|
||||
{ MiscRegNum64(1, 0, 8, 7, 2), MISCREG_TLBI_ASIDE1_Xt },
|
||||
@@ -783,12 +795,16 @@ std::unordered_map<MiscRegNum64, MiscRegIndex> miscRegNumToIdx{
|
||||
{ MiscRegNum64(1, 4, 7, 8, 6), MISCREG_AT_S12E0R_Xt },
|
||||
{ MiscRegNum64(1, 4, 7, 8, 7), MISCREG_AT_S12E0W_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 0, 1), MISCREG_TLBI_IPAS2E1IS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 0, 2), MISCREG_TLBI_RIPAS2E1IS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 0, 5), MISCREG_TLBI_IPAS2LE1IS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 1, 0), MISCREG_TLBI_ALLE2OS },
|
||||
{ MiscRegNum64(1, 4, 8, 1, 1), MISCREG_TLBI_VAE2OS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 1, 4), MISCREG_TLBI_ALLE1OS },
|
||||
{ MiscRegNum64(1, 4, 8, 1, 5), MISCREG_TLBI_VALE2OS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 1, 6), MISCREG_TLBI_VMALLS12E1OS },
|
||||
{ MiscRegNum64(1, 4, 8, 0, 6), MISCREG_TLBI_RIPAS2LE1IS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 2, 1), MISCREG_TLBI_RVAE2IS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 2, 5), MISCREG_TLBI_RVALE2IS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 3, 0), MISCREG_TLBI_ALLE2IS },
|
||||
{ MiscRegNum64(1, 4, 8, 3, 1), MISCREG_TLBI_VAE2IS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 3, 4), MISCREG_TLBI_ALLE1IS },
|
||||
@@ -796,8 +812,16 @@ std::unordered_map<MiscRegNum64, MiscRegIndex> miscRegNumToIdx{
|
||||
{ MiscRegNum64(1, 4, 8, 3, 6), MISCREG_TLBI_VMALLS12E1IS },
|
||||
{ MiscRegNum64(1, 4, 8, 4, 0), MISCREG_TLBI_IPAS2E1OS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 4, 1), MISCREG_TLBI_IPAS2E1_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 4, 2), MISCREG_TLBI_RIPAS2E1_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 4, 3), MISCREG_TLBI_RIPAS2E1OS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 4, 4), MISCREG_TLBI_IPAS2LE1OS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 4, 5), MISCREG_TLBI_IPAS2LE1_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 4, 6), MISCREG_TLBI_RIPAS2LE1_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 4, 7), MISCREG_TLBI_RIPAS2LE1OS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 5, 1), MISCREG_TLBI_RVAE2OS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 5, 5), MISCREG_TLBI_RVALE2OS_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 6, 1), MISCREG_TLBI_RVAE2_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 6, 5), MISCREG_TLBI_RVALE2_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 7, 0), MISCREG_TLBI_ALLE2 },
|
||||
{ MiscRegNum64(1, 4, 8, 7, 1), MISCREG_TLBI_VAE2_Xt },
|
||||
{ MiscRegNum64(1, 4, 8, 7, 4), MISCREG_TLBI_ALLE1 },
|
||||
@@ -808,9 +832,15 @@ std::unordered_map<MiscRegNum64, MiscRegIndex> miscRegNumToIdx{
|
||||
{ MiscRegNum64(1, 6, 8, 1, 0), MISCREG_TLBI_ALLE3OS },
|
||||
{ MiscRegNum64(1, 6, 8, 1, 1), MISCREG_TLBI_VAE3OS_Xt },
|
||||
{ MiscRegNum64(1, 6, 8, 1, 5), MISCREG_TLBI_VALE3OS_Xt },
|
||||
{ MiscRegNum64(1, 6, 8, 2, 1), MISCREG_TLBI_RVAE3IS_Xt },
|
||||
{ MiscRegNum64(1, 6, 8, 2, 5), MISCREG_TLBI_RVALE3IS_Xt },
|
||||
{ MiscRegNum64(1, 6, 8, 3, 0), MISCREG_TLBI_ALLE3IS },
|
||||
{ MiscRegNum64(1, 6, 8, 3, 1), MISCREG_TLBI_VAE3IS_Xt },
|
||||
{ MiscRegNum64(1, 6, 8, 3, 5), MISCREG_TLBI_VALE3IS_Xt },
|
||||
{ MiscRegNum64(1, 6, 8, 5, 1), MISCREG_TLBI_RVAE3OS_Xt },
|
||||
{ MiscRegNum64(1, 6, 8, 5, 5), MISCREG_TLBI_RVALE3OS_Xt },
|
||||
{ MiscRegNum64(1, 6, 8, 6, 1), MISCREG_TLBI_RVAE3_Xt },
|
||||
{ MiscRegNum64(1, 6, 8, 6, 5), MISCREG_TLBI_RVALE3_Xt },
|
||||
{ MiscRegNum64(1, 6, 8, 7, 0), MISCREG_TLBI_ALLE3 },
|
||||
{ MiscRegNum64(1, 6, 8, 7, 1), MISCREG_TLBI_VAE3_Xt },
|
||||
{ MiscRegNum64(1, 6, 8, 7, 5), MISCREG_TLBI_VALE3_Xt },
|
||||
@@ -4276,7 +4306,9 @@ ISA::initializeMiscRegMetadata()
|
||||
isar0_el1.atomic = release->has(ArmExtension::FEAT_LSE) ? 0x2 : 0x0;
|
||||
isar0_el1.rdm = release->has(ArmExtension::FEAT_RDM) ? 0x1 : 0x0;
|
||||
isar0_el1.tme = release->has(ArmExtension::TME) ? 0x1 : 0x0;
|
||||
isar0_el1.tlb = release->has(ArmExtension::FEAT_TLBIOS) ? 0x1 : 0x0;
|
||||
isar0_el1.tlb = release->has(ArmExtension::FEAT_TLBIRANGE) ?
|
||||
0x2 : release->has(ArmExtension::FEAT_TLBIOS) ?
|
||||
0x1 : 0x0;
|
||||
isar0_el1.ts = release->has(ArmExtension::FEAT_FLAGM2) ?
|
||||
0x2 : release->has(ArmExtension::FEAT_FLAGM) ?
|
||||
0x1 : 0x0;
|
||||
@@ -4889,6 +4921,79 @@ ISA::initializeMiscRegMetadata()
|
||||
.monSecureWrite().monNonSecureWrite();
|
||||
InitReg(MISCREG_TLBI_VALE3_Xt)
|
||||
.monSecureWrite().monNonSecureWrite();
|
||||
|
||||
InitReg(MISCREG_TLBI_RVAE1_Xt)
|
||||
.faultWrite(EL1, faultHcrFgtInstEL1<&HCR::ttlb, &HFGITR::tlbirvae1>)
|
||||
.writes(1).exceptUserMode();
|
||||
InitReg(MISCREG_TLBI_RVAAE1_Xt)
|
||||
.faultWrite(EL1, faultHcrFgtInstEL1<&HCR::ttlb, &HFGITR::tlbirvaae1>)
|
||||
.writes(1).exceptUserMode();
|
||||
InitReg(MISCREG_TLBI_RVALE1_Xt)
|
||||
.faultWrite(EL1, faultHcrFgtInstEL1<&HCR::ttlb, &HFGITR::tlbirvale1>)
|
||||
.writes(1).exceptUserMode();
|
||||
InitReg(MISCREG_TLBI_RVAALE1_Xt)
|
||||
.faultWrite(EL1, faultHcrFgtInstEL1<&HCR::ttlb, &HFGITR::tlbirvaale1>)
|
||||
.writes(1).exceptUserMode();
|
||||
InitReg(MISCREG_TLBI_RIPAS2E1_Xt)
|
||||
.hypWrite().monWrite();
|
||||
InitReg(MISCREG_TLBI_RIPAS2LE1_Xt)
|
||||
.hypWrite().monWrite();
|
||||
InitReg(MISCREG_TLBI_RVAE2_Xt)
|
||||
.hypWrite().monWrite();
|
||||
InitReg(MISCREG_TLBI_RVALE2_Xt)
|
||||
.hypWrite().monWrite();
|
||||
InitReg(MISCREG_TLBI_RVAE3_Xt)
|
||||
.monWrite();
|
||||
InitReg(MISCREG_TLBI_RVALE3_Xt)
|
||||
.monWrite();
|
||||
InitReg(MISCREG_TLBI_RVAE1IS_Xt)
|
||||
.faultWrite(EL1, faultTlbiIsEL1<&HFGITR::tlbirvae1is>)
|
||||
.writes(1).exceptUserMode();
|
||||
InitReg(MISCREG_TLBI_RVAAE1IS_Xt)
|
||||
.faultWrite(EL1, faultTlbiIsEL1<&HFGITR::tlbirvaae1is>)
|
||||
.writes(1).exceptUserMode();
|
||||
InitReg(MISCREG_TLBI_RVALE1IS_Xt)
|
||||
.faultWrite(EL1, faultTlbiIsEL1<&HFGITR::tlbirvale1is>)
|
||||
.writes(1).exceptUserMode();
|
||||
InitReg(MISCREG_TLBI_RVAALE1IS_Xt)
|
||||
.faultWrite(EL1, faultTlbiIsEL1<&HFGITR::tlbirvaale1is>)
|
||||
.writes(1).exceptUserMode();
|
||||
InitReg(MISCREG_TLBI_RIPAS2E1IS_Xt)
|
||||
.hypWrite().monWrite();
|
||||
InitReg(MISCREG_TLBI_RIPAS2LE1IS_Xt)
|
||||
.hypWrite().monWrite();
|
||||
InitReg(MISCREG_TLBI_RVAE2IS_Xt)
|
||||
.hypWrite().monWrite();
|
||||
InitReg(MISCREG_TLBI_RVALE2IS_Xt)
|
||||
.hypWrite().monWrite();
|
||||
InitReg(MISCREG_TLBI_RVAE3IS_Xt)
|
||||
.monWrite();
|
||||
InitReg(MISCREG_TLBI_RVALE3IS_Xt)
|
||||
.monWrite();
|
||||
InitReg(MISCREG_TLBI_RVAE1OS_Xt)
|
||||
.faultWrite(EL1, faultTlbiOsEL1<&HFGITR::tlbirvae1os>)
|
||||
.writes(1).exceptUserMode();
|
||||
InitReg(MISCREG_TLBI_RVAAE1OS_Xt)
|
||||
.faultWrite(EL1, faultTlbiOsEL1<&HFGITR::tlbirvaae1os>)
|
||||
.writes(1).exceptUserMode();
|
||||
InitReg(MISCREG_TLBI_RVALE1OS_Xt)
|
||||
.faultWrite(EL1, faultTlbiOsEL1<&HFGITR::tlbirvale1os>)
|
||||
.writes(1).exceptUserMode();
|
||||
InitReg(MISCREG_TLBI_RVAALE1OS_Xt)
|
||||
.faultWrite(EL1, faultTlbiOsEL1<&HFGITR::tlbirvaale1os>)
|
||||
.writes(1).exceptUserMode();
|
||||
InitReg(MISCREG_TLBI_RIPAS2E1OS_Xt)
|
||||
.hypWrite().monWrite();
|
||||
InitReg(MISCREG_TLBI_RIPAS2LE1OS_Xt)
|
||||
.hypWrite().monWrite();
|
||||
InitReg(MISCREG_TLBI_RVAE2OS_Xt)
|
||||
.hypWrite().monWrite();
|
||||
InitReg(MISCREG_TLBI_RVALE2OS_Xt)
|
||||
.hypWrite().monWrite();
|
||||
InitReg(MISCREG_TLBI_RVAE3OS_Xt)
|
||||
.monWrite();
|
||||
InitReg(MISCREG_TLBI_RVALE3OS_Xt)
|
||||
.monWrite();
|
||||
InitReg(MISCREG_PMINTENSET_EL1)
|
||||
.allPrivileges().exceptUserMode()
|
||||
.mapsTo(MISCREG_PMINTENSET);
|
||||
|
||||
@@ -729,6 +729,36 @@ namespace ArmISA
|
||||
MISCREG_TLBI_ALLE3,
|
||||
MISCREG_TLBI_VAE3_Xt,
|
||||
MISCREG_TLBI_VALE3_Xt,
|
||||
MISCREG_TLBI_RVAE1_Xt,
|
||||
MISCREG_TLBI_RVAAE1_Xt,
|
||||
MISCREG_TLBI_RVALE1_Xt,
|
||||
MISCREG_TLBI_RVAALE1_Xt,
|
||||
MISCREG_TLBI_RIPAS2E1_Xt,
|
||||
MISCREG_TLBI_RIPAS2LE1_Xt,
|
||||
MISCREG_TLBI_RVAE2_Xt,
|
||||
MISCREG_TLBI_RVALE2_Xt,
|
||||
MISCREG_TLBI_RVAE3_Xt,
|
||||
MISCREG_TLBI_RVALE3_Xt,
|
||||
MISCREG_TLBI_RVAE1IS_Xt,
|
||||
MISCREG_TLBI_RVAAE1IS_Xt,
|
||||
MISCREG_TLBI_RVALE1IS_Xt,
|
||||
MISCREG_TLBI_RVAALE1IS_Xt,
|
||||
MISCREG_TLBI_RIPAS2E1IS_Xt,
|
||||
MISCREG_TLBI_RIPAS2LE1IS_Xt,
|
||||
MISCREG_TLBI_RVAE2IS_Xt,
|
||||
MISCREG_TLBI_RVALE2IS_Xt,
|
||||
MISCREG_TLBI_RVAE3IS_Xt,
|
||||
MISCREG_TLBI_RVALE3IS_Xt,
|
||||
MISCREG_TLBI_RVAE1OS_Xt,
|
||||
MISCREG_TLBI_RVAAE1OS_Xt,
|
||||
MISCREG_TLBI_RVALE1OS_Xt,
|
||||
MISCREG_TLBI_RVAALE1OS_Xt,
|
||||
MISCREG_TLBI_RIPAS2E1OS_Xt,
|
||||
MISCREG_TLBI_RIPAS2LE1OS_Xt,
|
||||
MISCREG_TLBI_RVAE2OS_Xt,
|
||||
MISCREG_TLBI_RVALE2OS_Xt,
|
||||
MISCREG_TLBI_RVAE3OS_Xt,
|
||||
MISCREG_TLBI_RVALE3OS_Xt,
|
||||
MISCREG_PMINTENSET_EL1,
|
||||
MISCREG_PMINTENCLR_EL1,
|
||||
MISCREG_PMCR_EL0,
|
||||
@@ -1503,6 +1533,13 @@ namespace ArmISA
|
||||
return *this;
|
||||
}
|
||||
chain
|
||||
monWrite(bool v = true) const
|
||||
{
|
||||
monSecureWrite(v);
|
||||
monNonSecureWrite(v);
|
||||
return *this;
|
||||
}
|
||||
chain
|
||||
monSecure(bool v = true) const
|
||||
{
|
||||
monSecureRead(v);
|
||||
@@ -2411,6 +2448,36 @@ namespace ArmISA
|
||||
"tlbi_alle3",
|
||||
"tlbi_vae3_xt",
|
||||
"tlbi_vale3_xt",
|
||||
"tlbi_rvae1_xt",
|
||||
"tlbi_rvaae1_xt",
|
||||
"tlbi_rvale1_xt",
|
||||
"tlbi_rvaale1_xt",
|
||||
"tlbi_ripas2e1_xt",
|
||||
"tlbi_ripas2le1_xt",
|
||||
"tlbi_rvae2_xt",
|
||||
"tlbi_rvale2_xt",
|
||||
"tlbi_rvae3_xt",
|
||||
"tlbi_rvale3_xt",
|
||||
"tlbi_rvae1is_xt",
|
||||
"tlbi_rvaae1is_xt",
|
||||
"tlbi_rvale1is_xt",
|
||||
"tlbi_rvaale1is_xt",
|
||||
"tlbi_ripas2e1is_xt",
|
||||
"tlbi_ripas2le1is_xt",
|
||||
"tlbi_rvae2is_xt",
|
||||
"tlbi_rvale2is_xt",
|
||||
"tlbi_rvae3is_xt",
|
||||
"tlbi_rvale3is_xt",
|
||||
"tlbi_rvae1os_xt",
|
||||
"tlbi_rvaae1os_xt",
|
||||
"tlbi_rvale1os_xt",
|
||||
"tlbi_rvaale1os_xt",
|
||||
"tlbi_ripas2e1os_xt",
|
||||
"tlbi_ripas2le1os_xt",
|
||||
"tlbi_rvae2os_xt",
|
||||
"tlbi_rvale2os_xt",
|
||||
"tlbi_rvae3os_xt",
|
||||
"tlbi_rvale3os_xt",
|
||||
"pmintenset_el1",
|
||||
"pmintenclr_el1",
|
||||
"pmcr_el0",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2012-2019, 2021-2022 Arm Limited
|
||||
* Copyright (c) 2010, 2012-2019, 2021-2023 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -2305,6 +2305,7 @@ TableWalker::insertPartialTableEntry(LongDescriptor &descriptor)
|
||||
te.asid = currState->asid;
|
||||
te.vmid = currState->vmid;
|
||||
te.N = descriptor.offsetBits();
|
||||
te.tg = descriptor.grainSize;
|
||||
te.vpn = currState->vaddr >> te.N;
|
||||
te.size = (1ULL << te.N) - 1;
|
||||
te.pfn = descriptor.nextTableAddr();
|
||||
@@ -2378,6 +2379,7 @@ TableWalker::insertTableEntry(DescriptorBase &descriptor, bool long_descriptor)
|
||||
LongDescriptor l_descriptor =
|
||||
dynamic_cast<LongDescriptor &>(descriptor);
|
||||
|
||||
te.tg = l_descriptor.grainSize;
|
||||
te.xn |= currState->xnTable;
|
||||
te.pxn = currState->pxnTable || l_descriptor.pxn();
|
||||
if (isStage2) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2022 Arm Limited
|
||||
* Copyright (c) 2018-2023 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -209,6 +209,22 @@ TLBIALLN::match(TlbEntry* te, vmid_t vmid) const
|
||||
te->checkELMatch(targetEL, false);
|
||||
}
|
||||
|
||||
TlbEntry::Lookup
|
||||
TLBIMVAA::lookupGen(vmid_t vmid) const
|
||||
{
|
||||
TlbEntry::Lookup lookup_data;
|
||||
lookup_data.va = sext<56>(addr);
|
||||
lookup_data.ignoreAsn = true;
|
||||
lookup_data.vmid = vmid;
|
||||
lookup_data.hyp = targetEL == EL2;
|
||||
lookup_data.secure = secureLookup;
|
||||
lookup_data.functional = true;
|
||||
lookup_data.targetEL = targetEL;
|
||||
lookup_data.inHost = inHost;
|
||||
lookup_data.mode = BaseMMU::Read;
|
||||
return lookup_data;
|
||||
}
|
||||
|
||||
void
|
||||
TLBIMVAA::operator()(ThreadContext* tc)
|
||||
{
|
||||
@@ -224,10 +240,19 @@ TLBIMVAA::operator()(ThreadContext* tc)
|
||||
|
||||
bool
|
||||
TLBIMVAA::match(TlbEntry* te, vmid_t vmid) const
|
||||
{
|
||||
TlbEntry::Lookup lookup_data = lookupGen(vmid);
|
||||
|
||||
return te->match(lookup_data) && (!lastLevel || !te->partial);
|
||||
}
|
||||
|
||||
TlbEntry::Lookup
|
||||
TLBIMVA::lookupGen(vmid_t vmid) const
|
||||
{
|
||||
TlbEntry::Lookup lookup_data;
|
||||
lookup_data.va = sext<56>(addr);
|
||||
lookup_data.ignoreAsn = true;
|
||||
lookup_data.asn = asid;
|
||||
lookup_data.ignoreAsn = false;
|
||||
lookup_data.vmid = vmid;
|
||||
lookup_data.hyp = targetEL == EL2;
|
||||
lookup_data.secure = secureLookup;
|
||||
@@ -236,7 +261,7 @@ TLBIMVAA::match(TlbEntry* te, vmid_t vmid) const
|
||||
lookup_data.inHost = inHost;
|
||||
lookup_data.mode = BaseMMU::Read;
|
||||
|
||||
return te->match(lookup_data) && (!lastLevel || !te->partial);
|
||||
return lookup_data;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -255,17 +280,7 @@ TLBIMVA::operator()(ThreadContext* tc)
|
||||
bool
|
||||
TLBIMVA::match(TlbEntry* te, vmid_t vmid) const
|
||||
{
|
||||
TlbEntry::Lookup lookup_data;
|
||||
lookup_data.va = sext<56>(addr);
|
||||
lookup_data.asn = asid;
|
||||
lookup_data.ignoreAsn = false;
|
||||
lookup_data.vmid = vmid;
|
||||
lookup_data.hyp = targetEL == EL2;
|
||||
lookup_data.secure = secureLookup;
|
||||
lookup_data.functional = true;
|
||||
lookup_data.targetEL = targetEL;
|
||||
lookup_data.inHost = inHost;
|
||||
lookup_data.mode = BaseMMU::Read;
|
||||
TlbEntry::Lookup lookup_data = lookupGen(vmid);
|
||||
|
||||
return te->match(lookup_data) && (!lastLevel || !te->partial);
|
||||
}
|
||||
@@ -305,5 +320,37 @@ TLBIIPA::operator()(ThreadContext* tc)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TLBIRMVA::match(TlbEntry* te, vmid_t vmid) const
|
||||
{
|
||||
TlbEntry::Lookup lookup_data = lookupGen(vmid);
|
||||
lookup_data.size = rangeSize();
|
||||
|
||||
auto addr_match = te->match(lookup_data) && (!lastLevel || !te->partial);
|
||||
if (addr_match) {
|
||||
return tgMap[rangeData.tg] == te->tg &&
|
||||
(resTLBIttl(rangeData.tg, rangeData.ttl) ||
|
||||
rangeData.ttl == te->lookupLevel);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TLBIRMVAA::match(TlbEntry* te, vmid_t vmid) const
|
||||
{
|
||||
TlbEntry::Lookup lookup_data = lookupGen(vmid);
|
||||
lookup_data.size = rangeSize();
|
||||
|
||||
auto addr_match = te->match(lookup_data) && (!lastLevel || !te->partial);
|
||||
if (addr_match) {
|
||||
return tgMap[rangeData.tg] == te->tg &&
|
||||
(resTLBIttl(rangeData.tg, rangeData.ttl) ||
|
||||
rangeData.ttl == te->lookupLevel);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ArmISA
|
||||
} // namespace gem5
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020, 2022 Arm Limited
|
||||
* Copyright (c) 2018-2020, 2022-2023 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -300,6 +300,8 @@ class TLBIALLN : public TLBIOp
|
||||
/** TLB Invalidate by VA, All ASID */
|
||||
class TLBIMVAA : public TLBIOp
|
||||
{
|
||||
protected:
|
||||
TlbEntry::Lookup lookupGen(vmid_t vmid) const;
|
||||
public:
|
||||
TLBIMVAA(ExceptionLevel _targetEL, bool _secure,
|
||||
Addr _addr, bool last_level)
|
||||
@@ -319,6 +321,9 @@ class TLBIMVAA : public TLBIOp
|
||||
/** TLB Invalidate by VA */
|
||||
class TLBIMVA : public TLBIOp
|
||||
{
|
||||
protected:
|
||||
TlbEntry::Lookup lookupGen(vmid_t vmid) const;
|
||||
|
||||
public:
|
||||
TLBIMVA(ExceptionLevel _targetEL, bool _secure,
|
||||
Addr _addr, uint16_t _asid, bool last_level)
|
||||
@@ -368,6 +373,61 @@ class DTLBIMVA : public TLBIMVA
|
||||
bool match(TlbEntry *entry, vmid_t curr_vmid) const override;
|
||||
};
|
||||
|
||||
class TLBIRange
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Is the range valid? This mainly depends on the specified
|
||||
* translation granule.
|
||||
*/
|
||||
bool valid() const { return granule != ReservedGrain; }
|
||||
|
||||
protected:
|
||||
BitUnion64(RangeData)
|
||||
Bitfield<47, 46> tg;
|
||||
Bitfield<45, 44> scale;
|
||||
Bitfield<43, 39> num;
|
||||
Bitfield<38, 37> ttl;
|
||||
Bitfield<36, 0> baseAddr;
|
||||
EndBitUnion(RangeData)
|
||||
|
||||
static constexpr std::array<GrainSize, 4> tgMap = {
|
||||
ReservedGrain,
|
||||
Grain4KB,
|
||||
Grain16KB,
|
||||
Grain64KB
|
||||
};
|
||||
|
||||
TLBIRange(RegVal val)
|
||||
: rangeData(val), granule(tgMap[rangeData.tg])
|
||||
{}
|
||||
|
||||
Addr
|
||||
startAddress() const
|
||||
{
|
||||
return sext<37>(rangeData.baseAddr) << granule;
|
||||
}
|
||||
|
||||
Addr
|
||||
rangeSize() const
|
||||
{
|
||||
return (rangeData.num + 1) << (5 * rangeData.scale + 1 + granule);
|
||||
}
|
||||
|
||||
bool
|
||||
resTLBIttl(uint8_t tg, uint8_t ttl) const
|
||||
{
|
||||
switch (ttl) {
|
||||
case 0: return true;
|
||||
case 1: return tgMap[tg] == Grain16KB;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
RangeData rangeData;
|
||||
GrainSize granule;
|
||||
};
|
||||
|
||||
/** TLB Invalidate by Intermediate Physical Address */
|
||||
class TLBIIPA : public TLBIOp
|
||||
{
|
||||
@@ -392,7 +452,7 @@ class TLBIIPA : public TLBIOp
|
||||
}
|
||||
|
||||
/** TLBIIPA is basically a TLBIMVAA for stage2 TLBs */
|
||||
TLBIMVAA
|
||||
virtual TLBIMVAA
|
||||
makeStage2() const
|
||||
{
|
||||
return TLBIMVAA(EL1, secureLookup, addr, lastLevel);
|
||||
@@ -402,6 +462,49 @@ class TLBIIPA : public TLBIOp
|
||||
bool lastLevel;
|
||||
};
|
||||
|
||||
/** TLB Range Invalidate by VA */
|
||||
class TLBIRMVA : public TLBIRange, public TLBIMVA
|
||||
{
|
||||
public:
|
||||
TLBIRMVA(ExceptionLevel _targetEL, bool _secure,
|
||||
RegVal val, uint16_t _asid, bool last_level)
|
||||
: TLBIRange(val),
|
||||
TLBIMVA(_targetEL, _secure, startAddress(), _asid, last_level)
|
||||
{}
|
||||
|
||||
bool match(TlbEntry *entry, vmid_t curr_vmid) const override;
|
||||
};
|
||||
|
||||
/** TLB Range Invalidate by VA, All ASIDs */
|
||||
class TLBIRMVAA : public TLBIRange, public TLBIMVAA
|
||||
{
|
||||
public:
|
||||
TLBIRMVAA(ExceptionLevel _targetEL, bool _secure,
|
||||
RegVal val, bool last_level)
|
||||
: TLBIRange(val),
|
||||
TLBIMVAA(_targetEL, _secure, startAddress(), last_level)
|
||||
{}
|
||||
|
||||
bool match(TlbEntry *entry, vmid_t curr_vmid) const override;
|
||||
};
|
||||
|
||||
/** TLB Range Invalidate by VA, All ASIDs */
|
||||
class TLBIRIPA : public TLBIRange, public TLBIIPA
|
||||
{
|
||||
public:
|
||||
TLBIRIPA(ExceptionLevel _targetEL, bool _secure,
|
||||
RegVal val, bool last_level)
|
||||
: TLBIRange(val),
|
||||
TLBIIPA(_targetEL, _secure, startAddress(), last_level)
|
||||
{}
|
||||
|
||||
virtual TLBIMVAA
|
||||
makeStage2() const
|
||||
{
|
||||
return TLBIRMVAA(EL1, secureLookup, rangeData, lastLevel);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ArmISA
|
||||
} // namespace gem5
|
||||
|
||||
|
||||
@@ -366,6 +366,12 @@ void syncVecElemsToRegs(ThreadContext *tc);
|
||||
|
||||
bool fgtEnabled(ThreadContext *tc);
|
||||
|
||||
static inline bool
|
||||
useVMID(ExceptionLevel el, bool in_host)
|
||||
{
|
||||
return el == EL1 || (el == EL0 && !in_host);
|
||||
}
|
||||
|
||||
} // namespace ArmISA
|
||||
} // namespace gem5
|
||||
|
||||
|
||||
Reference in New Issue
Block a user