Message ID | 20230703101700.24064-3-npiggin@gmail.com |
---|---|
State | New |
Headers | show |
Series | ppc/pnv: SMT support for powernv | expand |
On 7/3/23 12:16, Nicholas Piggin wrote: > HID is a per-core shared register, skiboot sets this (e.g., setting > HILE) on one thread and that must affect all threads of the core. > > Tested-by: Cédric Le Goater <clg@kaod.org> > Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Reviewed-by: Cédric Le Goater <clg@kaod.org> Thanks, C. > --- > target/ppc/cpu_init.c | 2 +- > target/ppc/helper.h | 1 + > target/ppc/misc_helper.c | 21 +++++++++++++++++++++ > target/ppc/spr_common.h | 1 + > target/ppc/translate.c | 16 ++++++++++++++++ > 5 files changed, 40 insertions(+), 1 deletion(-) > > diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c > index 905a59aea9..720aad9e05 100644 > --- a/target/ppc/cpu_init.c > +++ b/target/ppc/cpu_init.c > @@ -5638,7 +5638,7 @@ static void register_power_common_book4_sprs(CPUPPCState *env) > spr_register_hv(env, SPR_HID0, "HID0", > SPR_NOACCESS, SPR_NOACCESS, > SPR_NOACCESS, SPR_NOACCESS, > - &spr_read_generic, &spr_write_generic, > + &spr_read_generic, &spr_core_write_generic, > 0x00000000); > spr_register_hv(env, SPR_TSCR, "TSCR", > SPR_NOACCESS, SPR_NOACCESS, > diff --git a/target/ppc/helper.h b/target/ppc/helper.h > index 828f7844c8..abec6fe341 100644 > --- a/target/ppc/helper.h > +++ b/target/ppc/helper.h > @@ -704,6 +704,7 @@ DEF_HELPER_3(store_dcr, void, env, tl, tl) > > DEF_HELPER_2(load_dump_spr, void, env, i32) > DEF_HELPER_2(store_dump_spr, void, env, i32) > +DEF_HELPER_3(spr_core_write_generic, void, env, i32, tl) > DEF_HELPER_3(spr_write_CTRL, void, env, i32, tl) > > DEF_HELPER_4(fscr_facility_check, void, env, i32, i32, i32) > diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c > index 1f1af21f33..0da335472e 100644 > --- a/target/ppc/misc_helper.c > +++ b/target/ppc/misc_helper.c > @@ -43,6 +43,27 @@ void helper_store_dump_spr(CPUPPCState *env, uint32_t sprn) > env->spr[sprn]); > } > > +void helper_spr_core_write_generic(CPUPPCState *env, uint32_t sprn, > + target_ulong val) > +{ > + CPUState *cs = env_cpu(env); > + CPUState *ccs; > + uint32_t nr_threads = cs->nr_threads; > + uint32_t core_id = env->spr[SPR_PIR] & ~(nr_threads - 1); > + > + assert(core_id == env->spr[SPR_PIR] - env->spr[SPR_TIR]); > + > + if (nr_threads == 1) { > + env->spr[sprn] = val; > + return; > + } > + > + THREAD_SIBLING_FOREACH(cs, ccs) { > + CPUPPCState *cenv = &POWERPC_CPU(ccs)->env; > + cenv->spr[sprn] = val; > + } > +} > + > void helper_spr_write_CTRL(CPUPPCState *env, uint32_t sprn, > target_ulong val) > { > diff --git a/target/ppc/spr_common.h b/target/ppc/spr_common.h > index fbf52123b5..5995070eaf 100644 > --- a/target/ppc/spr_common.h > +++ b/target/ppc/spr_common.h > @@ -82,6 +82,7 @@ void spr_noaccess(DisasContext *ctx, int gprn, int sprn); > void spr_read_generic(DisasContext *ctx, int gprn, int sprn); > void spr_write_generic(DisasContext *ctx, int sprn, int gprn); > void spr_write_generic32(DisasContext *ctx, int sprn, int gprn); > +void spr_core_write_generic(DisasContext *ctx, int sprn, int gprn); > void spr_write_MMCR0(DisasContext *ctx, int sprn, int gprn); > void spr_write_MMCR1(DisasContext *ctx, int sprn, int gprn); > void spr_write_PMC(DisasContext *ctx, int sprn, int gprn); > diff --git a/target/ppc/translate.c b/target/ppc/translate.c > index 10598cde40..07c491df62 100644 > --- a/target/ppc/translate.c > +++ b/target/ppc/translate.c > @@ -448,6 +448,22 @@ void spr_write_generic32(DisasContext *ctx, int sprn, int gprn) > #endif > } > > +void spr_core_write_generic(DisasContext *ctx, int sprn, int gprn) > +{ > + if (!(ctx->flags & POWERPC_FLAG_SMT)) { > + spr_write_generic(ctx, sprn, gprn); > + return; > + } > + > + if (!gen_serialize(ctx)) { > + return; > + } > + > + gen_helper_spr_core_write_generic(cpu_env, tcg_constant_i32(sprn), > + cpu_gpr[gprn]); > + spr_store_dump_spr(sprn); > +} > + > static void spr_write_CTRL_ST(DisasContext *ctx, int sprn, int gprn) > { > /* This does not implement >1 thread */
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 905a59aea9..720aad9e05 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -5638,7 +5638,7 @@ static void register_power_common_book4_sprs(CPUPPCState *env) spr_register_hv(env, SPR_HID0, "HID0", SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_core_write_generic, 0x00000000); spr_register_hv(env, SPR_TSCR, "TSCR", SPR_NOACCESS, SPR_NOACCESS, diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 828f7844c8..abec6fe341 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -704,6 +704,7 @@ DEF_HELPER_3(store_dcr, void, env, tl, tl) DEF_HELPER_2(load_dump_spr, void, env, i32) DEF_HELPER_2(store_dump_spr, void, env, i32) +DEF_HELPER_3(spr_core_write_generic, void, env, i32, tl) DEF_HELPER_3(spr_write_CTRL, void, env, i32, tl) DEF_HELPER_4(fscr_facility_check, void, env, i32, i32, i32) diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index 1f1af21f33..0da335472e 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -43,6 +43,27 @@ void helper_store_dump_spr(CPUPPCState *env, uint32_t sprn) env->spr[sprn]); } +void helper_spr_core_write_generic(CPUPPCState *env, uint32_t sprn, + target_ulong val) +{ + CPUState *cs = env_cpu(env); + CPUState *ccs; + uint32_t nr_threads = cs->nr_threads; + uint32_t core_id = env->spr[SPR_PIR] & ~(nr_threads - 1); + + assert(core_id == env->spr[SPR_PIR] - env->spr[SPR_TIR]); + + if (nr_threads == 1) { + env->spr[sprn] = val; + return; + } + + THREAD_SIBLING_FOREACH(cs, ccs) { + CPUPPCState *cenv = &POWERPC_CPU(ccs)->env; + cenv->spr[sprn] = val; + } +} + void helper_spr_write_CTRL(CPUPPCState *env, uint32_t sprn, target_ulong val) { diff --git a/target/ppc/spr_common.h b/target/ppc/spr_common.h index fbf52123b5..5995070eaf 100644 --- a/target/ppc/spr_common.h +++ b/target/ppc/spr_common.h @@ -82,6 +82,7 @@ void spr_noaccess(DisasContext *ctx, int gprn, int sprn); void spr_read_generic(DisasContext *ctx, int gprn, int sprn); void spr_write_generic(DisasContext *ctx, int sprn, int gprn); void spr_write_generic32(DisasContext *ctx, int sprn, int gprn); +void spr_core_write_generic(DisasContext *ctx, int sprn, int gprn); void spr_write_MMCR0(DisasContext *ctx, int sprn, int gprn); void spr_write_MMCR1(DisasContext *ctx, int sprn, int gprn); void spr_write_PMC(DisasContext *ctx, int sprn, int gprn); diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 10598cde40..07c491df62 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -448,6 +448,22 @@ void spr_write_generic32(DisasContext *ctx, int sprn, int gprn) #endif } +void spr_core_write_generic(DisasContext *ctx, int sprn, int gprn) +{ + if (!(ctx->flags & POWERPC_FLAG_SMT)) { + spr_write_generic(ctx, sprn, gprn); + return; + } + + if (!gen_serialize(ctx)) { + return; + } + + gen_helper_spr_core_write_generic(cpu_env, tcg_constant_i32(sprn), + cpu_gpr[gprn]); + spr_store_dump_spr(sprn); +} + static void spr_write_CTRL_ST(DisasContext *ctx, int sprn, int gprn) { /* This does not implement >1 thread */