Skip to content

Commit a7138e2

Browse files
milesg-githubnpiggin
authored andcommitted
target/ppc: Add new hflags to support BHRB
This commit is preparatory to the addition of Branch History Rolling Buffer (BHRB) functionality, which is being provided today starting with the P8 processor. BHRB uses several SPR register fields to control whether or not a branch instruction's address (and sometimes target address) should be recorded. Checking each of these fields with each branch instruction using jitted code would lead to a significant decrease in performance. Therefore, it was decided that BHRB configuration bits that are not expected to change frequently should have their state summarized in an hflag so that the amount of checking done by jitted code can be reduced. This commit contains the changes for summarizing the state of the following register fields in the HFLAGS_BHRB_ENABLE hflag: MMCR0[FCP] - Determines if BHRB recording is frozen in the problem state MMCR0[FCPC] - A modifier for MMCR0[FCP] MMCRA[BHRBRD] - Disables all BHRB recording for a thread Reviewed-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
1 parent 687a30a commit a7138e2

File tree

10 files changed

+67
-9
lines changed

10 files changed

+67
-9
lines changed

target/ppc/cpu.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,8 @@ FIELD(MSR, LE, MSR_LE, 1)
533533
#define MMCR0_FC56 PPC_BIT(59) /* PMC Freeze Counters 5-6 bit */
534534
#define MMCR0_PMC1CE PPC_BIT(48) /* MMCR0 PMC1 Condition Enabled */
535535
#define MMCR0_PMCjCE PPC_BIT(49) /* MMCR0 PMCj Condition Enabled */
536+
#define MMCR0_FCP PPC_BIT(34) /* Freeze Counters/BHRB if PR=1 */
537+
#define MMCR0_FCPC PPC_BIT(51) /* Condition for FCP bit */
536538
/* MMCR0 userspace r/w mask */
537539
#define MMCR0_UREG_MASK (MMCR0_FC | MMCR0_PMAO | MMCR0_PMAE)
538540
/* MMCR2 userspace r/w mask */
@@ -545,6 +547,8 @@ FIELD(MSR, LE, MSR_LE, 1)
545547
#define MMCR2_UREG_MASK (MMCR2_FC1P0 | MMCR2_FC2P0 | MMCR2_FC3P0 | \
546548
MMCR2_FC4P0 | MMCR2_FC5P0 | MMCR2_FC6P0)
547549

550+
#define MMCRA_BHRBRD PPC_BIT(26) /* BHRB Recording Disable */
551+
548552
#define MMCR1_EVT_SIZE 8
549553
/* extract64() does a right shift before extracting */
550554
#define MMCR1_PMC1SEL_START 32
@@ -797,6 +801,7 @@ enum {
797801
HFLAGS_PMCJCE = 17, /* MMCR0 PMCjCE bit */
798802
HFLAGS_PMC_OTHER = 18, /* PMC other than PMC5-6 is enabled */
799803
HFLAGS_INSN_CNT = 19, /* PMU instruction count enabled */
804+
HFLAGS_BHRB_ENABLE = 20, /* Summary flag for enabling BHRB */
800805
HFLAGS_VSX = 23, /* MSR_VSX if cpu has VSX */
801806
HFLAGS_VR = 25, /* MSR_VR if cpu has VRE */
802807

target/ppc/cpu_init.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5152,7 +5152,7 @@ static void register_book3s_pmu_sup_sprs(CPUPPCState *env)
51525152
KVM_REG_PPC_MMCR1, 0x00000000);
51535153
spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA",
51545154
SPR_NOACCESS, SPR_NOACCESS,
5155-
&spr_read_generic, &spr_write_generic,
5155+
&spr_read_generic, &spr_write_MMCRA,
51565156
KVM_REG_PPC_MMCRA, 0x00000000);
51575157
spr_register_kvm(env, SPR_POWER_PMC1, "PMC1",
51585158
SPR_NOACCESS, SPR_NOACCESS,
@@ -7196,7 +7196,7 @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
71967196
if (env->mmu_model != POWERPC_MMU_REAL) {
71977197
ppc_tlb_invalidate_all(env);
71987198
}
7199-
pmu_mmcr01_updated(env);
7199+
pmu_mmcr01a_updated(env);
72007200
}
72017201

