|
@@ -38,7 +38,6 @@
|
|
#endif
|
|
#endif
|
|
|
|
|
|
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
|
|
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
|
|
-#define PMCR_NUM_COUNTERS 4 /* QEMU IMPDEF choice */
|
|
|
|
|
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
|
|
@@ -1149,7 +1148,9 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
|
|
|
|
|
|
static inline uint32_t pmu_num_counters(CPUARMState *env)
|
|
static inline uint32_t pmu_num_counters(CPUARMState *env)
|
|
{
|
|
{
|
|
- return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT;
|
|
|
|
|
|
+ ARMCPU *cpu = env_archcpu(env);
|
|
|
|
+
|
|
|
|
+ return (cpu->isar.reset_pmcr_el0 & PMCRN_MASK) >> PMCRN_SHIFT;
|
|
}
|
|
}
|
|
|
|
|
|
/* Bits allowed to be set/cleared for PMCNTEN* and PMINTEN* */
|
|
/* Bits allowed to be set/cleared for PMCNTEN* and PMINTEN* */
|
|
@@ -5753,13 +5754,6 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
|
|
.resetvalue = 0,
|
|
.resetvalue = 0,
|
|
.writefn = gt_hyp_ctl_write, .raw_writefn = raw_write },
|
|
.writefn = gt_hyp_ctl_write, .raw_writefn = raw_write },
|
|
#endif
|
|
#endif
|
|
- /* The only field of MDCR_EL2 that has a defined architectural reset value
|
|
|
|
- * is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N.
|
|
|
|
- */
|
|
|
|
- { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
|
|
|
|
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
|
|
|
|
- .access = PL2_RW, .resetvalue = PMCR_NUM_COUNTERS,
|
|
|
|
- .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2), },
|
|
|
|
{ .name = "HPFAR", .state = ARM_CP_STATE_AA32,
|
|
{ .name = "HPFAR", .state = ARM_CP_STATE_AA32,
|
|
.cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
|
|
.cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
|
|
.access = PL2_RW, .accessfn = access_el3_aa32ns,
|
|
.access = PL2_RW, .accessfn = access_el3_aa32ns,
|
|
@@ -6689,7 +6683,7 @@ static void define_pmu_regs(ARMCPU *cpu)
|
|
* field as main ID register, and we implement four counters in
|
|
* field as main ID register, and we implement four counters in
|
|
* addition to the cycle count register.
|
|
* addition to the cycle count register.
|
|
*/
|
|
*/
|
|
- unsigned int i, pmcrn = PMCR_NUM_COUNTERS;
|
|
|
|
|
|
+ unsigned int i, pmcrn = pmu_num_counters(&cpu->env);
|
|
ARMCPRegInfo pmcr = {
|
|
ARMCPRegInfo pmcr = {
|
|
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
|
|
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
|
|
.access = PL0_RW,
|
|
.access = PL0_RW,
|
|
@@ -6704,10 +6698,10 @@ static void define_pmu_regs(ARMCPU *cpu)
|
|
.access = PL0_RW, .accessfn = pmreg_access,
|
|
.access = PL0_RW, .accessfn = pmreg_access,
|
|
.type = ARM_CP_IO,
|
|
.type = ARM_CP_IO,
|
|
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
|
|
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
|
|
- .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT) |
|
|
|
|
- PMCRLC,
|
|
|
|
|
|
+ .resetvalue = cpu->isar.reset_pmcr_el0,
|
|
.writefn = pmcr_write, .raw_writefn = raw_write,
|
|
.writefn = pmcr_write, .raw_writefn = raw_write,
|
|
};
|
|
};
|
|
|
|
+
|
|
define_one_arm_cp_reg(cpu, &pmcr);
|
|
define_one_arm_cp_reg(cpu, &pmcr);
|
|
define_one_arm_cp_reg(cpu, &pmcr64);
|
|
define_one_arm_cp_reg(cpu, &pmcr64);
|
|
for (i = 0; i < pmcrn; i++) {
|
|
for (i = 0; i < pmcrn; i++) {
|
|
@@ -7825,6 +7819,17 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
|
.fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },
|
|
.fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },
|
|
REGINFO_SENTINEL
|
|
REGINFO_SENTINEL
|
|
};
|
|
};
|
|
|
|
+ /*
|
|
|
|
+ * The only field of MDCR_EL2 that has a defined architectural reset
|
|
|
|
+ * value is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N.
|
|
|
|
+ */
|
|
|
|
+ ARMCPRegInfo mdcr_el2 = {
|
|
|
|
+ .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
|
|
|
|
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
|
|
|
|
+ .access = PL2_RW, .resetvalue = pmu_num_counters(env),
|
|
|
|
+ .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2),
|
|
|
|
+ };
|
|
|
|
+ define_one_arm_cp_reg(cpu, &mdcr_el2);
|
|
define_arm_cp_regs(cpu, vpidr_regs);
|
|
define_arm_cp_regs(cpu, vpidr_regs);
|
|
define_arm_cp_regs(cpu, el2_cp_reginfo);
|
|
define_arm_cp_regs(cpu, el2_cp_reginfo);
|
|
if (arm_feature(env, ARM_FEATURE_V8)) {
|
|
if (arm_feature(env, ARM_FEATURE_V8)) {
|