diff options
author | Akihiko Odaki <akihiko.odaki@daynix.com> | 2024-07-20 18:30:53 +0900 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2024-07-29 16:05:49 +0100 |
commit | e6fd3192edb8178613e61f7f0242a774ad8ffa2c (patch) | |
tree | d409b853e327b0b0a60ffe0da1bdbfe188a9f64c | |
parent | e9e640148c676ac2c087a3dd93e3917c8fca25ea (diff) |
hvf: arm: Properly disable PMU
Setting pmu property used to have no effect for hvf so fix it.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | target/arm/hvf/hvf.c | 184 |
1 files changed, 97 insertions, 87 deletions
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 1a749534fb..adcdfae0b1 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -1204,45 +1204,50 @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint64_t *val) ARMCPU *arm_cpu = ARM_CPU(cpu); CPUARMState *env = &arm_cpu->env; + if (arm_feature(env, ARM_FEATURE_PMU)) { + switch (reg) { + case SYSREG_PMCR_EL0: + *val = env->cp15.c9_pmcr; + return 0; + case SYSREG_PMCCNTR_EL0: + pmu_op_start(env); + *val = env->cp15.c15_ccnt; + pmu_op_finish(env); + return 0; + case SYSREG_PMCNTENCLR_EL0: + *val = env->cp15.c9_pmcnten; + return 0; + case SYSREG_PMOVSCLR_EL0: + *val = env->cp15.c9_pmovsr; + return 0; + case SYSREG_PMSELR_EL0: + *val = env->cp15.c9_pmselr; + return 0; + case SYSREG_PMINTENCLR_EL1: + *val = env->cp15.c9_pminten; + return 0; + case SYSREG_PMCCFILTR_EL0: + *val = env->cp15.pmccfiltr_el0; + return 0; + case SYSREG_PMCNTENSET_EL0: + *val = env->cp15.c9_pmcnten; + return 0; + case SYSREG_PMUSERENR_EL0: + *val = env->cp15.c9_pmuserenr; + return 0; + case SYSREG_PMCEID0_EL0: + case SYSREG_PMCEID1_EL0: + /* We can't really count anything yet, declare all events invalid */ + *val = 0; + return 0; + } + } + switch (reg) { case SYSREG_CNTPCT_EL0: *val = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / gt_cntfrq_period_ns(arm_cpu); return 0; - case SYSREG_PMCR_EL0: - *val = env->cp15.c9_pmcr; - return 0; - case SYSREG_PMCCNTR_EL0: - pmu_op_start(env); - *val = env->cp15.c15_ccnt; - pmu_op_finish(env); - return 0; - case SYSREG_PMCNTENCLR_EL0: - *val = env->cp15.c9_pmcnten; - return 0; - case SYSREG_PMOVSCLR_EL0: - *val = env->cp15.c9_pmovsr; - return 0; - case SYSREG_PMSELR_EL0: - *val = env->cp15.c9_pmselr; - return 0; - case SYSREG_PMINTENCLR_EL1: - *val = env->cp15.c9_pminten; - return 0; - case SYSREG_PMCCFILTR_EL0: - *val = env->cp15.pmccfiltr_el0; - return 0; - case SYSREG_PMCNTENSET_EL0: - *val = env->cp15.c9_pmcnten; - return 0; - case SYSREG_PMUSERENR_EL0: - *val = env->cp15.c9_pmuserenr; - return 0; - case SYSREG_PMCEID0_EL0: - case SYSREG_PMCEID1_EL0: - /* We can't really count anything yet, declare all events invalid */ - *val = 0; - return 0; case SYSREG_OSLSR_EL1: *val = env->cp15.oslsr_el1; return 0; @@ -1486,64 +1491,69 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val) SYSREG_OP2(reg), val); - switch (reg) { - case SYSREG_PMCCNTR_EL0: - pmu_op_start(env); - env->cp15.c15_ccnt = val; - pmu_op_finish(env); - return 0; - case SYSREG_PMCR_EL0: - pmu_op_start(env); + if (arm_feature(env, ARM_FEATURE_PMU)) { + switch (reg) { + case SYSREG_PMCCNTR_EL0: + pmu_op_start(env); + env->cp15.c15_ccnt = val; + pmu_op_finish(env); + return 0; + case SYSREG_PMCR_EL0: + pmu_op_start(env); - if (val & PMCRC) { - /* The counter has been reset */ - env->cp15.c15_ccnt = 0; - } + if (val & PMCRC) { + /* The counter has been reset */ + env->cp15.c15_ccnt = 0; + } - if (val & PMCRP) { - unsigned int i; - for (i = 0; i < pmu_num_counters(env); i++) { - env->cp15.c14_pmevcntr[i] = 0; + if (val & PMCRP) { + unsigned int i; + for (i = 0; i < pmu_num_counters(env); i++) { + env->cp15.c14_pmevcntr[i] = 0; + } } - } - env->cp15.c9_pmcr &= ~PMCR_WRITABLE_MASK; - env->cp15.c9_pmcr |= (val & PMCR_WRITABLE_MASK); + env->cp15.c9_pmcr &= ~PMCR_WRITABLE_MASK; + env->cp15.c9_pmcr |= (val & PMCR_WRITABLE_MASK); - pmu_op_finish(env); - return 0; - case SYSREG_PMUSERENR_EL0: - env->cp15.c9_pmuserenr = val & 0xf; - return 0; - case SYSREG_PMCNTENSET_EL0: - env->cp15.c9_pmcnten |= (val & pmu_counter_mask(env)); - return 0; - case SYSREG_PMCNTENCLR_EL0: - env->cp15.c9_pmcnten &= ~(val & pmu_counter_mask(env)); - return 0; - case SYSREG_PMINTENCLR_EL1: - pmu_op_start(env); - env->cp15.c9_pminten |= val; - pmu_op_finish(env); - return 0; - case SYSREG_PMOVSCLR_EL0: - pmu_op_start(env); - env->cp15.c9_pmovsr &= ~val; - pmu_op_finish(env); - return 0; - case SYSREG_PMSWINC_EL0: - pmu_op_start(env); - pmswinc_write(env, val); - pmu_op_finish(env); - return 0; - case SYSREG_PMSELR_EL0: - env->cp15.c9_pmselr = val & 0x1f; - return 0; - case SYSREG_PMCCFILTR_EL0: - pmu_op_start(env); - env->cp15.pmccfiltr_el0 = val & PMCCFILTR_EL0; - pmu_op_finish(env); - return 0; + pmu_op_finish(env); + return 0; + case SYSREG_PMUSERENR_EL0: + env->cp15.c9_pmuserenr = val & 0xf; + return 0; + case SYSREG_PMCNTENSET_EL0: + env->cp15.c9_pmcnten |= (val & pmu_counter_mask(env)); + return 0; + case SYSREG_PMCNTENCLR_EL0: + env->cp15.c9_pmcnten &= ~(val & pmu_counter_mask(env)); + return 0; + case SYSREG_PMINTENCLR_EL1: + pmu_op_start(env); + env->cp15.c9_pminten |= val; + pmu_op_finish(env); + return 0; + case SYSREG_PMOVSCLR_EL0: + pmu_op_start(env); + env->cp15.c9_pmovsr &= ~val; + pmu_op_finish(env); + return 0; + case SYSREG_PMSWINC_EL0: + pmu_op_start(env); + pmswinc_write(env, val); + pmu_op_finish(env); + return 0; + case SYSREG_PMSELR_EL0: + env->cp15.c9_pmselr = val & 0x1f; + return 0; + case SYSREG_PMCCFILTR_EL0: + pmu_op_start(env); + env->cp15.pmccfiltr_el0 = val & PMCCFILTR_EL0; + pmu_op_finish(env); + return 0; + } + } + + switch (reg) { case SYSREG_OSLAR_EL1: env->cp15.oslsr_el1 = val & 1; return 0; |