diff mbox series

[RFC,2/5] target/ppc: Add initial flags and helpers for SMT support

Message ID 20230531012313.19891-3-npiggin@gmail.com (mailing list archive)
State New, archived
Headers show
Series target/ppc: initial SMT support in TCG | expand

Commit Message

Nicholas Piggin May 31, 2023, 1:23 a.m. UTC
SMT TCG emulation needs to be able to iterate over siblings in a core,
and needs to serialise core access to shared SPRs and state.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/cpu.h       |  9 +++++++++
 target/ppc/cpu_init.c  |  5 +++++
 target/ppc/translate.c | 20 ++++++++++++++++++++
 3 files changed, 34 insertions(+)

Comments

Cédric Le Goater May 31, 2023, 7:25 a.m. UTC | #1
On 5/31/23 03:23, Nicholas Piggin wrote:
> SMT TCG emulation needs to be able to iterate over siblings in a core,
> and needs to serialise core access to shared SPRs and state.
> 
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
>   target/ppc/cpu.h       |  9 +++++++++
>   target/ppc/cpu_init.c  |  5 +++++
>   target/ppc/translate.c | 20 ++++++++++++++++++++
>   3 files changed, 34 insertions(+)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 1f23b81e90..b594408a8d 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -672,6 +672,8 @@ enum {
>       POWERPC_FLAG_TM       = 0x00100000,
>       /* Has SCV (ISA 3.00)                                                    */
>       POWERPC_FLAG_SCV      = 0x00200000,
> +    /* Has >1 thread per core                                                */
> +    POWERPC_FLAG_SMT      = 0x00400000,
>   };
>   
>   /*
> @@ -1266,6 +1268,13 @@ struct CPUArchState {
>       uint64_t pmu_base_time;
>   };
>   
> +#define _CORE_ID(cs)                                            \
> +    (POWERPC_CPU(cs)->env.spr_cb[SPR_PIR].default_value & ~(cs->nr_threads - 1))
> +
> +#define THREAD_SIBLING_FOREACH(cs, cs_sibling)			\
> +    CPU_FOREACH(cs_sibling)                                     \
> +        if (_CORE_ID(cs) == _CORE_ID(cs_sibling))
> +


May be introduce these helpers when needed (and if needed).

>   #define SET_FIT_PERIOD(a_, b_, c_, d_)          \
>   do {                                            \
>       env->fit_period[0] = (a_);                  \
> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> index aa364f36f6..5035f6dada 100644
> --- a/target/ppc/cpu_init.c
> +++ b/target/ppc/cpu_init.c
> @@ -6754,6 +6754,7 @@ static void ppc_cpu_realize(DeviceState *dev, Error **errp)
>   {
>       CPUState *cs = CPU(dev);
>       PowerPCCPU *cpu = POWERPC_CPU(dev);
> +    CPUPPCState *env = &cpu->env;
>       PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>       Error *local_err = NULL;
>   
> @@ -6785,6 +6786,10 @@ static void ppc_cpu_realize(DeviceState *dev, Error **errp)
>   
>       pcc->parent_realize(dev, errp);
>   
> +    if (env_cpu(env)->nr_threads > 1) {
> +        env->flags |= POWERPC_FLAG_SMT;
> +    }
> +
>       return;
>   
>   unrealize:
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index b6bab4c234..72270c2163 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -227,6 +227,26 @@ struct opc_handler_t {
>       void (*handler)(DisasContext *ctx);
>   };
>   
> +static inline bool gen_serialize(DisasContext *ctx)
> +{
> +    if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
> +        /* Restart with exclusive lock.  */
> +        gen_helper_exit_atomic(cpu_env);
> +        ctx->base.is_jmp = DISAS_NORETURN;
> +        return false;
> +    }
> +    return true;
> +}
> +
> +static inline bool gen_serialize_core(DisasContext *ctx)
> +{
> +    if (ctx->flags & POWERPC_FLAG_SMT) {
> +        return gen_serialize(ctx);
> +    }
> +
> +    return true;
> +}
> +
>   /* SPR load/store helpers */
>   static inline void gen_load_spr(TCGv t, int reg)
>   {
Nicholas Piggin June 2, 2023, 6:54 a.m. UTC | #2
On Wed May 31, 2023 at 5:25 PM AEST, Cédric Le Goater wrote:
> On 5/31/23 03:23, Nicholas Piggin wrote:
> > SMT TCG emulation needs to be able to iterate over siblings in a core,
> > and needs to serialise core access to shared SPRs and state.
> > 
> > Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> > ---
> >   target/ppc/cpu.h       |  9 +++++++++
> >   target/ppc/cpu_init.c  |  5 +++++
> >   target/ppc/translate.c | 20 ++++++++++++++++++++
> >   3 files changed, 34 insertions(+)
> > 
> > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> > index 1f23b81e90..b594408a8d 100644
> > --- a/target/ppc/cpu.h
> > +++ b/target/ppc/cpu.h
> > @@ -672,6 +672,8 @@ enum {
> >       POWERPC_FLAG_TM       = 0x00100000,
> >       /* Has SCV (ISA 3.00)                                                    */
> >       POWERPC_FLAG_SCV      = 0x00200000,
> > +    /* Has >1 thread per core                                                */
> > +    POWERPC_FLAG_SMT      = 0x00400000,
> >   };
> >   
> >   /*
> > @@ -1266,6 +1268,13 @@ struct CPUArchState {
> >       uint64_t pmu_base_time;
> >   };
> >   
> > +#define _CORE_ID(cs)                                            \
> > +    (POWERPC_CPU(cs)->env.spr_cb[SPR_PIR].default_value & ~(cs->nr_threads - 1))
> > +
> > +#define THREAD_SIBLING_FOREACH(cs, cs_sibling)			\
> > +    CPU_FOREACH(cs_sibling)                                     \
> > +        if (_CORE_ID(cs) == _CORE_ID(cs_sibling))
> > +
>
>
> May be introduce these helpers when needed (and if needed).

Yeah that's a good idea, I tried to structure it so you could see
the main components first, but for a real patch it might indeed be
better add them as needed.

Thanks,
Nick
diff mbox series

Patch

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 1f23b81e90..b594408a8d 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -672,6 +672,8 @@  enum {
     POWERPC_FLAG_TM       = 0x00100000,
     /* Has SCV (ISA 3.00)                                                    */
     POWERPC_FLAG_SCV      = 0x00200000,
+    /* Has >1 thread per core                                                */
+    POWERPC_FLAG_SMT      = 0x00400000,
 };
 
 /*
@@ -1266,6 +1268,13 @@  struct CPUArchState {
     uint64_t pmu_base_time;
 };
 
+#define _CORE_ID(cs)                                            \
+    (POWERPC_CPU(cs)->env.spr_cb[SPR_PIR].default_value & ~(cs->nr_threads - 1))
+
+#define THREAD_SIBLING_FOREACH(cs, cs_sibling)			\
+    CPU_FOREACH(cs_sibling)                                     \
+        if (_CORE_ID(cs) == _CORE_ID(cs_sibling))
+
 #define SET_FIT_PERIOD(a_, b_, c_, d_)          \
 do {                                            \
     env->fit_period[0] = (a_);                  \
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index aa364f36f6..5035f6dada 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6754,6 +6754,7 @@  static void ppc_cpu_realize(DeviceState *dev, Error **errp)
 {
     CPUState *cs = CPU(dev);
     PowerPCCPU *cpu = POWERPC_CPU(dev);
+    CPUPPCState *env = &cpu->env;
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
     Error *local_err = NULL;
 
@@ -6785,6 +6786,10 @@  static void ppc_cpu_realize(DeviceState *dev, Error **errp)
 
     pcc->parent_realize(dev, errp);
 
+    if (env_cpu(env)->nr_threads > 1) {
+        env->flags |= POWERPC_FLAG_SMT;
+    }
+
     return;
 
 unrealize:
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index b6bab4c234..72270c2163 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -227,6 +227,26 @@  struct opc_handler_t {
     void (*handler)(DisasContext *ctx);
 };
 
+static inline bool gen_serialize(DisasContext *ctx)
+{
+    if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
+        /* Restart with exclusive lock.  */
+        gen_helper_exit_atomic(cpu_env);
+        ctx->base.is_jmp = DISAS_NORETURN;
+        return false;
+    }
+    return true;
+}
+
+static inline bool gen_serialize_core(DisasContext *ctx)
+{
+    if (ctx->flags & POWERPC_FLAG_SMT) {
+        return gen_serialize(ctx);
+    }
+
+    return true;
+}
+
 /* SPR load/store helpers */
 static inline void gen_load_spr(TCGv t, int reg)
 {