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
commita6f91249e064a2ee935c900529b03f949ad89e6c (patch)
tree7d88e50eb2da676a27b12440c611f7ca213d9fa6 /target/ppc
parent308b9fad2a301f3473e920f981d49e2ff0829029 (diff)
downloadqemu-a6f91249e064a2ee935c900529b03f949ad89e6c.zip
qemu-a6f91249e064a2ee935c900529b03f949ad89e6c.tar.gz
qemu-a6f91249e064a2ee935c900529b03f949ad89e6c.tar.bz2
target/ppc: PMU: update counters on MMCR1 write
MMCR1 determines the events to be sampled by the PMU. Updating the counters at every MMCR1 write ensures that we're not sampling more or less events by looking only at MMCR0 and the PMCs. It is worth noticing that both the Book3S PowerPC PMU, and this IBM Power8+ PMU that we're modeling, also uses MMCRA, MMCR2 and MMCR3 to control the PMU. These three registers aren't being handled in this initial implementation, so for now we're controlling all the PMU aspects using MMCR0, MMCR1 and the PMCs. Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> Message-Id: <20211201151734.654994-5-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.c2
-rw-r--r--target/ppc/helper.h1
-rw-r--r--target/ppc/power8-pmu-regs.c.inc11
-rw-r--r--target/ppc/power8-pmu.c7
-rw-r--r--target/ppc/spr_tcg.h1
5 files changed, 21 insertions, 1 deletions
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index ceb325b..e865d36 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6258,7 +6258,7 @@ static void register_book3s_pmu_sup_sprs(CPUPPCState *env)
KVM_REG_PPC_MMCR0, 0x80000000);
spr_register_kvm(env, SPR_POWER_MMCR1, "MMCR1",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, &spr_write_MMCR1,
KVM_REG_PPC_MMCR1, 0x00000000);
spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA",
SPR_NOACCESS, SPR_NOACCESS,
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 984d031..77c85e1 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -21,6 +21,7 @@ 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_2(store_mmcr1, void, env, tl)
DEF_HELPER_3(store_pmc, void, env, i32, i64)
DEF_HELPER_2(read_pmc, tl, env, i32)
#endif
diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc
index f0c9cc3..25b13ad 100644
--- a/target/ppc/power8-pmu-regs.c.inc
+++ b/target/ppc/power8-pmu-regs.c.inc
@@ -255,6 +255,12 @@ void spr_write_MMCR0(DisasContext *ctx, int sprn, int gprn)
{
write_MMCR0_common(ctx, cpu_gpr[gprn]);
}
+
+void spr_write_MMCR1(DisasContext *ctx, int sprn, int gprn)
+{
+ gen_icount_io_start(ctx);
+ gen_helper_store_mmcr1(cpu_env, cpu_gpr[gprn]);
+}
#else
void spr_read_MMCR0_ureg(DisasContext *ctx, int gprn, int sprn)
{
@@ -301,6 +307,11 @@ void spr_write_MMCR0(DisasContext *ctx, int sprn, int gprn)
spr_write_generic(ctx, sprn, gprn);
}
+void spr_write_MMCR1(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);
diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 7131f52..7325252 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -133,6 +133,13 @@ void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
hreg_compute_hflags(env);
}
+void helper_store_mmcr1(CPUPPCState *env, uint64_t value)
+{
+ pmu_update_cycles(env);
+
+ env->spr[SPR_POWER_MMCR1] = value;
+}
+
target_ulong helper_read_pmc(CPUPPCState *env, uint32_t sprn)
{
pmu_update_cycles(env);
diff --git a/target/ppc/spr_tcg.h b/target/ppc/spr_tcg.h
index 1e79a05..1d6521e 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_MMCR1(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);