diff --git a/src/arch/arm/ArmISA.py b/src/arch/arm/ArmISA.py index 9f296983d0..e7f215822c 100644 --- a/src/arch/arm/ArmISA.py +++ b/src/arch/arm/ArmISA.py @@ -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. diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py index e260ac1b28..94cbb496aa 100644 --- a/src/arch/arm/ArmSystem.py +++ b/src/arch/arm/ArmSystem.py @@ -115,6 +115,7 @@ class ArmExtension(ScopedEnum): "LPAE", "VIRTUALIZATION", "TME", + "FEAT_MPAM", ] diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index bf7d1b0a9c..69ca95d306 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -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( + tc, highestEL).mpamEn; + mpam1.el1.forcedNs = isSecure(tc) ? + readRegisterNoEffect(tc, EL3).el3.forceNs : 0; + return mpam1; + } + case MISCREG_MPAM2_EL2: + { + MPAM mpam2 = readMiscRegNoEffect(MISCREG_MPAM2_EL2); + mpam2.mpamEn = readRegisterNoEffect( + 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; diff --git a/src/arch/arm/regs/misc.cc b/src/arch/arm/regs/misc.cc index 929ccf1169..d29a8bc367 100644 --- a/src/arch/arm/regs/misc.cc +++ b/src/arch/arm/regs/misc.cc @@ -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 lookUpMiscReg(NUM_MISCREGS); namespace { - // The map is translating a MiscRegIndex into AArch64 system register // numbers (op0, op1, crn, crm, op2) std::unordered_map idxToMiscRegNum; @@ -1032,6 +1032,9 @@ std::unordered_map 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 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 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 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 diff --git a/src/arch/arm/regs/misc.hh b/src/arch/arm/regs/misc.hh index fc18e3f8e1..93005aa0e1 100644 --- a/src/arch/arm/regs/misc.hh +++ b/src/arch/arm/regs/misc.hh @@ -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 diff --git a/src/arch/arm/regs/misc_accessors.hh b/src/arch/arm/regs/misc_accessors.hh index 47bd0209d5..710f6139ab 100644 --- a/src/arch/arm/regs/misc_accessors.hh +++ b/src/arch/arm/regs/misc_accessors.hh @@ -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 MiscRegIndex getRegVersion(ExceptionLevel el) diff --git a/src/arch/arm/regs/misc_types.hh b/src/arch/arm/regs/misc_types.hh index f2b246288a..0f3a9f558c 100644 --- a/src/arch/arm/regs/misc_types.hh +++ b/src/arch/arm/regs/misc_types.hh @@ -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