aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorDaniel Henrique Barboza <danielhb413@gmail.com>2021-10-17 22:01:22 -0300
committerDavid Gibson <david@gibson.dropbear.id.au>2021-10-21 11:42:47 +1100
commitcedf706956e7440653b18ac2c2a9452b8d710577 (patch)
tree3664a9a7ee24c076316f7a37275679756c6306be /target
parent7b3ecf16c81c16eb3cf171b0bd63c08f1a5dd942 (diff)
downloadqemu-cedf706956e7440653b18ac2c2a9452b8d710577.zip
qemu-cedf706956e7440653b18ac2c2a9452b8d710577.tar.gz
qemu-cedf706956e7440653b18ac2c2a9452b8d710577.tar.bz2
target/ppc: adding user read/write functions for PMCs
Problem state needs to be able to read and write the PMU counters, otherwise it won't be aware of any sampling result that the PMU produces after a Perf run. This patch does that in a similar fashion as already done in the previous patches. PMCs 5 and 6 have a special condition, aside from the constraints that are common with PMCs 1-4, where they are not part of the PMU if MMCR0_PMCC is 0b11. Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> Message-Id: <20211018010133.315842-5-danielhb413@gmail.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target')
-rw-r--r--target/ppc/cpu_init.c12
-rw-r--r--target/ppc/power8-pmu-regs.c.inc70
-rw-r--r--target/ppc/spr_tcg.h4
3 files changed, 80 insertions, 6 deletions
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index ad88e54..65545ba 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6879,27 +6879,27 @@ static void register_book3s_pmu_user_sprs(CPUPPCState *env)
&spr_read_ureg, &spr_write_ureg,
0x00000000);
spr_register(env, SPR_POWER_UPMC1, "UPMC1",
- &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_PMC14_ureg, &spr_write_PMC14_ureg,
&spr_read_ureg, &spr_write_ureg,
0x00000000);
spr_register(env, SPR_POWER_UPMC2, "UPMC2",
- &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_PMC14_ureg, &spr_write_PMC14_ureg,
&spr_read_ureg, &spr_write_ureg,
0x00000000);
spr_register(env, SPR_POWER_UPMC3, "UPMC3",
- &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_PMC14_ureg, &spr_write_PMC14_ureg,
&spr_read_ureg, &spr_write_ureg,
0x00000000);
spr_register(env, SPR_POWER_UPMC4, "UPMC4",
- &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_PMC14_ureg, &spr_write_PMC14_ureg,
&spr_read_ureg, &spr_write_ureg,
0x00000000);
spr_register(env, SPR_POWER_UPMC5, "UPMC5",
- &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_PMC56_ureg, &spr_write_PMC56_ureg,
&spr_read_ureg, &spr_write_ureg,
0x00000000);
spr_register(env, SPR_POWER_UPMC6, "UPMC6",
- &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_PMC56_ureg, &spr_write_PMC56_ureg,
&spr_read_ureg, &spr_write_ureg,
0x00000000);
spr_register(env, SPR_POWER_USIAR, "USIAR",
diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc
index fb95175..7391851 100644
--- a/target/ppc/power8-pmu-regs.c.inc
+++ b/target/ppc/power8-pmu-regs.c.inc
@@ -169,6 +169,56 @@ void spr_write_MMCR2_ureg(DisasContext *ctx, int sprn, int gprn)
tcg_temp_free(masked_gprn);
}
+
+void spr_read_PMC14_ureg(DisasContext *ctx, int gprn, int sprn)
+{
+ if (!spr_groupA_read_allowed(ctx)) {
+ return;
+ }
+
+ spr_read_ureg(ctx, gprn, sprn);
+}
+
+void spr_read_PMC56_ureg(DisasContext *ctx, int gprn, int sprn)
+{
+ /*
+ * If PMCC = 0b11, PMC5 and PMC6 aren't included in the Performance
+ * Monitor, and a read attempt results in a Facility Unavailable
+ * Interrupt.
+ */
+ if (ctx->mmcr0_pmcc0 && ctx->mmcr0_pmcc1) {
+ gen_hvpriv_exception(ctx, POWERPC_EXCP_FU);
+ return;
+ }
+
+ /* The remaining steps are similar to PMCs 1-4 userspace read */
+ spr_read_PMC14_ureg(ctx, gprn, 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);
+}
+
+void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int gprn)
+{
+ /*
+ * If PMCC = 0b11, PMC5 and PMC6 aren't included in the Performance
+ * Monitor, and a write attempt results in a Facility Unavailable
+ * Interrupt.
+ */
+ if (ctx->mmcr0_pmcc0 && ctx->mmcr0_pmcc1) {
+ gen_hvpriv_exception(ctx, POWERPC_EXCP_FU);
+ return;
+ }
+
+ /* The remaining steps are similar to PMCs 1-4 userspace write */
+ spr_write_PMC14_ureg(ctx, sprn, gprn);
+}
#else
void spr_read_MMCR0_ureg(DisasContext *ctx, int gprn, int sprn)
{
@@ -189,4 +239,24 @@ void spr_write_MMCR2_ureg(DisasContext *ctx, int sprn, int gprn)
{
spr_noaccess(ctx, gprn, sprn);
}
+
+void spr_read_PMC14_ureg(DisasContext *ctx, int gprn, int sprn)
+{
+ spr_read_ureg(ctx, gprn, sprn);
+}
+
+void spr_read_PMC56_ureg(DisasContext *ctx, int gprn, int sprn)
+{
+ spr_read_ureg(ctx, gprn, sprn);
+}
+
+void spr_write_PMC14_ureg(DisasContext *ctx, int sprn, int gprn)
+{
+ spr_noaccess(ctx, gprn, sprn);
+}
+
+void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int gprn)
+{
+ spr_noaccess(ctx, gprn, sprn);
+}
#endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
diff --git a/target/ppc/spr_tcg.h b/target/ppc/spr_tcg.h
index cb7f40e..520f1ef 100644
--- a/target/ppc/spr_tcg.h
+++ b/target/ppc/spr_tcg.h
@@ -34,6 +34,8 @@ 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_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);
void spr_read_tbu(DisasContext *ctx, int gprn, int sprn);
void spr_read_atbl(DisasContext *ctx, int gprn, int sprn);
@@ -44,6 +46,8 @@ void spr_read_spefscr(DisasContext *ctx, int gprn, int sprn);
void spr_write_spefscr(DisasContext *ctx, int sprn, int gprn);
void spr_write_MMCR0_ureg(DisasContext *ctx, int sprn, int gprn);
void spr_write_MMCR2_ureg(DisasContext *ctx, int sprn, int gprn);
+void spr_write_PMC14_ureg(DisasContext *ctx, int sprn, int gprn);
+void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int gprn);
#ifndef CONFIG_USER_ONLY
void spr_write_generic32(DisasContext *ctx, int sprn, int gprn);