diff options
author | Daniel Henrique Barboza <danielhb413@gmail.com> | 2021-10-17 22:01:22 -0300 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2021-10-21 11:42:47 +1100 |
commit | cedf706956e7440653b18ac2c2a9452b8d710577 (patch) | |
tree | 3664a9a7ee24c076316f7a37275679756c6306be /target | |
parent | 7b3ecf16c81c16eb3cf171b0bd63c08f1a5dd942 (diff) | |
download | qemu-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.c | 12 | ||||
-rw-r--r-- | target/ppc/power8-pmu-regs.c.inc | 70 | ||||
-rw-r--r-- | target/ppc/spr_tcg.h | 4 |
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); |