72027202
/* clean any pending stop state */

target/ppc/helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ DEF_HELPER_2(store_dawr0, void, env, tl)
3030
DEF_HELPER_2(store_dawrx0, void, env, tl)
3131
DEF_HELPER_2(store_mmcr0, void, env, tl)
3232
DEF_HELPER_2(store_mmcr1, void, env, tl)
33+
DEF_HELPER_2(store_mmcrA, void, env, tl)
3334
DEF_HELPER_3(store_pmc, void, env, i32, i64)
3435
DEF_HELPER_2(read_pmc, tl, env, i32)
3536
DEF_HELPER_2(insns_inc, void, env, i32)

target/ppc/helper_regs.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,39 @@ void hreg_swap_gpr_tgpr(CPUPPCState *env)
4747
env->tgpr[3] = tmp;
4848
}
4949

50+
#if defined(TARGET_PPC64)
51+
static bool hreg_check_bhrb_enable(CPUPPCState *env)
52+
{
53+
bool pr = !!(env->msr & (1 << MSR_PR));
54+
target_long mmcr0;
55+
bool fcp;
56+
bool hv;
57+
58+
/* ISA 3.1 adds the PMCRA[BRHBRD] and problem state checks */
59+
if ((env->insns_flags2 & PPC2_ISA310) &&
60+
((env->spr[SPR_POWER_MMCRA] & MMCRA_BHRBRD) || !pr)) {
61+
return false;
62+
}
63+
64+
/* Check for BHRB "frozen" conditions */
65+
mmcr0 = env->spr[SPR_POWER_MMCR0];
66+
fcp = !!(mmcr0 & MMCR0_FCP);
67+
if (mmcr0 & MMCR0_FCPC) {
68+
hv = !!(env->msr & (1ull << MSR_HV));
69+
if (fcp) {
70+
if (hv && pr) {
71+
return false;
72+
}
73+
} else if (!hv && pr) {
74+
return false;
75+
}
76+
} else if (fcp && pr) {
77+
return false;
78+
}
79+
return true;
80+
}
81+
#endif
82+
5083
static uint32_t hreg_compute_pmu_hflags_value(CPUPPCState *env)
5184
{
5285
uint32_t hflags = 0;
@@ -61,6 +94,9 @@ static uint32_t hreg_compute_pmu_hflags_value(CPUPPCState *env)
6194
if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE) {
6295
hflags |= 1 << HFLAGS_PMCJCE;
6396
}
97+
if (hreg_check_bhrb_enable(env)) {
98+
hflags |= 1 << HFLAGS_BHRB_ENABLE;
99+
}
64100

65101
#ifndef CONFIG_USER_ONLY
66102
if (env->pmc_ins_cnt) {
@@ -85,6 +121,7 @@ static uint32_t hreg_compute_pmu_hflags_mask(CPUPPCState *env)
85121
hflags_mask |= 1 << HFLAGS_PMCJCE;
86122
hflags_mask |= 1 << HFLAGS_INSN_CNT;
87123
hflags_mask |= 1 << HFLAGS_PMC_OTHER;
124+
hflags_mask |= 1 << HFLAGS_BHRB_ENABLE;
88125
#endif
89126
return hflags_mask;
90127
}

target/ppc/machine.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ static int cpu_post_load(void *opaque, int version_id)
333333
* triggered types (including HDEC) would need to carry more state.
334334
*/
335335
cpu_ppc_store_decr(env, env->spr[SPR_DECR]);
336-
pmu_mmcr01_updated(env);
336+
pmu_mmcr01a_updated(env);
337337
}
338338

339339
return 0;

target/ppc/power8-pmu-regs.c.inc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,11 @@ void spr_write_MMCR2_ureg(DisasContext *ctx, int sprn, int gprn)
175175
gen_store_spr(SPR_POWER_MMCR2, masked_gprn);
176176
}
177177

178+
void spr_write_MMCRA(DisasContext *ctx, int sprn, int gprn)
179+
{
180+
gen_helper_store_mmcrA(tcg_env, cpu_gpr[gprn]);
181+
}
182+
178183
void spr_read_PMC(DisasContext *ctx, int gprn, int sprn)
179184
{
180185
TCGv_i32 t_sprn = tcg_constant_i32(sprn);

target/ppc/power8-pmu.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ static void pmu_update_summaries(CPUPPCState *env)
8282
env->pmc_cyc_cnt = cyc_cnt;
8383
}
8484

