mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-27 05:20:50 +00:00
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>
This commit is contained in:
parent
7b3ecf16c8
commit
cedf706956
@ -6879,27 +6879,27 @@ static void register_book3s_pmu_user_sprs(CPUPPCState *env)
|
|||||||
&spr_read_ureg, &spr_write_ureg,
|
&spr_read_ureg, &spr_write_ureg,
|
||||||
0x00000000);
|
0x00000000);
|
||||||
spr_register(env, SPR_POWER_UPMC1, "UPMC1",
|
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,
|
&spr_read_ureg, &spr_write_ureg,
|
||||||
0x00000000);
|
0x00000000);
|
||||||
spr_register(env, SPR_POWER_UPMC2, "UPMC2",
|
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,
|
&spr_read_ureg, &spr_write_ureg,
|
||||||
0x00000000);
|
0x00000000);
|
||||||
spr_register(env, SPR_POWER_UPMC3, "UPMC3",
|
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,
|
&spr_read_ureg, &spr_write_ureg,
|
||||||
0x00000000);
|
0x00000000);
|
||||||
spr_register(env, SPR_POWER_UPMC4, "UPMC4",
|
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,
|
&spr_read_ureg, &spr_write_ureg,
|
||||||
0x00000000);
|
0x00000000);
|
||||||
spr_register(env, SPR_POWER_UPMC5, "UPMC5",
|
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,
|
&spr_read_ureg, &spr_write_ureg,
|
||||||
0x00000000);
|
0x00000000);
|
||||||
spr_register(env, SPR_POWER_UPMC6, "UPMC6",
|
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,
|
&spr_read_ureg, &spr_write_ureg,
|
||||||
0x00000000);
|
0x00000000);
|
||||||
spr_register(env, SPR_POWER_USIAR, "USIAR",
|
spr_register(env, SPR_POWER_USIAR, "USIAR",
|
||||||
|
@ -169,6 +169,56 @@ void spr_write_MMCR2_ureg(DisasContext *ctx, int sprn, int gprn)
|
|||||||
|
|
||||||
tcg_temp_free(masked_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
|
#else
|
||||||
void spr_read_MMCR0_ureg(DisasContext *ctx, int gprn, int sprn)
|
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);
|
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) */
|
#endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
|
||||||
|
@ -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_ureg(DisasContext *ctx, int gprn, int sprn);
|
||||||
void spr_read_MMCR0_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_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_tbl(DisasContext *ctx, int gprn, int sprn);
|
||||||
void spr_read_tbu(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);
|
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_spefscr(DisasContext *ctx, int sprn, int gprn);
|
||||||
void spr_write_MMCR0_ureg(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_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
|
#ifndef CONFIG_USER_ONLY
|
||||||
void spr_write_generic32(DisasContext *ctx, int sprn, int gprn);
|
void spr_write_generic32(DisasContext *ctx, int sprn, int gprn);
|
||||||
|
Loading…
Reference in New Issue
Block a user