From: Jonathan Cameron <[email protected]> Add the MPAM system registers for TCG: MPAMIDR_EL1 (RO) reporting 64 PARTIDs and 4 PMGs, and MPAM0_EL1/MPAM1_EL1 (RW, of which only MPAM1_EL1.MPAMEN is architecturally reset). Advertise FEAT_MPAM via ID_AA64PFR0.MPAM for TCG CPUs.
It is common to support MPAM on CPU cores, but not in the rest of the system, so there is little disadvantage in always enabling these. Based on an RFC series by Jonathan Cameron, adapted to the current idregs[] storage and access_tid3() naming. Signed-off-by: Jonathan Cameron <[email protected]> Signed-off-by: Jinjie Ruan <[email protected]> --- target/arm/cpu-features.h | 11 +++++++++++ target/arm/cpu.c | 10 +++++++++- target/arm/cpu.h | 3 +++ target/arm/helper.c | 17 +++++++++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index a9eebb4..4b7d47b 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -459,6 +459,17 @@ FIELD(DBGDEVID, DOUBLELOCK, 20, 4) FIELD(DBGDEVID, AUXREGS, 24, 4) FIELD(DBGDEVID, CIDMASK, 28, 4) +FIELD(MPAMIDR, PARTID_MAX, 0, 16) +FIELD(MPAMIDR, HAS_HCR, 17, 1) +FIELD(MPAMIDR, VMR_MAX, 18, 3) +FIELD(MPAMIDR, PMG_MAX, 32, 8) +FIELD(MPAMIDR, HAS_ALTSP, 57, 1) +FIELD(MPAMIDR, HAS_TIDR, 58, 1) +FIELD(MPAMIDR, SP4, 59, 1) +FIELD(MPAMIDR, HAS_FORCE_NS, 60, 1) +FIELD(MPAMIDR, HAS_SDEFLT, 61, 1) +FIELD(MPAM1_EL1, MPAMEN, 63, 1) + FIELD(DBGDEVID1, PCSROFFSET, 0, 4) FIELD(MVFR0, SIMDREG, 0, 4) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 10ac6c9..e7529d5 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -439,6 +439,8 @@ static void arm_cpu_reset_hold(Object *obj, ResetType type) /* Sample rvbar at reset. */ env->cp15.rvbar = cpu->rvbar_prop; env->pc = env->cp15.rvbar; + + env->mpam1_el1 = R_MPAM1_EL1_MPAMEN_MASK; #endif } else { #if defined(CONFIG_USER_ONLY) @@ -452,6 +454,8 @@ static void arm_cpu_reset_hold(Object *obj, ResetType type) env->cp15.rvbar = cpu->rvbar_prop; env->regs[15] = cpu->rvbar_prop; } + + env->mpam1_el1 = R_MPAM1_EL1_MPAMEN_MASK; } #if defined(CONFIG_USER_ONLY) @@ -2333,7 +2337,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) FIELD_DP64_IDREG(isar, ID_AA64PFR0, AMU, 0); FIELD_DP32_IDREG(isar, ID_PFR0, AMU, 0); /* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */ - FIELD_DP64_IDREG(isar, ID_AA64PFR0, MPAM, 0); + FIELD_DP64_IDREG(isar, ID_AA64PFR0, MPAM, 1); + cpu->isar.mpamidr_el1 = + FIELD_DP64(cpu->isar.mpamidr_el1, MPAMIDR, PARTID_MAX, 63); + cpu->isar.mpamidr_el1 = + FIELD_DP64(cpu->isar.mpamidr_el1, MPAMIDR, PMG_MAX, 3); } /* MPU can be configured out of a PMSA CPU either by setting has-mpu diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 06ebed4..51a36fa 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -757,6 +757,8 @@ typedef struct CPUArchState { struct CPUBreakpoint *cpu_breakpoint[16]; struct CPUWatchpoint *cpu_watchpoint[16]; + uint64_t mpam0_el1; + uint64_t mpam1_el1; /* Optional fault info across tlb lookup. */ ARMMMUFaultInfo *tlb_fi; @@ -1121,6 +1123,7 @@ struct ArchCPU { uint32_t dbgdevid; uint32_t dbgdevid1; uint64_t reset_pmcr_el0; + uint64_t mpamidr_el1; uint64_t idregs[NUM_ID_IDX]; } isar; uint64_t midr; diff --git a/target/arm/helper.c b/target/arm/helper.c index ff0b766..896ac0e 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6907,6 +6907,23 @@ void register_cp_regs_for_features(ARMCPU *cpu) .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_tid3, .resetvalue = cpu->isar.mvfr0 }, + { .name = "MPAMIDR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0xa, .crm = 4, .opc2 = 4, + .access = PL1_R, .type = ARM_CP_CONST, + .accessfn = access_tid3, + .resetvalue = cpu->isar.mpamidr_el1 }, + { .name = "MPAM0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0xa, .crm = 5, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_ALIAS, + .accessfn = access_tid3, + .fieldoffset = offsetof(CPUARMState, mpam0_el1), + }, + { .name = "MPAM1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0xa, .crm = 5, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_ALIAS, + .accessfn = access_tid3, + .fieldoffset = offsetof(CPUARMState, mpam1_el1), + }, { .name = "MVFR1_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, -- 2.43.0
