arch-arm: Define system registers for FEAT_MPAM

This patch is adding FEAT_MPAM register definition/decoding.

Co-authored-by: Hristo Belchev <hristo.belchev@arm.com>
Co-authored-by: Giacomo Travaglini <giacomo.travaglini@arm.com>

Change-Id: I70483fcc758419365f4b3762479684c6c52f4d62
Signed-off-by: Adrián Herrera <adrian.herrera@arm.com>
Reviewed-by: Richard Cooper <richard.cooper@arm.com>
This commit is contained in:
Adrián Herrera
2021-04-02 15:39:30 +01:00
committed by Giacomo Travaglini
parent 65cf6b0a1c
commit c988642ca8
7 changed files with 333 additions and 10 deletions

View File

@@ -170,6 +170,10 @@ class ArmISA(BaseISA):
0x0000000000010010, "AArch64 Memory Model Feature Register 2"
)
# HAS_SDEFLT | HAS_FORCE_NS | HAS_TIDR | PMG_MAX = 64 |
# VPMR_MAX = 7 | HAS_HCR | PARTID_MAX = 256
mpamidr_el1 = Param.UInt64(0x34000040001E0100, "MPAM ID Register (EL1)")
# Any access (read/write) to an unimplemented
# Implementation Defined registers is not causing an Undefined Instruction.
# It is rather executed as a NOP.

View File

@@ -115,6 +115,7 @@ class ArmExtension(ScopedEnum):
"LPAE",
"VIRTUALIZATION",
"TME",
"FEAT_MPAM",
]

View File

