summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--target/arm/cpu.h17
-rw-r--r--target/arm/helper.c19
2 files changed, 35 insertions, 1 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index ce1e2a090e..0b84742b66 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -904,7 +904,7 @@ struct ARMCPU {
/* The elements of this array are the CCSIDR values for each cache,
* in the order L1DCache, L1ICache, L2DCache, L2ICache, etc.
*/
- uint32_t ccsidr[16];
+ uint64_t ccsidr[16];
uint64_t reset_cbar;
uint32_t reset_auxcr;
bool reset_hivecs;
@@ -3577,6 +3577,11 @@ static inline bool isar_feature_aa32_ac2(const ARMISARegisters *id)
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, AC2) != 0;
}
+static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
+}
+
/*
* 64-bit feature tests via id registers.
*/
@@ -3784,6 +3789,11 @@ static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id)
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2;
}
+static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
+}
+
/*
* Feature tests for "does this exist in either 32-bit or 64-bit?"
*/
@@ -3807,6 +3817,11 @@ static inline bool isar_feature_any_pmu_8_4(const ARMISARegisters *id)
return isar_feature_aa64_pmu_8_4(id) || isar_feature_aa32_pmu_8_4(id);
}
+static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
+{
+ return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
+}
+
/*
* Forward to the above feature tests given an ARMCPU pointer.
*/
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 8841cc7fde..6be9ffa09e 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6726,6 +6726,21 @@ static const ARMCPRegInfo predinv_reginfo[] = {
REGINFO_SENTINEL
};
+static uint64_t ccsidr2_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ /* Read the high 32 bits of the current CCSIDR */
+ return extract64(ccsidr_read(env, ri), 32, 32);
+}
+
+static const ARMCPRegInfo ccsidr2_reginfo[] = {
+ { .name = "CCSIDR2", .state = ARM_CP_STATE_BOTH,
+ .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 2,
+ .access = PL1_R,
+ .accessfn = access_aa64_tid2,
+ .readfn = ccsidr2_read, .type = ARM_CP_NO_RAW },
+ REGINFO_SENTINEL
+};
+
static CPAccessResult access_aa64_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
@@ -7788,6 +7803,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_arm_cp_regs(cpu, predinv_reginfo);
}
+ if (cpu_isar_feature(any_ccidx, cpu)) {
+ define_arm_cp_regs(cpu, ccsidr2_reginfo);
+ }
+
#ifndef CONFIG_USER_ONLY
/*
* Register redirections and aliases must be done last,