Skip to content

Commit

Permalink
target/ppc: adding user read/write functions for PMCs
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
danielhb authored and dgibson committed Oct 21, 2021
1 parent 7b3ecf1 commit cedf706
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 6 deletions.
12 changes: 6 additions & 6 deletions target/ppc/cpu_init.c
Expand Up @@ -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",
Expand Down
70 changes: 70 additions & 0 deletions target/ppc/power8-pmu-regs.c.inc
Expand Up @@ -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)
{
Expand All @@ -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) */
4 changes: 4 additions & 0 deletions target/ppc/spr_tcg.h
Expand Up @@ -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);
Expand All @@ -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);
Expand Down

0 comments on commit cedf706

Please sign in to comment.