@@ -44,6 +44,7 @@
#include "arch/arm/mmu.hh"
#include "arch/arm/pmu.hh"
#include "arch/arm/regs/misc.hh"
#include "arch/arm/regs/misc_accessors.hh"
#include "arch/arm/self_debug.hh"
#include "arch/arm/system.hh"
#include "arch/arm/utility.hh"
@@ -72,6 +73,8 @@ namespace gem5
namespace ArmISA
{
using namespace misc_regs;
namespace
{
@@ -269,6 +272,8 @@ ISA::redirectRegVHE(int misc_reg)
return currEL() == EL2 ? MISCREG_CONTEXTIDR_EL2 : misc_reg;
case MISCREG_CNTKCTL_EL1:
return currEL() == EL2 ? MISCREG_CNTHCTL_EL2 : misc_reg;
case MISCREG_MPAM1_EL1:
return currEL() == EL2 ? MISCREG_MPAM2_EL2 : misc_reg;
case MISCREG_CNTP_TVAL:
case MISCREG_CNTP_TVAL_EL0:
if (ELIsInHost(tc, currEL())) {
@@ -358,6 +363,8 @@ ISA::redirectRegVHE(int misc_reg)
return MISCREG_CONTEXTIDR_EL1;
case MISCREG_CNTKCTL_EL12:
return MISCREG_CNTKCTL_EL1;
case MISCREG_MPAM1_EL12:
return MISCREG_MPAM1_EL1;
// _EL02 registers
case MISCREG_CNTP_TVAL_EL02:
return MISCREG_CNTP_TVAL_EL0;
@@ -602,6 +609,23 @@ ISA::readMiscReg(RegIndex idx)
case MISCREG_HIFAR: // alias for secure IFAR
return readMiscRegNoEffect(MISCREG_IFAR_S);
case MISCREG_MPAM1_EL1:
{
MPAM mpam1 = readMiscRegNoEffect(MISCREG_MPAM1_EL1);
mpam1.mpamEn = readRegisterNoEffect<MpamAccessor>(
tc, highestEL).mpamEn;
mpam1.el1.forcedNs = isSecure(tc) ?
readRegisterNoEffect<MpamAccessor>(tc, EL3).el3.forceNs : 0;
return mpam1;
}
case MISCREG_MPAM2_EL2:
{
MPAM mpam2 = readMiscRegNoEffect(MISCREG_MPAM2_EL2);
mpam2.mpamEn = readRegisterNoEffect<MpamAccessor>(
tc, highestEL).mpamEn;
return mpam2;
}
case MISCREG_RNDR:
tc->setReg(cc_reg::Nz, (RegVal)0);
tc->setReg(cc_reg::C, (RegVal)0);
@@ -733,8 +757,8 @@ ISA::setMiscReg(RegIndex idx, RegVal val)
const uint32_t ones = (uint32_t)(-1);
CPACR cpacrMask = 0;
// Only cp10, cp11, and ase are implemented, nothing else should
// be writable
// Only cp10, cp11, and ase are implemented
// nothing else should be writable
cpacrMask.cp10 = ones;
cpacrMask.cp11 = ones;
cpacrMask.asedis = ones;

View File

@@ -41,11 +41,12 @@
#include "arch/arm/insts/misc64.hh"
#include "arch/arm/isa.hh"
#include "base/bitfield.hh"
#include "base/logging.hh"
#include "cpu/thread_context.hh"
#include "dev/arm/gic_v3_cpu_interface.hh"
#include "sim/full_system.hh"
#include "params/ArmISA.hh"
#include "sim/full_system.hh"
namespace gem5
{
@@ -735,7 +736,6 @@ checkFaultAccessAArch64SysReg(MiscRegIndex reg, CPSR cpsr,
std::vector<struct MiscRegLUTEntry> lookUpMiscReg(NUM_MISCREGS);
namespace {
// The map is translating a MiscRegIndex into AArch64 system register
// numbers (op0, op1, crn, crm, op2)
std::unordered_map<MiscRegIndex, MiscRegNum64> idxToMiscRegNum;
@@ -1032,6 +1032,9 @@ std::unordered_map<MiscRegNum64, MiscRegIndex> miscRegNumToIdx{
{ MiscRegNum64(3, 0, 9, 14, 2), MISCREG_PMINTENCLR_EL1 },
{ MiscRegNum64(3, 0, 10, 2, 0), MISCREG_MAIR_EL1 },
{ MiscRegNum64(3, 0, 10, 3, 0), MISCREG_AMAIR_EL1 },
{ MiscRegNum64(3, 0, 10, 4, 4), MISCREG_MPAMIDR_EL1 },
{ MiscRegNum64(3, 0, 10, 5, 0), MISCREG_MPAM1_EL1 },
{ MiscRegNum64(3, 0, 10, 5, 1), MISCREG_MPAM0_EL1 },
{ MiscRegNum64(3, 0, 10, 5, 3), MISCREG_MPAMSM_EL1 },
{ MiscRegNum64(3, 0, 12, 0, 0), MISCREG_VBAR_EL1 },
{ MiscRegNum64(3, 0, 12, 0, 1), MISCREG_RVBAR_EL1 },
@@ -1181,6 +1184,17 @@ std::unordered_map<MiscRegNum64, MiscRegIndex> miscRegNumToIdx{
{ MiscRegNum64(3, 4, 6, 0, 4), MISCREG_HPFAR_EL2 },
{ MiscRegNum64(3, 4, 10, 2, 0), MISCREG_MAIR_EL2 },
{ MiscRegNum64(3, 4, 10, 3, 0), MISCREG_AMAIR_EL2 },
{ MiscRegNum64(3, 4, 10, 4, 0), MISCREG_MPAMHCR_EL2 },
{ MiscRegNum64(3, 4, 10, 4, 1), MISCREG_MPAMVPMV_EL2 },
{ MiscRegNum64(3, 4, 10, 5, 0), MISCREG_MPAM2_EL2 },
{ MiscRegNum64(3, 4, 10, 6, 0), MISCREG_MPAMVPM0_EL2 },
{ MiscRegNum64(3, 4, 10, 6, 1), MISCREG_MPAMVPM1_EL2 },
{ MiscRegNum64(3, 4, 10, 6, 2), MISCREG_MPAMVPM2_EL2 },
{ MiscRegNum64(3, 4, 10, 6, 3), MISCREG_MPAMVPM3_EL2 },
{ MiscRegNum64(3, 4, 10, 6, 4), MISCREG_MPAMVPM4_EL2 },
{ MiscRegNum64(3, 4, 10, 6, 5), MISCREG_MPAMVPM5_EL2 },
{ MiscRegNum64(3, 4, 10, 6, 6), MISCREG_MPAMVPM6_EL2 },
{ MiscRegNum64(3, 4, 10, 6, 7), MISCREG_MPAMVPM7_EL2 },
{ MiscRegNum64(3, 4, 12, 0, 0), MISCREG_VBAR_EL2 },
{ MiscRegNum64(3, 4, 12, 0, 1), MISCREG_RVBAR_EL2 },
{ MiscRegNum64(3, 4, 12, 1, 1), MISCREG_VDISR_EL2 },
@@ -1248,6 +1262,7 @@ std::unordered_map<MiscRegNum64, MiscRegIndex> miscRegNumToIdx{
{ MiscRegNum64(3, 5, 6, 0, 0), MISCREG_FAR_EL12 },
{ MiscRegNum64(3, 5, 10, 2, 0), MISCREG_MAIR_EL12 },
{ MiscRegNum64(3, 5, 10, 3, 0), MISCREG_AMAIR_EL12 },
{ MiscRegNum64(3, 5, 10, 5, 0), MISCREG_MPAM1_EL12 },
{ MiscRegNum64(3, 5, 12, 0, 0), MISCREG_VBAR_EL12 },
{ MiscRegNum64(3, 5, 13, 0, 1), MISCREG_CONTEXTIDR_EL12 },
{ MiscRegNum64(3, 5, 14, 1, 0), MISCREG_CNTKCTL_EL12 },
@@ -1277,6 +1292,7 @@ std::unordered_map<MiscRegNum64, MiscRegIndex> miscRegNumToIdx{
{ MiscRegNum64(3, 6, 6, 0, 0), MISCREG_FAR_EL3 },
{ MiscRegNum64(3, 6, 10, 2, 0), MISCREG_MAIR_EL3 },
{ MiscRegNum64(3, 6, 10, 3, 0), MISCREG_AMAIR_EL3 },
{ MiscRegNum64(3, 6, 10, 5, 0), MISCREG_MPAM3_EL3 },
{ MiscRegNum64(3, 6, 12, 0, 0), MISCREG_VBAR_EL3 },
{ MiscRegNum64(3, 6, 12, 0, 1), MISCREG_RVBAR_EL3 },
{ MiscRegNum64(3, 6, 12, 0, 2), MISCREG_RMR_EL3 },
@@ -2620,6 +2636,113 @@ faultIdst(const MiscRegLUTEntry &entry,
}
}
Fault
faultMpamIdrEL1(const MiscRegLUTEntry &entry,
ThreadContext *tc, const MiscRegOp64 &inst)
{
if (HaveExt(tc, ArmExtension::FEAT_MPAM)) {
MPAM mpam2 = tc->readMiscReg(MISCREG_MPAM2_EL2);
MPAM mpam3 = tc->readMiscReg(MISCREG_MPAM3_EL3);
MPAMIDR mpamidr = tc->readMiscReg(MISCREG_MPAMIDR_EL1);
MPAMHCR mpamhcr = tc->readMiscReg(MISCREG_MPAMHCR_EL2);
if (ArmSystem::haveEL(tc, EL3) && mpam3.el3.trapLower) {
return inst.generateTrap(EL3);
} else if (EL2Enabled(tc) && mpamidr.hasHcr && mpamhcr.trapMpamIdrEL1) {
return inst.generateTrap(EL2);
} else if (EL2Enabled(tc) && mpamidr.hasTidr && mpam2.el2.tidr) {
return inst.generateTrap(EL2);
} else {
return NoFault;
}
} else {
return inst.undefined();
}
}
Fault
faultMpam0EL1(const MiscRegLUTEntry &entry,
ThreadContext *tc, const MiscRegOp64 &inst)
{
if (HaveExt(tc, ArmExtension::FEAT_MPAM)) {
MPAM mpam2 = tc->readMiscReg(MISCREG_MPAM2_EL2);
MPAM mpam3 = tc->readMiscReg(MISCREG_MPAM3_EL3);
if (ArmSystem::haveEL(tc, EL3) && mpam3.el3.trapLower) {
return inst.generateTrap(EL3);
} else if (EL2Enabled(tc) && mpam2.el2.trapMpam0EL1) {
return inst.generateTrap(EL2);
} else {
return NoFault;
}
} else {
return inst.undefined();
}
}
Fault
faultMpam1EL1(const MiscRegLUTEntry &entry,
ThreadContext *tc, const MiscRegOp64 &inst)
{
if (HaveExt(tc, ArmExtension::FEAT_MPAM)) {
MPAM mpam2 = tc->readMiscReg(MISCREG_MPAM2_EL2);
MPAM mpam3 = tc->readMiscReg(MISCREG_MPAM3_EL3);
if (ArmSystem::haveEL(tc, EL3) && mpam3.el3.trapLower) {
return inst.generateTrap(EL3);
} else if (EL2Enabled(tc) && mpam2.el2.trapMpam1EL1) {
return inst.generateTrap(EL2);
} else {
return NoFault;
}
} else {
return inst.undefined();
}
}
Fault
faultMpamEL2(const MiscRegLUTEntry &entry,
ThreadContext *tc, const MiscRegOp64 &inst)
{
if (HaveExt(tc, ArmExtension::FEAT_MPAM)) {
MPAM mpam3 = tc->readMiscReg(MISCREG_MPAM3_EL3);
if (ArmSystem::haveEL(tc, EL3) && mpam3.el3.trapLower) {
return inst.generateTrap(EL3);
} else {
return NoFault;
}
} else {
return inst.undefined();
}
}
Fault
faultMpam12EL2(const MiscRegLUTEntry &entry,
ThreadContext *tc, const MiscRegOp64 &inst)
{
if (ELIsInHost(tc, EL2)) {
return faultMpamEL2(entry, tc, inst);
} else {
return inst.undefined();
}
}
Fault
faultMpamsmEL1(const MiscRegLUTEntry &entry,
ThreadContext *tc, const MiscRegOp64 &inst)
{
if (HaveExt(tc, ArmExtension::FEAT_MPAM)) {
MPAM mpam2 = tc->readMiscReg(MISCREG_MPAM2_EL2);
MPAM mpam3 = tc->readMiscReg(MISCREG_MPAM3_EL3);
if (ArmSystem::haveEL(tc, EL3) && mpam3.el3.trapLower) {
return inst.generateTrap(EL3);
} else if (EL2Enabled(tc) && mpam2.el2.enMpamSm) {
return inst.generateTrap(EL2);
} else {
return NoFault;
}
} else {
return inst.undefined();
}
}
}
MiscRegIndex
@@ -4567,10 +4690,14 @@ ISA::initializeMiscRegMetadata()
AA64PFR0 pfr0_el1 = 0;
pfr0_el1.el0 = 0x2;
pfr0_el1.el1 = 0x2;
pfr0_el1.el2 = release->has(ArmExtension::VIRTUALIZATION) ? 0x2 : 0x0;
pfr0_el1.el2 = release->has(ArmExtension::VIRTUALIZATION)
? 0x2 : 0x0;
pfr0_el1.el3 = release->has(ArmExtension::SECURITY) ? 0x2 : 0x0;
pfr0_el1.sve = release->has(ArmExtension::FEAT_SVE) ? 0x1 : 0x0;
pfr0_el1.sel2 = release->has(ArmExtension::FEAT_SEL2) ? 0x1 : 0x0;
// See MPAM frac in MISCREG_ID_AA64PFR1_EL1. Currently supporting
// MPAMv0p1
pfr0_el1.mpam = 0x0;
pfr0_el1.gic = FullSystem && getGICv3CPUInterface(tc) ? 0x1 : 0;
return pfr0_el1;
}())
@@ -4579,8 +4706,13 @@ ISA::initializeMiscRegMetadata()
.faultRead(EL1, faultHcrEL1<&HCR::tid3>)
.allPrivileges().writes(0);
InitReg(MISCREG_ID_AA64PFR1_EL1)
.reset(release->has(ArmExtension::FEAT_SME) ?
0x1 << 24 : 0)
.reset([release=release](){
AA64PFR1 pfr1_el1 = 0;
pfr1_el1.sme = release->has(ArmExtension::FEAT_SME) ? 0x1 : 0x0;
pfr1_el1.mpamFrac = release->has(ArmExtension::FEAT_MPAM) ?
0x1 : 0x0;
return pfr1_el1;
}())
.unserialize(0)
.faultRead(EL0, faultIdst)
.faultRead(EL1, faultHcrEL1<&HCR::tid3>)
@@ -6314,8 +6446,6 @@ ISA::initializeMiscRegMetadata()
.allPrivileges().exceptUserMode();
InitReg(MISCREG_TPIDR2_EL0)
.allPrivileges();
InitReg(MISCREG_MPAMSM_EL1)
.allPrivileges().exceptUserMode();
InitReg(MISCREG_RNDR)
.faultRead(EL0, faultRng)
@@ -6396,6 +6526,73 @@ ISA::initializeMiscRegMetadata()
.warnNotFail()
.fault(faultUnimplemented);
// MPAM extension
InitReg(MISCREG_MPAMIDR_EL1)
.reset(p.mpamidr_el1)
.res0(mask(63, 62) | mask(56, 40) | mask(31, 21) | mask(16, 16))
.faultRead(EL1, faultMpamIdrEL1)
.faultRead(EL2, faultMpamEL2)
.allPrivileges().exceptUserMode().writes(0);
InitReg(MISCREG_MPAM0_EL1)
.res0(mask(63, 48))
.fault(EL1, faultMpam0EL1)
.fault(EL2, faultMpamEL2)
.priv().hyp().mon();
InitReg(MISCREG_MPAM1_EL1)
.res0(mask(62, 61) | mask(59, 48))
.fault(EL1, faultMpam1EL1)
.fault(EL2, faultMpamEL2)
.priv().hyp().mon();
InitReg(MISCREG_MPAM1_EL12)
.res0(mask(59, 48))
.fault(EL2, faultMpam12EL2)
.fault(EL3, defaultFaultE2H_EL3)
.hyp().mon();
InitReg(MISCREG_MPAM2_EL2)
.res0(mask(62, 59) | mask(57, 50))
.fault(EL2, faultMpamEL2)
.hyp().mon();
InitReg(MISCREG_MPAMHCR_EL2)
.res0(mask(63, 32) | mask(30, 9) | mask(7, 2))
.fault(EL2, faultMpamEL2)
.hyp().mon();
InitReg(MISCREG_MPAMVPM0_EL2)
.fault(EL2, faultMpamEL2)
.hyp().mon();
InitReg(MISCREG_MPAMVPM1_EL2)
.fault(EL2, faultMpamEL2)
.hyp().mon();
InitReg(MISCREG_MPAMVPM2_EL2)
.fault(EL2, faultMpamEL2)
.hyp().mon();
InitReg(MISCREG_MPAMVPM3_EL2)
.fault(EL2, faultMpamEL2)
.hyp().mon();
InitReg(MISCREG_MPAMVPM4_EL2)
.fault(EL2, faultMpamEL2)
.hyp().mon();
InitReg(MISCREG_MPAMVPM5_EL2)
.fault(EL2, faultMpamEL2)
.hyp().mon();
InitReg(MISCREG_MPAMVPM6_EL2)
.fault(EL2, faultMpamEL2)
.hyp().mon();
InitReg(MISCREG_MPAMVPM7_EL2)
.fault(EL2, faultMpamEL2)
.hyp().mon();
InitReg(MISCREG_MPAMVPMV_EL2)
.res0(mask(63, 32))
.fault(EL2, faultMpamEL2)
.hyp().mon();
InitReg(MISCREG_MPAM3_EL3)
.res0(mask(59, 48))
.mon();
InitReg(MISCREG_MPAMSM_EL1)
.res0(mask(63, 48) | mask(39, 32) | mask(15, 0))
.fault(EL1, faultMpamsmEL1)
.fault(EL2, faultMpamEL2)
.allPrivileges().exceptUserMode();
// Register mappings for some unimplemented registers:
// ESR_EL1 -> DFSR
// RMR_EL1 -> RMR

View File

@@ -1142,6 +1142,24 @@ namespace ArmISA
MISCREG_HDFGRTR_EL2,
MISCREG_HDFGWTR_EL2,
// FEAT_MPAM
MISCREG_MPAMIDR_EL1,
MISCREG_MPAM0_EL1,
MISCREG_MPAM1_EL1,
MISCREG_MPAM2_EL2,
MISCREG_MPAM3_EL3,
MISCREG_MPAM1_EL12,
MISCREG_MPAMHCR_EL2,
MISCREG_MPAMVPMV_EL2,
MISCREG_MPAMVPM0_EL2,
MISCREG_MPAMVPM1_EL2,
MISCREG_MPAMVPM2_EL2,
MISCREG_MPAMVPM3_EL2,
MISCREG_MPAMVPM4_EL2,
MISCREG_MPAMVPM5_EL2,
MISCREG_MPAMVPM6_EL2,
MISCREG_MPAMVPM7_EL2,
// NUM_PHYS_MISCREGS specifies the number of actual physical
// registers, not considering the following pseudo-registers
// (dummy registers), like MISCREG_UNKNOWN, MISCREG_IMPDEF_UNIMPL.
@@ -2859,6 +2877,24 @@ namespace ArmISA
"hdfgrtr_el2",
"hdfgwtr_el2",
// FEAT_MPAM
"mpamidr_el1",
"mpam0_el1",
"mpam1_el1",
"mpam2_el2",
"mpam3_el3",
"mpam1_el12",
"mpamhcr_el2",
"mpamvpmv_el2",
"mpamvpm0_el2",
"mpamvpm1_el2",
"mpamvpm2_el2",
"mpamvpm3_el2",
"mpamvpm4_el2",
"mpamvpm5_el2",
"mpamvpm6_el2",
"mpamvpm7_el2",
"num_phys_regs",
// Dummy registers

View File

@@ -59,6 +59,15 @@ struct FarAccessor
static const MiscRegIndex el3 = MISCREG_FAR_EL3;
};
struct MpamAccessor
{
using type = MPAM;
static const MiscRegIndex el0 = MISCREG_MPAM0_EL1;
static const MiscRegIndex el1 = MISCREG_MPAM1_EL1;
static const MiscRegIndex el2 = MISCREG_MPAM2_EL2;
static const MiscRegIndex el3 = MISCREG_MPAM3_EL3;
};
template <typename RegAccessor>
MiscRegIndex
getRegVersion(ExceptionLevel el)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2023 Arm Limited
* Copyright (c) 2010-2024 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -226,6 +226,11 @@ namespace ArmISA
Bitfield<3, 0> el0;
EndBitUnion(AA64PFR0)
BitUnion64(AA64PFR1)
Bitfield<27, 24> sme;
Bitfield<19, 16> mpamFrac;
EndBitUnion(AA64PFR1)
BitUnion64(AA64ZFR0)
Bitfield<59, 56> f64mm;
Bitfield<55, 52> f32mm;
@@ -1085,6 +1090,53 @@ namespace ArmISA
Bitfield<14> tcr2En;
EndBitUnion(HCRX)
BitUnion64(MPAMIDR)
Bitfield<61> hasSdeflt;
Bitfield<60> hasForceNs;
Bitfield<58> hasTidr;
Bitfield<39,32> pmgMax;
Bitfield<20,18> vpmrMax;
Bitfield<17> hasHcr;
Bitfield<15,0> partidMax;
EndBitUnion(MPAMIDR)
// Generic view of MPAMx_ELy
BitUnion64(MPAM)
Bitfield<63> mpamEn;
// MPAM1_EL1 only
SubBitUnion(el1, 62, 48)
Bitfield<60> forcedNs;
EndSubBitUnion(el1)
// MPAM2_EL2 only
SubBitUnion(el2, 62, 48)
Bitfield<58> tidr;
Bitfield<50> enMpamSm;
Bitfield<49> trapMpam0EL1;
Bitfield<48> trapMpam1EL1;
EndSubBitUnion(el2)
// MPAM3_EL3 only
SubBitUnion(el3, 62, 48)
Bitfield<62> trapLower;
Bitfield<61> sdeflt;
Bitfield<60> forceNs;
EndSubBitUnion(el3)
Bitfield<47,40> pmgD;
Bitfield<39,32> pmgI;
Bitfield<31,16> partidD;
Bitfield<15,0> partidI;
EndBitUnion(MPAM)
BitUnion64(MPAMHCR)
Bitfield<31> trapMpamIdrEL1;
Bitfield<8> gstappPlk;
Bitfield<1> el1Vpmen;
Bitfield<0> el0Vpmen;
EndBitUnion(MPAMHCR)
} // namespace ArmISA
} // namespace gem5