85-
void pmu_mmcr01_updated(CPUPPCState *env)
85+
void pmu_mmcr01a_updated(CPUPPCState *env)
8686
{
8787
PowerPCCPU *cpu = env_archcpu(env);
8888

@@ -260,7 +260,7 @@ void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
260260

261261
env->spr[SPR_POWER_MMCR0] = value;
262262

263-
pmu_mmcr01_updated(env);
263+
pmu_mmcr01a_updated(env);
264264

265265
/* Update cycle overflow timers with the current MMCR0 state */
266266
pmu_update_overflow_timers(env);
@@ -272,7 +272,14 @@ void helper_store_mmcr1(CPUPPCState *env, uint64_t value)
272272

273273
env->spr[SPR_POWER_MMCR1] = value;
274274

275-
pmu_mmcr01_updated(env);
275+
pmu_mmcr01a_updated(env);
276+
}
277+
278+
void helper_store_mmcrA(CPUPPCState *env, uint64_t value)
279+
{
280+
env->spr[SPR_POWER_MMCRA] = value;
281+
282+
pmu_mmcr01a_updated(env);
276283
}
277284

278285
target_ulong helper_read_pmc(CPUPPCState *env, uint32_t sprn)
@@ -301,7 +308,7 @@ static void perfm_alert(PowerPCCPU *cpu)
301308
env->spr[SPR_POWER_MMCR0] |= MMCR0_FC;
302309

303310
/* Changing MMCR0_FC requires summaries and hflags update */
304-
pmu_mmcr01_updated(env);
311+
pmu_mmcr01a_updated(env);
305312

306313
/*
307314
* Delete all pending timers if we need to freeze

target/ppc/power8-pmu.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
#define PMC_COUNTER_NEGATIVE_VAL 0x80000000UL
1919

2020
void cpu_ppc_pmu_init(CPUPPCState *env);
21-
void pmu_mmcr01_updated(CPUPPCState *env);
21+
void pmu_mmcr01a_updated(CPUPPCState *env);
2222
#else
2323
static inline void cpu_ppc_pmu_init(CPUPPCState *env) { }
24-
static inline void pmu_mmcr01_updated(CPUPPCState *env) { }
24+
static inline void pmu_mmcr01a_updated(CPUPPCState *env) { }
2525
#endif
2626

2727
#endif

target/ppc/spr_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ void spr_write_generic32(DisasContext *ctx, int sprn, int gprn);
8585
void spr_core_write_generic(DisasContext *ctx, int sprn, int gprn);
8686
void spr_write_MMCR0(DisasContext *ctx, int sprn, int gprn);
8787
void spr_write_MMCR1(DisasContext *ctx, int sprn, int gprn);
88+
void spr_write_MMCRA(DisasContext *ctx, int sprn, int gprn);
8889
void spr_write_PMC(DisasContext *ctx, int sprn, int gprn);
8990
void spr_write_CTRL(DisasContext *ctx, int sprn, int gprn);
9091
void spr_read_xer(DisasContext *ctx, int gprn, int sprn);

target/ppc/translate.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ struct DisasContext {
193193
bool mmcr0_pmcjce;
194194
bool pmc_other;
195195
bool pmu_insn_cnt;
196+
bool bhrb_enable;
196197
ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
197198
int singlestep_enabled;
198199
uint32_t flags;
@@ -6345,6 +6346,7 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
63456346
ctx->mmcr0_pmcjce = (hflags >> HFLAGS_PMCJCE) & 1;
63466347
ctx->pmc_other = (hflags >> HFLAGS_PMC_OTHER) & 1;
63476348
ctx->pmu_insn_cnt = (hflags >> HFLAGS_INSN_CNT) & 1;
6349+
ctx->bhrb_enable = (hflags >> HFLAGS_BHRB_ENABLE) & 1;
63486350

63496351
ctx->singlestep_enabled = 0;
63506352
if ((hflags >> HFLAGS_SE) & 1) {

0 commit comments

Comments
 (0)