aboutsummaryrefslogtreecommitdiff
path: root/target/ppc
diff options
context:
space:
mode:
authorDaniel Henrique Barboza <danielhb413@gmail.com>2021-12-17 17:57:18 +0100
committerCédric Le Goater <clg@kaod.org>2021-12-17 17:57:18 +0100
commit308b9fad2a301f3473e920f981d49e2ff0829029 (patch)
tree31a1efd3afb8af06592c3bdcfb3ffae982a777a1 /target/ppc
parentc2eff582a32f4251515e041f4919d3fbe4a0048e (diff)
target/ppc: PMU: update counters on PMCs r/w
Calling pmu_update_cycles() on every PMC read/write operation ensures that the values being fetched are up to date with the current PMU state. In theory we can get away by just trapping PMCs reads, but we're going to trap PMC writes to deal with counter overflow logic later on. Let's put the required wiring for that and make our lives a bit easier in the next patches. Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> Message-Id: <20211201151734.654994-4-danielhb413@gmail.com> Signed-off-by: Cédric Le Goater <clg@kaod.org>
Diffstat (limited to 'target/ppc')
-rw-r--r--target/ppc/cpu_init.c12
-rw-r--r--target/ppc/helper.h2
-rw-r--r--target/ppc/power8-pmu-regs.c.inc29
-rw-r--r--target/ppc/power8-pmu.c14
-rw-r--r--target/ppc/spr_tcg.h2
5 files changed, 51 insertions, 8 deletions
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index cfa605a76b..ceb325b311 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6266,27 +6266,27 @@ static void register_book3s_pmu_sup_sprs(CPUPPCState *env)
KVM_REG_PPC_MMCRA, 0x00000000);
spr_register_kvm(env, SPR_POWER_PMC1, "PMC1",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_PMC, &spr_write_PMC,
KVM_REG_PPC_PMC1, 0x00000000);
spr_register_kvm(env, SPR_POWER_PMC2, "PMC2",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_PMC, &spr_write_PMC,
KVM_REG_PPC_PMC2, 0x00000000);
spr_register_kvm(env, SPR_POWER_PMC3, "PMC3",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_PMC, &spr_write_PMC,
KVM_REG_PPC_PMC3, 0x00000000);
spr_register_kvm(env, SPR_POWER_PMC4, "PMC4",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_PMC, &spr_write_PMC,
KVM_REG_PPC_PMC4, 0x00000000);
spr_register_kvm(env, SPR_POWER_PMC5, "PMC5",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_PMC, &spr_write_PMC,
KVM_REG_PPC_PMC5, 0x00000000);
spr_register_kvm(env, SPR_POWER_PMC6, "PMC6",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_PMC, &spr_write_PMC,
KVM_REG_PPC_PMC6, 0x00000000);
spr_register_kvm(env, SPR_POWER_SIAR, "SIAR",
SPR_NOACCESS, SPR_NOACCESS,
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 0e6cf2d09d..984d03181a 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -21,6 +21,8 @@ DEF_HELPER_1(hrfid, void, env)
DEF_HELPER_2(store_lpcr, void, env, tl)
DEF_HELPER_2(store_pcr, void, env, tl)
DEF_HELPER_2(store_mmcr0, void, env, tl)
+DEF_HELPER_3(store_pmc, void, env, i32, i64)
+DEF_HELPER_2(read_pmc, tl, env, i32)
#endif
DEF_HELPER_1(check_tlb_flush_local, void, env)
DEF_HELPER_1(check_tlb_flush_global, void, env)
diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc
index fbb8977641..f0c9cc343b 100644
--- a/target/ppc/power8-pmu-regs.c.inc
+++ b/target/ppc/power8-pmu-regs.c.inc
@@ -181,13 +181,23 @@ void spr_write_MMCR2_ureg(DisasContext *ctx, int sprn, int gprn)
tcg_temp_free(masked_gprn);
}
+void spr_read_PMC(DisasContext *ctx, int gprn, int sprn)
+{
+ TCGv_i32 t_sprn = tcg_const_i32(sprn);
+
+ gen_icount_io_start(ctx);
+ gen_helper_read_pmc(cpu_gpr[gprn], cpu_env, t_sprn);
+
+ tcg_temp_free_i32(t_sprn);
+}
+
void spr_read_PMC14_ureg(DisasContext *ctx, int gprn, int sprn)
{
if (!spr_groupA_read_allowed(ctx)) {
return;
}
- spr_read_ureg(ctx, gprn, sprn);
+ spr_read_PMC(ctx, gprn, sprn + 0x10);
}
void spr_read_PMC56_ureg(DisasContext *ctx, int gprn, int sprn)
@@ -206,13 +216,23 @@ void spr_read_PMC56_ureg(DisasContext *ctx, int gprn, int sprn)
spr_read_PMC14_ureg(ctx, gprn, sprn);
}
+void spr_write_PMC(DisasContext *ctx, int sprn, int gprn)
+{
+ TCGv_i32 t_sprn = tcg_const_i32(sprn);
+
+ gen_icount_io_start(ctx);
+ gen_helper_store_pmc(cpu_env, t_sprn, cpu_gpr[gprn]);
+
+ tcg_temp_free_i32(t_sprn);
+}
+
void spr_write_PMC14_ureg(DisasContext *ctx, int sprn, int gprn)
{
if (!spr_groupA_write_allowed(ctx)) {
return;
}
- spr_write_ureg(ctx, sprn, gprn);
+ spr_write_PMC(ctx, sprn + 0x10, gprn);
}
void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int gprn)
@@ -280,4 +300,9 @@ void spr_write_MMCR0(DisasContext *ctx, int sprn, int gprn)
{
spr_write_generic(ctx, sprn, gprn);
}
+
+void spr_write_PMC(DisasContext *ctx, int sprn, int gprn)
+{
+ spr_write_generic(ctx, sprn, gprn);
+}
#endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 5e689144d7..7131f52ccc 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -133,6 +133,20 @@ void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
hreg_compute_hflags(env);
}
+target_ulong helper_read_pmc(CPUPPCState *env, uint32_t sprn)
+{
+ pmu_update_cycles(env);
+
+ return env->spr[sprn];
+}
+
+void helper_store_pmc(CPUPPCState *env, uint32_t sprn, uint64_t value)
+{
+ pmu_update_cycles(env);
+
+ env->spr[sprn] = value;
+}
+
static void fire_PMC_interrupt(PowerPCCPU *cpu)
{
CPUPPCState *env = &cpu->env;
diff --git a/target/ppc/spr_tcg.h b/target/ppc/spr_tcg.h
index eb1d0c2bf0..1e79a0522a 100644
--- a/target/ppc/spr_tcg.h
+++ b/target/ppc/spr_tcg.h
@@ -26,6 +26,7 @@ void spr_noaccess(DisasContext *ctx, int gprn, int sprn);
void spr_read_generic(DisasContext *ctx, int gprn, int sprn);
void spr_write_generic(DisasContext *ctx, int sprn, int gprn);
void spr_write_MMCR0(DisasContext *ctx, int sprn, int gprn);
+void spr_write_PMC(DisasContext *ctx, int sprn, int gprn);
void spr_read_xer(DisasContext *ctx, int gprn, int sprn);
void spr_write_xer(DisasContext *ctx, int sprn, int gprn);
void spr_read_lr(DisasContext *ctx, int gprn, int sprn);
@@ -35,6 +36,7 @@ void spr_write_ctr(DisasContext *ctx, int sprn, int gprn);
void spr_read_ureg(DisasContext *ctx, int gprn, int sprn);
void spr_read_MMCR0_ureg(DisasContext *ctx, int gprn, int sprn);
void spr_read_MMCR2_ureg(DisasContext *ctx, int gprn, int sprn);
+void spr_read_PMC(DisasContext *ctx, int gprn, int sprn);
void spr_read_PMC14_ureg(DisasContext *ctx, int gprn, int sprn);
void spr_read_PMC56_ureg(DisasContext *ctx, int gprn, int sprn);
void spr_read_tbl(DisasContext *ctx, int gprn, int sprn);