target/ppc: Add support for SMT CTRL register
A relatively simple case to begin with, CTRL is a SMT shared register where reads and writes need to synchronise against state changes by other threads in the core. Atomic serialisation operations are used to achieve this. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Reviewed-by: Cédric Le Goater <clg@kaod.org> Signed-off-by: Cédric Le Goater <clg@kaod.org>
This commit is contained in:
parent
b769d4c8f4
commit
c5d98a7b3d
@ -704,6 +704,8 @@ 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_write_CTRL, void, env, i32, tl)
|
||||
|
||||
DEF_HELPER_4(fscr_facility_check, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msr_facility_check, void, env, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_1(load_tbl, TCG_CALL_NO_RWG, tl, env)
|
||||
|
@ -43,6 +43,31 @@ void helper_store_dump_spr(CPUPPCState *env, uint32_t sprn)
|
||||
env->spr[sprn]);
|
||||
}
|
||||
|
||||
void helper_spr_write_CTRL(CPUPPCState *env, uint32_t sprn,
|
||||
target_ulong val)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
CPUState *ccs;
|
||||
uint32_t run = val & 1;
|
||||
uint32_t ts, ts_mask;
|
||||
|
||||
assert(sprn == SPR_CTRL);
|
||||
|
||||
env->spr[sprn] &= ~1U;
|
||||
env->spr[sprn] |= run;
|
||||
|
||||
ts_mask = ~(1U << (8 + env->spr[SPR_TIR]));
|
||||
ts = run << (8 + env->spr[SPR_TIR]);
|
||||
|
||||
THREAD_SIBLING_FOREACH(cs, ccs) {
|
||||
CPUPPCState *cenv = &POWERPC_CPU(ccs)->env;
|
||||
|
||||
cenv->spr[sprn] &= ts_mask;
|
||||
cenv->spr[sprn] |= ts;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef TARGET_PPC64
|
||||
static void raise_hv_fu_exception(CPUPPCState *env, uint32_t bit,
|
||||
const char *caller, uint32_t cause,
|
||||
|
@ -438,7 +438,7 @@ void spr_write_generic32(DisasContext *ctx, int sprn, int gprn)
|
||||
#endif
|
||||
}
|
||||
|
||||
void spr_write_CTRL(DisasContext *ctx, int sprn, int gprn)
|
||||
static void spr_write_CTRL_ST(DisasContext *ctx, int sprn, int gprn)
|
||||
{
|
||||
/* This does not implement >1 thread */
|
||||
TCGv t0 = tcg_temp_new();
|
||||
@ -447,6 +447,22 @@ void spr_write_CTRL(DisasContext *ctx, int sprn, int gprn)
|
||||
tcg_gen_shli_tl(t1, t0, 8); /* Duplicate the bit in TS */
|
||||
tcg_gen_or_tl(t1, t1, t0);
|
||||
gen_store_spr(sprn, t1);
|
||||
}
|
||||
|
||||
void spr_write_CTRL(DisasContext *ctx, int sprn, int gprn)
|
||||
{
|
||||
if (!(ctx->flags & POWERPC_FLAG_SMT)) {
|
||||
spr_write_CTRL_ST(ctx, sprn, gprn);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!gen_serialize(ctx)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gen_helper_spr_write_CTRL(cpu_env, tcg_constant_i32(sprn),
|
||||
cpu_gpr[gprn]);
|
||||
out:
|
||||
spr_store_dump_spr(sprn);
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user