qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/14] target/ppc: Various TCG emulation patches
@ 2024-05-18  9:31 Nicholas Piggin
  2024-05-18  9:31 ` [PATCH 01/14] target/ppc: larx/stcx generation need only apply DEF_MEMOP() once Nicholas Piggin
                   ` (13 more replies)
  0 siblings, 14 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

This is a bunch of instruction and register additions, improved SMT
support, etc. for TCG.

Thanks,
Nick

Nicholas Piggin (14):
  target/ppc: larx/stcx generation need only apply DEF_MEMOP() once
  target/ppc: Remove redundant MEMOP_GET_SIZE macro
  target/ppc: Make checkstop actually stop the system
  target/ppc: improve checkstop logging
  target/ppc: Implement attn instruction on BookS 64-bit processors
  target/ppc: BookE DECAR SPR is 32-bit
  target/ppc: Wire up BookE ATB registers for e500 family
  target/ppc: Add PPR32 SPR
  target/ppc: add helper to write per-LPAR SPRs
  target/ppc: Add SMT support to simple SPRs
  target/ppc: Add SMT support to PTCR SPR
  target/ppc: Implement LDBAR, TTR SPRs
  target/ppc: Implement SPRC/SPRD SPRs
  target/ppc: add SMT support to msgsnd broadcast

 target/ppc/cpu.h                              |  32 +++-
 target/ppc/helper.h                           |   6 +-
 target/ppc/spr_common.h                       |   7 +
 target/ppc/cpu_init.c                         | 145 ++++++++++++++++--
 target/ppc/excp_helper.c                      | 114 ++++++++++----
 target/ppc/misc_helper.c                      |  82 +++++++++-
 target/ppc/translate.c                        | 101 ++++++++++--
 .../ppc/translate/processor-ctrl-impl.c.inc   |   2 +-
 8 files changed, 426 insertions(+), 63 deletions(-)

-- 
2.43.0



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 01/14] target/ppc: larx/stcx generation need only apply DEF_MEMOP() once
  2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
@ 2024-05-18  9:31 ` Nicholas Piggin
  2024-05-18 10:58   ` Richard Henderson
  2024-05-18  9:31 ` [PATCH 02/14] target/ppc: Remove redundant MEMOP_GET_SIZE macro Nicholas Piggin
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

Use DEF_MEMOP() consistently in larx and stcx. generation, and apply it
once when it's used rather than where the macros are expanded, to reduce
typing.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/translate.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index a8fd6ef3ae..0882fe2fd2 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -2913,7 +2913,7 @@ static void gen_load_locked(DisasContext *ctx, MemOp memop)
 
     gen_set_access_type(ctx, ACCESS_RES);
     gen_addr_reg_index(ctx, t0);
-    tcg_gen_qemu_ld_tl(gpr, t0, ctx->mem_idx, memop | MO_ALIGN);
+    tcg_gen_qemu_ld_tl(gpr, t0, ctx->mem_idx, DEF_MEMOP(memop) | MO_ALIGN);
     tcg_gen_mov_tl(cpu_reserve, t0);
     tcg_gen_movi_tl(cpu_reserve_length, memop_size(memop));
     tcg_gen_mov_tl(cpu_reserve_val, gpr);
@@ -2926,9 +2926,9 @@ static void gen_##name(DisasContext *ctx)  \
 }
 
 /* lwarx */
-LARX(lbarx, DEF_MEMOP(MO_UB))
-LARX(lharx, DEF_MEMOP(MO_UW))
-LARX(lwarx, DEF_MEMOP(MO_UL))
+LARX(lbarx, MO_UB)
+LARX(lharx, MO_UW)
+LARX(lwarx, MO_UL)
 
 static void gen_fetch_inc_conditional(DisasContext *ctx, MemOp memop,
                                       TCGv EA, TCGCond cond, int addend)
@@ -3173,15 +3173,15 @@ static void gen_##name(DisasContext *ctx)  \
     gen_conditional_store(ctx, memop);     \
 }
 
-STCX(stbcx_, DEF_MEMOP(MO_UB))
-STCX(sthcx_, DEF_MEMOP(MO_UW))
-STCX(stwcx_, DEF_MEMOP(MO_UL))
+STCX(stbcx_, MO_UB)
+STCX(sthcx_, MO_UW)
+STCX(stwcx_, MO_UL)
 
 #if defined(TARGET_PPC64)
 /* ldarx */
-LARX(ldarx, DEF_MEMOP(MO_UQ))
+LARX(ldarx, MO_UQ)
 /* stdcx. */
-STCX(stdcx_, DEF_MEMOP(MO_UQ))
+STCX(stdcx_, MO_UQ)
 
 /* lqarx */
 static void gen_lqarx(DisasContext *ctx)
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 02/14] target/ppc: Remove redundant MEMOP_GET_SIZE macro
  2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
  2024-05-18  9:31 ` [PATCH 01/14] target/ppc: larx/stcx generation need only apply DEF_MEMOP() once Nicholas Piggin
@ 2024-05-18  9:31 ` Nicholas Piggin
  2024-05-18  9:57   ` BALATON Zoltan
  2024-05-18 10:59   ` Richard Henderson
  2024-05-18  9:31 ` [PATCH 03/14] target/ppc: Make checkstop actually stop the system Nicholas Piggin
                   ` (11 subsequent siblings)
  13 siblings, 2 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

There is a memop_size() function for this.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/translate.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 0882fe2fd2..cf2404330b 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -2904,8 +2904,6 @@ static void gen_isync(DisasContext *ctx)
     ctx->base.is_jmp = DISAS_EXIT_UPDATE;
 }
 
-#define MEMOP_GET_SIZE(x)  (1 << ((x) & MO_SIZE))
-
 static void gen_load_locked(DisasContext *ctx, MemOp memop)
 {
     TCGv gpr = cpu_gpr[rD(ctx->opcode)];
@@ -2938,7 +2936,7 @@ static void gen_fetch_inc_conditional(DisasContext *ctx, MemOp memop,
     TCGv u = tcg_temp_new();
 
     tcg_gen_qemu_ld_tl(t, EA, ctx->mem_idx, memop);
-    tcg_gen_addi_tl(t2, EA, MEMOP_GET_SIZE(memop));
+    tcg_gen_addi_tl(t2, EA, memop_size(memop));
     tcg_gen_qemu_ld_tl(t2, t2, ctx->mem_idx, memop);
     tcg_gen_addi_tl(u, t, addend);
 
@@ -2948,7 +2946,7 @@ static void gen_fetch_inc_conditional(DisasContext *ctx, MemOp memop,
     tcg_gen_qemu_st_tl(u, EA, ctx->mem_idx, memop);
 
     /* RT = (t != t2 ? t : u = 1<<(s*8-1)) */
-    tcg_gen_movi_tl(u, 1 << (MEMOP_GET_SIZE(memop) * 8 - 1));
+    tcg_gen_movi_tl(u, 1 << (memop_size(memop) * 8 - 1));
     tcg_gen_movcond_tl(cond, cpu_gpr[rD(ctx->opcode)], t, t2, t, u);
 }
 
@@ -3110,7 +3108,7 @@ static void gen_st_atomic(DisasContext *ctx, MemOp memop)
             TCGv ea_plus_s = tcg_temp_new();
 
             tcg_gen_qemu_ld_tl(t, EA, ctx->mem_idx, memop);
-            tcg_gen_addi_tl(ea_plus_s, EA, MEMOP_GET_SIZE(memop));
+            tcg_gen_addi_tl(ea_plus_s, EA, memop_size(memop));
             tcg_gen_qemu_ld_tl(t2, ea_plus_s, ctx->mem_idx, memop);
             tcg_gen_movcond_tl(TCG_COND_EQ, s, t, t2, src, t);
             tcg_gen_movcond_tl(TCG_COND_EQ, s2, t, t2, src, t2);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 03/14] target/ppc: Make checkstop actually stop the system
  2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
  2024-05-18  9:31 ` [PATCH 01/14] target/ppc: larx/stcx generation need only apply DEF_MEMOP() once Nicholas Piggin
  2024-05-18  9:31 ` [PATCH 02/14] target/ppc: Remove redundant MEMOP_GET_SIZE macro Nicholas Piggin
@ 2024-05-18  9:31 ` Nicholas Piggin
  2024-05-18  9:31 ` [PATCH 04/14] target/ppc: improve checkstop logging Nicholas Piggin
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

checkstop state does not halt the system, interrupts continue to be
serviced, and other CPUs run. Make it stop the machine with
qemu_system_guest_panicked.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/excp_helper.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 2e3f36a3ef..fd00c044b5 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -19,6 +19,8 @@
 #include "qemu/osdep.h"
 #include "qemu/main-loop.h"
 #include "qemu/log.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/runstate.h"
 #include "cpu.h"
 #include "exec/exec-all.h"
 #include "internal.h"
@@ -425,6 +427,8 @@ static void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector,
 
 static void powerpc_mcheck_checkstop(CPUPPCState *env)
 {
+    /* KVM guests always have MSR[ME] enabled */
+#ifdef CONFIG_TCG
     CPUState *cs = env_cpu(env);
 
     if (FIELD_EX64(env->msr, MSR, ME)) {
@@ -437,9 +441,15 @@ static void powerpc_mcheck_checkstop(CPUPPCState *env)
     if (qemu_log_separate()) {
         qemu_log("Machine check while not allowed. "
                  "Entering checkstop state\n");
-    }
-    cs->halted = 1;
-    cpu_interrupt_exittb(cs);
+
+    /*
+     * This stops the machine and logs CPU state without killing QEMU
+     * (like cpu_abort()) so the machine can still be debugged (because
+     * it is often a guest error).
+     */
+    qemu_system_guest_panicked(NULL);
+    cpu_loop_exit_noexc(cs);
+#endif
 }
 
 static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 04/14] target/ppc: improve checkstop logging
  2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
                   ` (2 preceding siblings ...)
  2024-05-18  9:31 ` [PATCH 03/14] target/ppc: Make checkstop actually stop the system Nicholas Piggin
@ 2024-05-18  9:31 ` Nicholas Piggin
  2024-05-18  9:31 ` [PATCH 05/14] target/ppc: Implement attn instruction on BookS 64-bit processors Nicholas Piggin
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

Change the logging not to print to stderr as well, because a
checkstop is a guest error (or perhaps a simulated machine error)
rather than a QEMU error, so send it to the log.

Update the checkstop message, and log CPU registers too.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/excp_helper.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index fd00c044b5..a283c97717 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -430,17 +430,19 @@ static void powerpc_mcheck_checkstop(CPUPPCState *env)
     /* KVM guests always have MSR[ME] enabled */
 #ifdef CONFIG_TCG
     CPUState *cs = env_cpu(env);
+    FILE *f;
 
     if (FIELD_EX64(env->msr, MSR, ME)) {
         return;
     }
 
-    /* Machine check exception is not enabled. Enter checkstop state. */
-    fprintf(stderr, "Machine check while not allowed. "
-            "Entering checkstop state\n");
-    if (qemu_log_separate()) {
-        qemu_log("Machine check while not allowed. "
-                 "Entering checkstop state\n");
+    f = qemu_log_trylock();
+    if (f) {
+        fprintf(f, "Entering checkstop state: "
+                   "machine check with MSR[ME]=0\n");
+        cpu_dump_state(cs, f, CPU_DUMP_FPU | CPU_DUMP_CCOP);
+        qemu_log_unlock(f);
+    }
 
     /*
      * This stops the machine and logs CPU state without killing QEMU
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 05/14] target/ppc: Implement attn instruction on BookS 64-bit processors
  2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
                   ` (3 preceding siblings ...)
  2024-05-18  9:31 ` [PATCH 04/14] target/ppc: improve checkstop logging Nicholas Piggin
@ 2024-05-18  9:31 ` Nicholas Piggin
  2024-05-18 11:05   ` Richard Henderson
  2024-05-18 11:07   ` Richard Henderson
  2024-05-18  9:31 ` [PATCH 06/14] target/ppc: BookE DECAR SPR is 32-bit Nicholas Piggin
                   ` (8 subsequent siblings)
  13 siblings, 2 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

attn is an implementation-specific instruction that on POWER (and G5/
970) can be enabled with a HID bit (disabled = illegal), and executing
it causes the host processor to stop and the service processor to be
notified. Generally used for debugging.

Implement attn and make it checkstop the system, which should be good
enough for QEMU debugging.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/cpu.h         | 16 +++++++-
 target/ppc/helper.h      |  1 +
 target/ppc/cpu_init.c    | 82 +++++++++++++++++++++++++++++++++++++---
 target/ppc/excp_helper.c | 39 +++++++++++++++----
 target/ppc/translate.c   | 11 ++++++
 5 files changed, 135 insertions(+), 14 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index c358927211..2f7fab22ba 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1375,6 +1375,9 @@ struct CPUArchState {
     /* Power management */
     int (*check_pow)(CPUPPCState *env);
 
+    /* attn instruction enable */
+    int (*check_attn)(CPUPPCState *env);
+
 #if !defined(CONFIG_USER_ONLY)
     void *load_info;  /* holds boot loading state */
 #endif
@@ -1523,6 +1526,7 @@ struct PowerPCCPUClass {
     int n_host_threads;
     void (*init_proc)(CPUPPCState *env);
     int  (*check_pow)(CPUPPCState *env);
+    int  (*check_attn)(CPUPPCState *env);
 };
 
 ObjectClass *ppc_cpu_class_by_name(const char *name);
@@ -2320,6 +2324,8 @@ void ppc_compat_add_property(Object *obj, const char *name,
 #define HID0_NAP            (1 << 22)           /* pre-2.06 */
 #define HID0_HILE           PPC_BIT(19) /* POWER8 */
 #define HID0_POWER9_HILE    PPC_BIT(4)
+#define HID0_ENABLE_ATTN    PPC_BIT(31) /* POWER8 */
+#define HID0_POWER9_ENABLE_ATTN PPC_BIT(3)
 
 /*****************************************************************************/
 /* PowerPC Instructions types definitions                                    */
@@ -2516,6 +2522,8 @@ enum {
     PPC2_MEM_LWSYNC    = 0x0000000000200000ULL,
     /* ISA 2.06 BCD assist instructions                                      */
     PPC2_BCDA_ISA206   = 0x0000000000400000ULL,
+    /* attn instruction found in IBM POWER (including 970)                   */
+    PPC2_ATTN          = 0x0000000000800000ULL,
 
 #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
                         PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
@@ -2525,7 +2533,7 @@ enum {
                         PPC2_ALTIVEC_207 | PPC2_ISA207S | PPC2_DFP | \
                         PPC2_FP_CVT_S64 | PPC2_TM | PPC2_PM_ISA206 | \
                         PPC2_ISA300 | PPC2_ISA310 | PPC2_MEM_LWSYNC | \
-                        PPC2_BCDA_ISA206)
+                        PPC2_BCDA_ISA206 | PPC2_ATTN)
 };
 
 /*****************************************************************************/
@@ -3025,6 +3033,12 @@ static inline int check_pow_nocheck(CPUPPCState *env)
     return 1;
 }
 
+/* attn enable check                                                         */
+static inline int check_attn_none(CPUPPCState *env)
+{
+    return 0;
+}
+
 /*****************************************************************************/
 /* PowerPC implementations definitions                                       */
 
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 55293e20a9..09d50f9b76 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -825,5 +825,6 @@ DEF_HELPER_FLAGS_1(fixup_thrm, TCG_CALL_NO_RWG, void, env)
 #if defined(TARGET_PPC64)
 DEF_HELPER_1(clrbhrb, void, env)
 DEF_HELPER_FLAGS_2(mfbhrbe, TCG_CALL_NO_WG, i64, env, i32)
+DEF_HELPER_1(attn, noreturn, env)
 #endif
 #endif
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 1ec84b5ddc..71da8d4856 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -2107,6 +2107,26 @@ static int check_pow_hid0_74xx(CPUPPCState *env)
     return 0;
 }
 
+#if defined(TARGET_PPC64)
+static int check_attn_hid0(CPUPPCState *env)
+{
+    if (env->spr[SPR_HID0] & HID0_ENABLE_ATTN) {
+        return 1;
+    }
+
+    return 0;
+}
+
+static int check_attn_hid0_power9(CPUPPCState *env)
+{
+    if (env->spr[SPR_HID0] & HID0_POWER9_ENABLE_ATTN) {
+        return 1;
+    }
+
+    return 0;
+}
+#endif
+
 static void init_proc_405(CPUPPCState *env)
 {
     register_40x_sprs(env);
@@ -2138,6 +2158,7 @@ POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 405";
     pcc->init_proc = init_proc_405;
     pcc->check_pow = check_pow_nocheck;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_DCR | PPC_WRTEE |
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
@@ -2210,6 +2231,7 @@ POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 440 EP";
     pcc->init_proc = init_proc_440EP;
     pcc->check_pow = check_pow_nocheck;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
                        PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -2248,6 +2270,7 @@ POWERPC_FAMILY(460EX)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 460 EX";
     pcc->init_proc = init_proc_440EP;
     pcc->check_pow = check_pow_nocheck;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
                        PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -2308,6 +2331,7 @@ POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 440 GP";
     pcc->init_proc = init_proc_440GP;
     pcc->check_pow = check_pow_nocheck;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
                        PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI |
                        PPC_CACHE | PPC_CACHE_ICBI |
@@ -2382,6 +2406,7 @@ POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 440x5";
     pcc->init_proc = init_proc_440x5;
     pcc->check_pow = check_pow_nocheck;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
                        PPC_DCR | PPC_WRTEE | PPC_RFMCI |
                        PPC_CACHE | PPC_CACHE_ICBI |
@@ -2417,6 +2442,7 @@ POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 440x5 with double precision FPU";
     pcc->init_proc = init_proc_440x5;
     pcc->check_pow = check_pow_nocheck;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
                        PPC_FLOAT | PPC_FLOAT_FSQRT |
                        PPC_FLOAT_STFIWX |
@@ -2465,6 +2491,7 @@ POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
     dc->desc = "Freescale 5xx cores (aka RCPU)";
     pcc->init_proc = init_proc_MPC5xx;
     pcc->check_pow = check_pow_none;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
                        PPC_MEM_EIEIO | PPC_MEM_SYNC |
                        PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX |
@@ -2507,6 +2534,7 @@ POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
     dc->desc = "Freescale 8xx cores (aka PowerQUICC)";
     pcc->init_proc = init_proc_MPC8xx;
     pcc->check_pow = check_pow_none;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING  |
                        PPC_MEM_EIEIO | PPC_MEM_SYNC |
                        PPC_CACHE_ICBI | PPC_MFTB;
@@ -2557,6 +2585,7 @@ POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC G2";
     pcc->init_proc = init_proc_G2;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_STFIWX |
@@ -2595,6 +2624,7 @@ POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC G2LE";
     pcc->init_proc = init_proc_G2;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_STFIWX |
@@ -2741,6 +2771,7 @@ POWERPC_FAMILY(e200)(ObjectClass *oc, void *data)
     dc->desc = "e200 core";
     pcc->init_proc = init_proc_e200;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     /*
      * XXX: unimplemented instructions:
      * dcblc
@@ -3029,6 +3060,7 @@ POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data)
     dc->desc = "e500v1 core";
     pcc->init_proc = init_proc_e500v1;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
                        PPC_SPE | PPC_SPE_SINGLE |
                        PPC_WRTEE | PPC_RFDI |
@@ -3072,6 +3104,7 @@ POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data)
     dc->desc = "e500v2 core";
     pcc->init_proc = init_proc_e500v2;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
                        PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE |
                        PPC_WRTEE | PPC_RFDI |
@@ -3115,6 +3148,7 @@ POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data)
     dc->desc = "e500mc core";
     pcc->init_proc = init_proc_e500mc;
     pcc->check_pow = check_pow_none;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
                        PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
                        PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
@@ -3161,6 +3195,7 @@ POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
     dc->desc = "e5500 core";
     pcc->init_proc = init_proc_e5500;
     pcc->check_pow = check_pow_none;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
                        PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
                        PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
@@ -3209,6 +3244,7 @@ POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data)
     dc->desc = "e6500 core";
     pcc->init_proc = init_proc_e6500;
     pcc->check_pow = check_pow_none;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
                        PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
                        PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
@@ -3271,6 +3307,7 @@ POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 603";
     pcc->init_proc = init_proc_603;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
@@ -3310,6 +3347,7 @@ POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 603e";
     pcc->init_proc = init_proc_603;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
@@ -3355,6 +3393,7 @@ POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
     dc->desc = "e300 core";
     pcc->init_proc = init_proc_e300;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_STFIWX |
@@ -3410,6 +3449,7 @@ POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 604";
     pcc->init_proc = init_proc_604;
     pcc->check_pow = check_pow_nocheck;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
@@ -3455,6 +3495,7 @@ POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 604E";
     pcc->init_proc = init_proc_604E;
     pcc->check_pow = check_pow_nocheck;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
@@ -3511,6 +3552,7 @@ POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 740";
     pcc->init_proc = init_proc_740;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
@@ -3576,6 +3618,7 @@ POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 750";
     pcc->init_proc = init_proc_750;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
@@ -3722,6 +3765,7 @@ POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 750 CL";
     pcc->init_proc = init_proc_750cl;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     /*
      * XXX: not implemented:
      * cache lock instructions:
@@ -3829,6 +3873,7 @@ POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 750CX";
     pcc->init_proc = init_proc_750cx;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
@@ -3901,6 +3946,7 @@ POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 750FX";
     pcc->init_proc = init_proc_750fx;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
@@ -3973,6 +4019,7 @@ POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 750GX";
     pcc->init_proc = init_proc_750gx;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
@@ -4032,6 +4079,7 @@ POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 745";
     pcc->init_proc = init_proc_745;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
@@ -4077,6 +4125,7 @@ POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 755";
     pcc->init_proc = init_proc_755;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
@@ -4143,6 +4192,7 @@ POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 7400 (aka G4)";
     pcc->init_proc = init_proc_7400;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -4222,6 +4272,7 @@ POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 7410 (aka G4)";
     pcc->init_proc = init_proc_7410;
     pcc->check_pow = check_pow_hid0;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -4322,6 +4373,7 @@ POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 7440 (aka G4)";
     pcc->init_proc = init_proc_7440;
     pcc->check_pow = check_pow_hid0_74xx;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -4444,6 +4496,7 @@ POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 7450 (aka G4)";
     pcc->init_proc = init_proc_7450;
     pcc->check_pow = check_pow_hid0_74xx;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -4573,6 +4626,7 @@ POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 7445 (aka G4)";
     pcc->init_proc = init_proc_7445;
     pcc->check_pow = check_pow_hid0_74xx;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -4704,6 +4758,7 @@ POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 7455 (aka G4)";
     pcc->init_proc = init_proc_7455;
     pcc->check_pow = check_pow_hid0_74xx;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -4855,6 +4910,7 @@ POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 7457 (aka G4)";
     pcc->init_proc = init_proc_7457;
     pcc->check_pow = check_pow_hid0_74xx;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -4989,6 +5045,7 @@ POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC e600";
     pcc->init_proc = init_proc_e600;
     pcc->check_pow = check_pow_hid0_74xx;
+    pcc->check_attn = check_attn_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -5904,6 +5961,7 @@ POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
     dc->desc = "PowerPC 970";
     pcc->init_proc = init_proc_970;
     pcc->check_pow = check_pow_970;
+    pcc->check_attn = check_attn_hid0;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -5913,7 +5971,7 @@ POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_64B | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI;
-    pcc->insns_flags2 = PPC2_FP_CVT_S64 | PPC2_MEM_LWSYNC;
+    pcc->insns_flags2 = PPC2_FP_CVT_S64 | PPC2_MEM_LWSYNC | PPC2_ATTN;
     pcc->msr_mask = (1ull << MSR_SF) |
                     (1ull << MSR_VR) |
                     (1ull << MSR_POW) |
@@ -5979,6 +6037,7 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
     dc->desc = "POWER5+";
     pcc->init_proc = init_proc_power5plus;
     pcc->check_pow = check_pow_970;
+    pcc->check_attn = check_attn_hid0;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -5990,7 +6049,7 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
                        PPC_64B |
                        PPC_POPCNTB |
                        PPC_SEGMENT_64B | PPC_SLBI;
-    pcc->insns_flags2 = PPC2_FP_CVT_S64 | PPC2_MEM_LWSYNC;
+    pcc->insns_flags2 = PPC2_FP_CVT_S64 | PPC2_MEM_LWSYNC | PPC2_ATTN;
     pcc->msr_mask = (1ull << MSR_SF) |
                     (1ull << MSR_VR) |
                     (1ull << MSR_POW) |
@@ -6086,6 +6145,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
     pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
     pcc->init_proc = init_proc_POWER7;
     pcc->check_pow = check_pow_nocheck;
+    pcc->check_attn = check_attn_hid0;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -6103,7 +6163,8 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
                         PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
                         PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 |
-                        PPC2_PM_ISA206 | PPC2_MEM_LWSYNC | PPC2_BCDA_ISA206;
+                        PPC2_PM_ISA206 | PPC2_MEM_LWSYNC | PPC2_BCDA_ISA206 |
+                        PPC2_ATTN;
     pcc->msr_mask = (1ull << MSR_SF) |
                     (1ull << MSR_VR) |
                     (1ull << MSR_VSX) |
@@ -6247,6 +6308,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
     pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
     pcc->init_proc = init_proc_POWER8;
     pcc->check_pow = check_pow_nocheck;
+    pcc->check_attn = check_attn_hid0;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -6267,7 +6329,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                         PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
                         PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
                         PPC2_TM | PPC2_PM_ISA206 | PPC2_MEM_LWSYNC |
-                        PPC2_BCDA_ISA206;
+                        PPC2_BCDA_ISA206 | PPC2_ATTN;
     pcc->msr_mask = (1ull << MSR_SF) |
                     (1ull << MSR_HV) |
                     (1ull << MSR_TM) |
@@ -6439,6 +6501,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
                          PCR_COMPAT_2_05;
     pcc->init_proc = init_proc_POWER9;
     pcc->check_pow = check_pow_nocheck;
+    pcc->check_attn = check_attn_hid0_power9;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -6459,7 +6522,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
                         PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
                         PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
                         PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL | PPC2_MEM_LWSYNC |
-                        PPC2_BCDA_ISA206;
+                        PPC2_BCDA_ISA206 | PPC2_ATTN;
     pcc->msr_mask = (1ull << MSR_SF) |
                     (1ull << MSR_HV) |
                     (1ull << MSR_TM) |
@@ -6618,6 +6681,7 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
                          PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
     pcc->init_proc = init_proc_POWER10;
     pcc->check_pow = check_pow_nocheck;
+    pcc->check_attn = check_attn_hid0_power9;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -6638,7 +6702,7 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
                         PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
                         PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
                         PPC2_ISA300 | PPC2_PRCNTL | PPC2_ISA310 |
-                        PPC2_MEM_LWSYNC | PPC2_BCDA_ISA206;
+                        PPC2_MEM_LWSYNC | PPC2_BCDA_ISA206 | PPC2_ATTN;
     pcc->msr_mask = (1ull << MSR_SF) |
                     (1ull << MSR_HV) |
                     (1ull << MSR_VR) |
@@ -6856,6 +6920,11 @@ static void init_ppc_proc(PowerPCCPU *cpu)
         warn_report("no power management check handler registered."
                     " Attempt QEMU to crash very soon !");
     }
+
+    if (env->check_attn == NULL) {
+        warn_report("no attn check handler registered."
+                    " Attempt QEMU to crash very soon !");
+    }
 }
 
 
@@ -7317,6 +7386,7 @@ static void ppc_cpu_instance_init(Object *obj)
     env->flags = pcc->flags;
     env->bfd_mach = pcc->bfd_mach;
     env->check_pow = pcc->check_pow;
+    env->check_attn = pcc->check_attn;
 
     /*
      * Mark HV mode as supported if the CPU has an MSR_HV bit in the
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index a283c97717..28f2ab4583 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -154,6 +154,7 @@ static uint32_t ppc_ldl_code(CPUArchState *env, target_ulong addr)
 
     return insn;
 }
+
 #endif
 
 static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp)
@@ -425,17 +426,17 @@ static void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector,
     env->reserve_addr = -1;
 }
 
-static void powerpc_mcheck_checkstop(CPUPPCState *env)
-{
-    /* KVM guests always have MSR[ME] enabled */
 #ifdef CONFIG_TCG
+/*
+ * This stops the machine and logs CPU state without killing QEMU (like
+ * cpu_abort()) because it is often a guest error as opposed to a QEMU error,
+ * so the machine can still be debugged.
+ */
+static G_NORETURN void powerpc_checkstop(CPUPPCState *env, const char *reason)
+{
     CPUState *cs = env_cpu(env);
     FILE *f;
 
-    if (FIELD_EX64(env->msr, MSR, ME)) {
-        return;
-    }
-
     f = qemu_log_trylock();
     if (f) {
         fprintf(f, "Entering checkstop state: "
@@ -451,6 +452,30 @@ static void powerpc_mcheck_checkstop(CPUPPCState *env)
      */
     qemu_system_guest_panicked(NULL);
     cpu_loop_exit_noexc(cs);
+}
+
+#ifdef TARGET_PPC64
+void helper_attn(CPUPPCState *env)
+{
+    if ((*env->check_attn)(env)) {
+        powerpc_checkstop(env, "host executed attn");
+    } else {
+        raise_exception_err(env, POWERPC_EXCP_HV_EMU,
+                            POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
+    }
+}
+#endif
+#endif /* CONFIG_TCG */
+
+static void powerpc_mcheck_checkstop(CPUPPCState *env)
+{
+    /* KVM guests always have MSR[ME] enabled */
+#ifdef CONFIG_TCG
+    if (FIELD_EX64(env->msr, MSR, ME)) {
+        return;
+    }
+
+    powerpc_checkstop(env, "machine check with MSR[ME]=0");
 #endif
 }
 
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index cf2404330b..ee7f3ee5a2 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -5668,6 +5668,16 @@ static void gen_dform3D(DisasContext *ctx)
 }
 
 #if defined(TARGET_PPC64)
+/* attn */
+static void gen_attn(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+    GEN_PRIV(ctx);
+#else
+    gen_helper_attn(tcg_env);
+#endif
+}
+
 /* brd */
 static void gen_brd(DisasContext *ctx)
 {
@@ -5699,6 +5709,7 @@ static void gen_brh(DisasContext *ctx)
 
 static opcode_t opcodes[] = {
 #if defined(TARGET_PPC64)
+GEN_HANDLER_E(attn, 0x00, 0x00, 0x08, 0xFFFFFDFF, PPC_NONE, PPC2_ATTN),
 GEN_HANDLER_E(brd, 0x1F, 0x1B, 0x05, 0x0000F801, PPC_NONE, PPC2_ISA310),
 GEN_HANDLER_E(brw, 0x1F, 0x1B, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA310),
 GEN_HANDLER_E(brh, 0x1F, 0x1B, 0x06, 0x0000F801, PPC_NONE, PPC2_ISA310),
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 06/14] target/ppc: BookE DECAR SPR is 32-bit
  2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
                   ` (4 preceding siblings ...)
  2024-05-18  9:31 ` [PATCH 05/14] target/ppc: Implement attn instruction on BookS 64-bit processors Nicholas Piggin
@ 2024-05-18  9:31 ` Nicholas Piggin
  2024-05-18  9:31 ` [PATCH 07/14] target/ppc: Wire up BookE ATB registers for e500 family Nicholas Piggin
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

The DECAR SPR is 32-bits width.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/cpu_init.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 71da8d4856..462246cb7d 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -792,7 +792,7 @@ static void register_BookE_sprs(CPUPPCState *env, uint64_t ivor_mask)
                  0x00000000);
     spr_register(env, SPR_BOOKE_DECAR, "DECAR",
                  SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, &spr_write_generic,
+                 SPR_NOACCESS, &spr_write_generic32,
                  0x00000000);
     /* SPRGs */
     spr_register(env, SPR_USPRG0, "USPRG0",
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 07/14] target/ppc: Wire up BookE ATB registers for e500 family
  2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
                   ` (5 preceding siblings ...)
  2024-05-18  9:31 ` [PATCH 06/14] target/ppc: BookE DECAR SPR is 32-bit Nicholas Piggin
@ 2024-05-18  9:31 ` Nicholas Piggin
  2024-05-18  9:31 ` [PATCH 08/14] target/ppc: Add PPR32 SPR Nicholas Piggin
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

From the Freescale PowerPC Architecture Primer:

  Alternate time base APU. This APU, implemented on the e500v2, defines
  a 64-bit time base counter that differs from the PowerPC defined time
  base in that it is not writable and counts at a different, and
  typically much higher, frequency. The alternate time base always
  counts up, wrapping when the 64-bit count overflows.

This implementation of ATB uses the same frequency as the TB. The
existing spr_read_atbu/l functions are unused without this patch
to wire them into the SPR.

RTEMS uses this SPR on the e6500, though this hasn't been tested.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/cpu_init.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 462246cb7d..e186da5ef1 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -920,6 +920,18 @@ static void register_BookE206_sprs(CPUPPCState *env, uint32_t mas_mask,
 #endif
 }
 
+static void register_atb_sprs(CPUPPCState *env)
+{
+    spr_register(env, SPR_ATBL, "ATBL",
+                 &spr_read_atbl, SPR_NOACCESS,
+                 &spr_read_atbl, SPR_NOACCESS,
+                 0x00000000);
+    spr_register(env, SPR_ATBU, "ATBU",
+                 &spr_read_atbu, SPR_NOACCESS,
+                 &spr_read_atbu, SPR_NOACCESS,
+                 0x00000000);
+}
+
 /* SPR specific to PowerPC 440 implementation */
 static void register_440_sprs(CPUPPCState *env)
 {
@@ -2927,6 +2939,11 @@ static void init_proc_e500(CPUPPCState *env, int version)
     register_BookE206_sprs(env, 0x000000DF, tlbncfg, mmucfg);
     register_usprgh_sprs(env);
 
+    if (version != fsl_e500v1) {
+        /* e500v1 has no support for alternate timebase */
+        register_atb_sprs(env);
+    }
+
     spr_register(env, SPR_HID0, "HID0",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 08/14] target/ppc: Add PPR32 SPR
  2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
                   ` (6 preceding siblings ...)
  2024-05-18  9:31 ` [PATCH 07/14] target/ppc: Wire up BookE ATB registers for e500 family Nicholas Piggin
@ 2024-05-18  9:31 ` Nicholas Piggin
  2024-05-18  9:31 ` [PATCH 09/14] target/ppc: add helper to write per-LPAR SPRs Nicholas Piggin
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

PPR32 provides access to the upper half of PPR.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/cpu.h        |  1 +
 target/ppc/spr_common.h |  2 ++
 target/ppc/cpu_init.c   | 12 ++++++++++++
 target/ppc/translate.c  | 16 ++++++++++++++++
 4 files changed, 31 insertions(+)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 2f7fab22ba..9a51e54c1c 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -2120,6 +2120,7 @@ void ppc_compat_add_property(Object *obj, const char *name,
 #define SPR_POWER_MMCRS       (0x37E)
 #define SPR_WORT              (0x37F)
 #define SPR_PPR               (0x380)
+#define SPR_PPR32             (0x382)
 #define SPR_750_GQR0          (0x390)
 #define SPR_440_DNV0          (0x390)
 #define SPR_750_GQR1          (0x391)
diff --git a/target/ppc/spr_common.h b/target/ppc/spr_common.h
index eb2561f593..9e40b3b608 100644
--- a/target/ppc/spr_common.h
+++ b/target/ppc/spr_common.h
@@ -203,6 +203,8 @@ void spr_read_tfmr(DisasContext *ctx, int gprn, int sprn);
 void spr_write_tfmr(DisasContext *ctx, int sprn, int gprn);
 void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn);
 void spr_read_dexcr_ureg(DisasContext *ctx, int gprn, int sprn);
+void spr_read_ppr32(DisasContext *ctx, int sprn, int gprn);
+void spr_write_ppr32(DisasContext *ctx, int sprn, int gprn);
 #endif
 
 void register_low_BATs(CPUPPCState *env);
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index e186da5ef1..dd45251d7a 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -5623,6 +5623,14 @@ static void register_HEIR64_spr(CPUPPCState *env)
                  0x00000000);
 }
 
+static void register_power7_common_sprs(CPUPPCState *env)
+{
+    spr_register(env, SPR_PPR32, "PPR32",
+                 &spr_read_ppr32, &spr_write_ppr32,
+                 &spr_read_ppr32, &spr_write_ppr32,
+                 0x00000000);
+}
+
 static void register_power8_tce_address_control_sprs(CPUPPCState *env)
 {
     spr_register_kvm(env, SPR_TAR, "TAR",
@@ -6118,6 +6126,7 @@ static void init_proc_POWER7(CPUPPCState *env)
     register_power6_common_sprs(env);
     register_HEIR32_spr(env);
     register_power6_dbg_sprs(env);
+    register_power7_common_sprs(env);
     register_power7_book4_sprs(env);
 
     /* env variables */
@@ -6265,6 +6274,7 @@ static void init_proc_POWER8(CPUPPCState *env)
     register_power6_common_sprs(env);
     register_HEIR32_spr(env);
     register_power6_dbg_sprs(env);
+    register_power7_common_sprs(env);
     register_power8_tce_address_control_sprs(env);
     register_power8_ids_sprs(env);
     register_power8_ebb_sprs(env);
@@ -6432,6 +6442,7 @@ static void init_proc_POWER9(CPUPPCState *env)
     register_power6_common_sprs(env);
     register_HEIR32_spr(env);
     register_power6_dbg_sprs(env);
+    register_power7_common_sprs(env);
     register_power8_tce_address_control_sprs(env);
     register_power8_ids_sprs(env);
     register_power8_ebb_sprs(env);
@@ -6626,6 +6637,7 @@ static void init_proc_POWER10(CPUPPCState *env)
     register_power6_common_sprs(env);
     register_HEIR64_spr(env);
     register_power6_dbg_sprs(env);
+    register_power7_common_sprs(env);
     register_power8_tce_address_control_sprs(env);
     register_power8_ids_sprs(env);
     register_power8_ebb_sprs(env);
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index ee7f3ee5a2..c4b4f7ea62 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -1416,6 +1416,22 @@ void spr_read_dexcr_ureg(DisasContext *ctx, int gprn, int sprn)
     gen_load_spr(t0, sprn + 16);
     tcg_gen_ext32u_tl(cpu_gpr[gprn], t0);
 }
+
+/* The PPR32 SPR accesses the upper 32-bits of PPR */
+void spr_read_ppr32(DisasContext *ctx, int sprn, int gprn)
+{
+    gen_load_spr(cpu_gpr[gprn], SPR_PPR);
+    tcg_gen_shri_tl(cpu_gpr[gprn], cpu_gpr[gprn], 32);
+}
+
+void spr_write_ppr32(DisasContext *ctx, int sprn, int gprn)
+{
+    TCGv t0 = tcg_temp_new();
+
+    tcg_gen_shli_tl(t0, cpu_gpr[gprn], 32);
+    gen_store_spr(SPR_PPR, t0);
+    spr_store_dump_spr(SPR_PPR);
+}
 #endif
 
 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 09/14] target/ppc: add helper to write per-LPAR SPRs
  2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
                   ` (7 preceding siblings ...)
  2024-05-18  9:31 ` [PATCH 08/14] target/ppc: Add PPR32 SPR Nicholas Piggin
@ 2024-05-18  9:31 ` Nicholas Piggin
  2024-05-18 11:26   ` Richard Henderson
  2024-05-18  9:31 ` [PATCH 10/14] target/ppc: Add SMT support to simple SPRs Nicholas Piggin
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

An SPR can be either per-thread, per-core, or per-LPAR. Per-LPAR means
per-thread or per-core, depending on 1LPAR mode.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/spr_common.h |  2 ++
 target/ppc/translate.c  | 26 ++++++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/target/ppc/spr_common.h b/target/ppc/spr_common.h
index 9e40b3b608..85f73b860b 100644
--- a/target/ppc/spr_common.h
+++ b/target/ppc/spr_common.h
@@ -83,6 +83,8 @@ 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_core_write_generic32(DisasContext *ctx, int sprn, int gprn);
+void spr_core_lpar_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_MMCRA(DisasContext *ctx, int sprn, int gprn);
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index c4b4f7ea62..ccd90a5feb 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -537,6 +537,32 @@ void spr_core_write_generic(DisasContext *ctx, int sprn, int gprn)
     spr_store_dump_spr(sprn);
 }
 
+void spr_core_write_generic32(DisasContext *ctx, int sprn, int gprn)
+{
+    TCGv t0 = tcg_temp_new();
+    if (!(ctx->flags & POWERPC_FLAG_SMT)) {
+        spr_write_generic32(ctx, sprn, gprn);
+        return;
+    }
+
+    if (!gen_serialize(ctx)) {
+        return;
+    }
+
+    tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);
+    gen_helper_spr_core_write_generic(tcg_env, tcg_constant_i32(sprn), t0);
+    spr_store_dump_spr(sprn);
+}
+
+void spr_core_lpar_write_generic(DisasContext *ctx, int sprn, int gprn)
+{
+    if (ctx->flags & POWERPC_FLAG_SMT_1LPAR) {
+        spr_core_write_generic(ctx, sprn, gprn);
+    } else {
+        spr_write_generic(ctx, sprn, gprn);
+    }
+}
+
 static void spr_write_CTRL_ST(DisasContext *ctx, int sprn, int gprn)
 {
     /* This does not implement >1 thread */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 10/14] target/ppc: Add SMT support to simple SPRs
  2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
                   ` (8 preceding siblings ...)
  2024-05-18  9:31 ` [PATCH 09/14] target/ppc: add helper to write per-LPAR SPRs Nicholas Piggin
@ 2024-05-18  9:31 ` Nicholas Piggin
  2024-05-18  9:31 ` [PATCH 11/14] target/ppc: Add SMT support to PTCR SPR Nicholas Piggin
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

AMOR, MMCRC, HRMOR, TSCR, HMEER, RPR SPRs are per-core or per-LPAR
registers with simple (generic) implementations.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/cpu_init.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index dd45251d7a..dc6b4fc569 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -246,7 +246,7 @@ static void register_amr_sprs(CPUPPCState *env)
     spr_register_hv(env, SPR_AMOR, "AMOR",
                     SPR_NOACCESS, SPR_NOACCESS,
                     SPR_NOACCESS, SPR_NOACCESS,
-                    &spr_read_generic, &spr_write_generic,
+                    &spr_read_generic, &spr_core_lpar_write_generic,
                     0);
 #endif /* !CONFIG_USER_ONLY */
 }
@@ -5489,7 +5489,7 @@ static void register_book3s_ids_sprs(CPUPPCState *env)
     spr_register_hv(env, SPR_MMCRC, "MMCRC",
                  SPR_NOACCESS, SPR_NOACCESS,
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic32,
+                 &spr_read_generic, &spr_core_write_generic32,
                  0x00000000);
     spr_register_hv(env, SPR_MMCRH, "MMCRH",
                  SPR_NOACCESS, SPR_NOACCESS,
@@ -5529,7 +5529,7 @@ static void register_book3s_ids_sprs(CPUPPCState *env)
     spr_register_hv(env, SPR_HRMOR, "HRMOR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_generic, &spr_core_write_generic,
                  0x00000000);
 }
 
@@ -5757,7 +5757,7 @@ static void register_power_common_book4_sprs(CPUPPCState *env)
     spr_register_hv(env, SPR_TSCR, "TSCR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic32,
+                 &spr_read_generic, &spr_core_write_generic32,
                  0x00000000);
     spr_register_hv(env, SPR_HMER, "HMER",
                  SPR_NOACCESS, SPR_NOACCESS,
@@ -5767,7 +5767,7 @@ static void register_power_common_book4_sprs(CPUPPCState *env)
     spr_register_hv(env, SPR_HMEER, "HMEER",
                  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_TFMR, "TFMR",
                  SPR_NOACCESS, SPR_NOACCESS,
@@ -5843,7 +5843,7 @@ static void register_power8_rpr_sprs(CPUPPCState *env)
     spr_register_hv(env, SPR_RPR, "RPR",
                     SPR_NOACCESS, SPR_NOACCESS,
                     SPR_NOACCESS, SPR_NOACCESS,
-                    &spr_read_generic, &spr_write_generic,
+                    &spr_read_generic, &spr_core_write_generic,
                     0x00000103070F1F3F);
 #endif
 }
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 11/14] target/ppc: Add SMT support to PTCR SPR
  2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
                   ` (9 preceding siblings ...)
  2024-05-18  9:31 ` [PATCH 10/14] target/ppc: Add SMT support to simple SPRs Nicholas Piggin
@ 2024-05-18  9:31 ` Nicholas Piggin
  2024-05-18  9:31 ` [PATCH 12/14] target/ppc: Implement LDBAR, TTR SPRs Nicholas Piggin
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

PTCR is a per-core register.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/misc_helper.c | 16 ++++++++++++++--
 target/ppc/translate.c   |  4 ++++
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c
index 6f419c9346..a67930d031 100644
--- a/target/ppc/misc_helper.c
+++ b/target/ppc/misc_helper.c
@@ -173,6 +173,7 @@ void helper_store_sdr1(CPUPPCState *env, target_ulong val)
 void helper_store_ptcr(CPUPPCState *env, target_ulong val)
 {
     if (env->spr[SPR_PTCR] != val) {
+        CPUState *cs = env_cpu(env);
         PowerPCCPU *cpu = env_archcpu(env);
         target_ulong ptcr_mask = PTCR_PATB | PTCR_PATS;
         target_ulong patbsize = val & PTCR_PATS;
@@ -194,8 +195,19 @@ void helper_store_ptcr(CPUPPCState *env, target_ulong val)
             return;
         }
 
-        env->spr[SPR_PTCR] = val;
-        tlb_flush(env_cpu(env));
+        if (cs->nr_threads == 1 || !(env->flags & POWERPC_FLAG_SMT_1LPAR)) {
+            env->spr[SPR_PTCR] = val;
+            tlb_flush(cs);
+        } else {
+            CPUState *ccs;
+
+            THREAD_SIBLING_FOREACH(cs, ccs) {
+                PowerPCCPU *ccpu = POWERPC_CPU(ccs);
+                CPUPPCState *cenv = &ccpu->env;
+                cenv->spr[SPR_PTCR] = val;
+                tlb_flush(ccs);
+            }
+        }
     }
 }
 
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index ccd90a5feb..60a7afb086 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -971,6 +971,10 @@ void spr_write_hior(DisasContext *ctx, int sprn, int gprn)
 }
 void spr_write_ptcr(DisasContext *ctx, int sprn, int gprn)
 {
+    if (!gen_serialize_core(ctx)) {
+        return;
+    }
+
     gen_helper_store_ptcr(tcg_env, cpu_gpr[gprn]);
 }
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 12/14] target/ppc: Implement LDBAR, TTR SPRs
  2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
                   ` (10 preceding siblings ...)
  2024-05-18  9:31 ` [PATCH 11/14] target/ppc: Add SMT support to PTCR SPR Nicholas Piggin
@ 2024-05-18  9:31 ` Nicholas Piggin
  2024-05-18  9:31 ` [PATCH 13/14] target/ppc: Implement SPRC/SPRD SPRs Nicholas Piggin
  2024-05-18  9:31 ` [PATCH 14/14] target/ppc: add SMT support to msgsnd broadcast Nicholas Piggin
  13 siblings, 0 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

LDBAR, TTR are a Power-specific SPRs. These simple implementations
are enough for IBM proprietary firmware for now.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/cpu.h      |  2 ++
 target/ppc/cpu_init.c | 10 ++++++++++
 2 files changed, 12 insertions(+)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 9a51e54c1c..a014efc23a 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -2098,6 +2098,7 @@ void ppc_compat_add_property(Object *obj, const char *name,
 #define SPR_DEXCR             (0x33C)
 #define SPR_IC                (0x350)
 #define SPR_VTB               (0x351)
+#define SPR_LDBAR             (0x352)
 #define SPR_MMCRC             (0x353)
 #define SPR_PSSCR             (0x357)
 #define SPR_440_INV0          (0x370)
@@ -2144,6 +2145,7 @@ void ppc_compat_add_property(Object *obj, const char *name,
 #define SPR_440_IVLIM         (0x399)
 #define SPR_TSCR              (0x399)
 #define SPR_750_DMAU          (0x39A)
+#define SPR_POWER_TTR         (0x39A)
 #define SPR_750_DMAL          (0x39B)
 #define SPR_440_RSTCFG        (0x39B)
 #define SPR_BOOKE_DCDBTRL     (0x39C)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index dc6b4fc569..4591a68cc5 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -5784,6 +5784,16 @@ static void register_power_common_book4_sprs(CPUPPCState *env)
                  &spr_access_nop, &spr_write_generic,
                  &spr_access_nop, &spr_write_generic,
                  0x00000000);
+    spr_register_hv(env, SPR_LDBAR, "LDBAR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_core_lpar_write_generic,
+                 0x00000000);
+    spr_register_hv(env, SPR_POWER_TTR, "TTR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_core_write_generic,
+                 0x00000000);
 #endif
 }
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 13/14] target/ppc: Implement SPRC/SPRD SPRs
  2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
                   ` (11 preceding siblings ...)
  2024-05-18  9:31 ` [PATCH 12/14] target/ppc: Implement LDBAR, TTR SPRs Nicholas Piggin
@ 2024-05-18  9:31 ` Nicholas Piggin
  2024-05-18  9:31 ` [PATCH 14/14] target/ppc: add SMT support to msgsnd broadcast Nicholas Piggin
  13 siblings, 0 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

This implements the POWER SPRC/SPRD SPRs, and SCRATCH0-7 registers that
can be accessed via these indirect SPRs.

SCRATCH registers only provide storage, but they are used by firmware
for low level crash and progress data, so this implementation logs
writes to the registers to help with analysis.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/cpu.h         |  7 +++--
 target/ppc/helper.h      |  3 ++
 target/ppc/spr_common.h  |  3 ++
 target/ppc/cpu_init.c    | 10 ++++++
 target/ppc/misc_helper.c | 66 ++++++++++++++++++++++++++++++++++++++++
 target/ppc/translate.c   | 18 +++++++++++
 6 files changed, 105 insertions(+), 2 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index a014efc23a..8e15a9ccbb 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1264,6 +1264,9 @@ struct CPUArchState {
     ppc_slb_t slb[MAX_SLB_ENTRIES]; /* PowerPC 64 SLB area */
     struct CPUBreakpoint *ciabr_breakpoint;
     struct CPUWatchpoint *dawr0_watchpoint;
+
+    /* POWER CPU regs/state */
+    target_ulong scratch[8]; /* SCRATCH registers (shared across core) */
 #endif
     target_ulong sr[32];   /* segment registers */
     uint32_t nb_BATs;      /* number of BATs */
@@ -1806,9 +1809,9 @@ void ppc_compat_add_property(Object *obj, const char *name,
 #define SPR_SPRG2             (0x112)
 #define SPR_SPRG3             (0x113)
 #define SPR_SPRG4             (0x114)
-#define SPR_SCOMC             (0x114)
+#define SPR_POWER_SPRC        (0x114)
 #define SPR_SPRG5             (0x115)
-#define SPR_SCOMD             (0x115)
+#define SPR_POWER_SPRD        (0x115)
 #define SPR_SPRG6             (0x116)
 #define SPR_SPRG7             (0x117)
 #define SPR_ASR               (0x118)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 09d50f9b76..57bf8354e7 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -730,6 +730,9 @@ DEF_HELPER_2(book3s_msgsndp, void, env, tl)
 DEF_HELPER_2(book3s_msgclrp, void, env, tl)
 DEF_HELPER_1(load_tfmr, tl, env)
 DEF_HELPER_2(store_tfmr, void, env, tl)
+DEF_HELPER_FLAGS_2(store_sprc, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_FLAGS_1(load_sprd, TCG_CALL_NO_RWG_SE, tl, env)
+DEF_HELPER_FLAGS_2(store_sprd, TCG_CALL_NO_RWG, void, env, tl)
 #endif
 DEF_HELPER_2(store_sdr1, void, env, tl)
 DEF_HELPER_2(store_pidr, void, env, tl)
diff --git a/target/ppc/spr_common.h b/target/ppc/spr_common.h
index 85f73b860b..01aff449bc 100644
--- a/target/ppc/spr_common.h
+++ b/target/ppc/spr_common.h
@@ -207,6 +207,9 @@ void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn);
 void spr_read_dexcr_ureg(DisasContext *ctx, int gprn, int sprn);
 void spr_read_ppr32(DisasContext *ctx, int sprn, int gprn);
 void spr_write_ppr32(DisasContext *ctx, int sprn, int gprn);
+void spr_write_sprc(DisasContext *ctx, int sprn, int gprn);
+void spr_read_sprd(DisasContext *ctx, int sprn, int gprn);
+void spr_write_sprd(DisasContext *ctx, int sprn, int gprn);
 #endif
 
 void register_low_BATs(CPUPPCState *env);
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 4591a68cc5..0c1837fe76 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -5794,6 +5794,16 @@ static void register_power_common_book4_sprs(CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_core_write_generic,
                  0x00000000);
+    spr_register_hv(env, SPR_POWER_SPRC, "SPRC",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_sprc,
+                 0x00000000);
+    spr_register_hv(env, SPR_POWER_SPRD, "SPRD",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_sprd, &spr_write_sprd,
+                 0x00000000);
 #endif
 }
 
diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c
index a67930d031..fa47be2298 100644
--- a/target/ppc/misc_helper.c
+++ b/target/ppc/misc_helper.c
@@ -307,6 +307,72 @@ void helper_store_dpdes(CPUPPCState *env, target_ulong val)
     }
     bql_unlock();
 }
+
+/* Indirect SCOM (SPRC/SPRD) access to SCRATCH0-7 are implemented. */
+void helper_store_sprc(CPUPPCState *env, target_ulong val)
+{
+    if (val & ~0x3f8ULL) {
+        qemu_log_mask(LOG_GUEST_ERROR, "Invalid SPRC register value "
+                      TARGET_FMT_lx"\n", val);
+        return;
+    }
+    env->spr[SPR_POWER_SPRC] = val;
+}
+
+target_ulong helper_load_sprd(CPUPPCState *env)
+{
+    target_ulong sprc = env->spr[SPR_POWER_SPRC];
+
+    switch (sprc & 0x3c0) {
+    case 0: /* SCRATCH0-7 */
+        return env->scratch[(sprc >> 3) & 0x7];
+    default:
+        qemu_log_mask(LOG_UNIMP, "mfSPRD: Unimplemented SPRC:0x"
+                                  TARGET_FMT_lx"\n", sprc);
+        break;
+    }
+    return 0;
+}
+
+static void do_store_scratch(CPUPPCState *env, int nr, target_ulong val)
+{
+    CPUState *cs = env_cpu(env);
+    CPUState *ccs;
+    uint32_t nr_threads = cs->nr_threads;
+
+    /*
+     * Log stores to SCRATCH, because some firmware uses these for debugging
+     * and logging, but they would normally be read by the BMC, which is
+     * not implemented in QEMU yet. This gives a way to get at the information.
+     * Could also dump these upon checkstop.
+     */
+    qemu_log("SPRD write 0x" TARGET_FMT_lx " to SCRATCH%d\n", val, nr);
+
+    if (nr_threads == 1) {
+        env->scratch[nr] = val;
+        return;
+    }
+
+    THREAD_SIBLING_FOREACH(cs, ccs) {
+        CPUPPCState *cenv = &POWERPC_CPU(ccs)->env;
+        cenv->scratch[nr] = val;
+    }
+}
+
+void helper_store_sprd(CPUPPCState *env, target_ulong val)
+{
+    target_ulong sprc = env->spr[SPR_POWER_SPRC];
+
+    switch (sprc & 0x3c0) {
+    case 0: /* SCRATCH0-7 */
+        do_store_scratch(env, (sprc >> 3) & 0x7, val);
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "mfSPRD: Unimplemented SPRC:0x"
+                                  TARGET_FMT_lx"\n", sprc);
+        break;
+    }
+}
 #endif /* defined(TARGET_PPC64) */
 
 void helper_store_pidr(CPUPPCState *env, target_ulong val)
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 60a7afb086..8e944c4416 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -1363,6 +1363,24 @@ void spr_write_tfmr(DisasContext *ctx, int sprn, int gprn)
     gen_helper_store_tfmr(tcg_env, cpu_gpr[gprn]);
 }
 
+void spr_write_sprc(DisasContext *ctx, int sprn, int gprn)
+{
+    gen_helper_store_sprc(tcg_env, cpu_gpr[gprn]);
+}
+
+void spr_read_sprd(DisasContext *ctx, int gprn, int sprn)
+{
+    gen_helper_load_sprd(cpu_gpr[gprn], tcg_env);
+}
+
+void spr_write_sprd(DisasContext *ctx, int sprn, int gprn)
+{
+    if (!gen_serialize_core(ctx)) {
+        return;
+    }
+    gen_helper_store_sprd(tcg_env, cpu_gpr[gprn]);
+}
+
 void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn)
 {
     translator_io_start(&ctx->base);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 14/14] target/ppc: add SMT support to msgsnd broadcast
  2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
                   ` (12 preceding siblings ...)
  2024-05-18  9:31 ` [PATCH 13/14] target/ppc: Implement SPRC/SPRD SPRs Nicholas Piggin
@ 2024-05-18  9:31 ` Nicholas Piggin
  13 siblings, 0 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-18  9:31 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Nicholas Piggin, qemu-devel, Daniel Henrique Barboza, Glenn Miles

msgsnd has a broadcast mode that sends hypervisor doorbells to all
threads belonging to the same core as the target. A "subcore" mode
sends to all or one thread depending on 1LPAR mode.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/cpu.h                              |  6 +-
 target/ppc/helper.h                           |  2 +-
 target/ppc/excp_helper.c                      | 57 +++++++++++++------
 .../ppc/translate/processor-ctrl-impl.c.inc   |  2 +-
 4 files changed, 46 insertions(+), 21 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 8e15a9ccbb..ee6883c037 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1163,7 +1163,11 @@ FIELD(FPSCR, FI, FPSCR_FI, 1)
 
 #define DBELL_TYPE_DBELL_SERVER        (0x05 << DBELL_TYPE_SHIFT)
 
-#define DBELL_BRDCAST                  PPC_BIT(37)
+#define DBELL_BRDCAST_MASK             PPC_BITMASK(37, 38)
+#define DBELL_BRDCAST_SHIFT            25
+#define DBELL_BRDCAST_SUBPROC          (0x1 << DBELL_BRDCAST_SHIFT)
+#define DBELL_BRDCAST_CORE             (0x2 << DBELL_BRDCAST_SHIFT)
+
 #define DBELL_LPIDTAG_SHIFT            14
 #define DBELL_LPIDTAG_MASK             (0xfff << DBELL_LPIDTAG_SHIFT)
 #define DBELL_PIRTAG_MASK              0x3fff
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 57bf8354e7..dd92c6a937 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -695,7 +695,7 @@ DEF_HELPER_FLAGS_3(store_sr, TCG_CALL_NO_RWG, void, env, tl, tl)
 
 DEF_HELPER_1(msgsnd, void, tl)
 DEF_HELPER_2(msgclr, void, env, tl)
-DEF_HELPER_1(book3s_msgsnd, void, tl)
+DEF_HELPER_2(book3s_msgsnd, void, env, tl)
 DEF_HELPER_2(book3s_msgclr, void, env, tl)
 #endif
 
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 28f2ab4583..73837c7a14 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -2969,7 +2969,7 @@ void helper_msgsnd(target_ulong rb)
         PowerPCCPU *cpu = POWERPC_CPU(cs);
         CPUPPCState *cenv = &cpu->env;
 
-        if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
+        if ((rb & DBELL_BRDCAST_MASK) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
             ppc_set_irq(cpu, irq, 1);
         }
     }
@@ -2988,6 +2988,16 @@ static bool dbell_type_server(target_ulong rb)
     return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER;
 }
 
+static inline bool dbell_bcast_core(target_ulong rb)
+{
+    return (rb & DBELL_BRDCAST_MASK) == DBELL_BRDCAST_CORE;
+}
+
+static inline bool dbell_bcast_subproc(target_ulong rb)
+{
+    return (rb & DBELL_BRDCAST_MASK) == DBELL_BRDCAST_SUBPROC;
+}
+
 void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb)
 {
     if (!dbell_type_server(rb)) {
@@ -2997,32 +3007,43 @@ void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb)
     ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_HDOORBELL, 0);
 }
 
-static void book3s_msgsnd_common(int pir, int irq)
+void helper_book3s_msgsnd(CPUPPCState *env, target_ulong rb)
 {
-    CPUState *cs;
+    int pir = rb & DBELL_PROCIDTAG_MASK;
+    bool brdcast = false;
+    CPUState *cs, *ccs;
+    PowerPCCPU *cpu;
 
-    bql_lock();
-    CPU_FOREACH(cs) {
-        PowerPCCPU *cpu = POWERPC_CPU(cs);
-        CPUPPCState *cenv = &cpu->env;
+    if (!dbell_type_server(rb)) {
+        return;
+    }
 
-        /* TODO: broadcast message to all threads of the same  processor */
-        if (cenv->spr_cb[SPR_PIR].default_value == pir) {
-            ppc_set_irq(cpu, irq, 1);
-        }
+    cpu = ppc_get_vcpu_by_pir(pir);
+    if (!cpu) {
+        return;
     }
-    bql_unlock();
-}
+    cs = CPU(cpu);
 
-void helper_book3s_msgsnd(target_ulong rb)
-{
-    int pir = rb & DBELL_PROCIDTAG_MASK;
+    if (dbell_bcast_core(rb) || (dbell_bcast_subproc(rb) &&
+                                 (env->flags & POWERPC_FLAG_SMT_1LPAR))) {
+        brdcast = true;
+    }
 
-    if (!dbell_type_server(rb)) {
+    if (cs->nr_threads == 1 || !brdcast) {
+        ppc_set_irq(cpu, PPC_INTERRUPT_HDOORBELL, 1);
         return;
     }
 
-    book3s_msgsnd_common(pir, PPC_INTERRUPT_HDOORBELL);
+    /*
+     * Why is bql needed for walking CPU list? Answer seems to be because ppc
+     * irq handling needs it, but ppc_set_irq takes the lock itself if needed,
+     * so could this be removed?
+     */
+    bql_lock();
+    THREAD_SIBLING_FOREACH(cs, ccs) {
+        ppc_set_irq(POWERPC_CPU(ccs), PPC_INTERRUPT_HDOORBELL, 1);
+    }
+    bql_unlock();
 }
 
 #ifdef TARGET_PPC64
diff --git a/target/ppc/translate/processor-ctrl-impl.c.inc b/target/ppc/translate/processor-ctrl-impl.c.inc
index 0142801985..8abbb89630 100644
--- a/target/ppc/translate/processor-ctrl-impl.c.inc
+++ b/target/ppc/translate/processor-ctrl-impl.c.inc
@@ -59,7 +59,7 @@ static bool trans_MSGSND(DisasContext *ctx, arg_X_rb *a)
 
 #if !defined(CONFIG_USER_ONLY)
     if (is_book3s_arch2x(ctx)) {
-        gen_helper_book3s_msgsnd(cpu_gpr[a->rb]);
+        gen_helper_book3s_msgsnd(tcg_env, cpu_gpr[a->rb]);
     } else {
         gen_helper_msgsnd(cpu_gpr[a->rb]);
     }
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH 02/14] target/ppc: Remove redundant MEMOP_GET_SIZE macro
  2024-05-18  9:31 ` [PATCH 02/14] target/ppc: Remove redundant MEMOP_GET_SIZE macro Nicholas Piggin
@ 2024-05-18  9:57   ` BALATON Zoltan
  2024-05-18 10:59   ` Richard Henderson
  1 sibling, 0 replies; 24+ messages in thread
From: BALATON Zoltan @ 2024-05-18  9:57 UTC (permalink / raw)
  To: Nicholas Piggin
  Cc: qemu-ppc, qemu-devel, Daniel Henrique Barboza, Glenn Miles

On Sat, 18 May 2024, Nicholas Piggin wrote:
> There is a memop_size() function for this.
>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>

Reviewed-by: BALATON Zoltan <balaton@eik.bme.hu>

> ---
> target/ppc/translate.c | 8 +++-----
> 1 file changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 0882fe2fd2..cf2404330b 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -2904,8 +2904,6 @@ static void gen_isync(DisasContext *ctx)
>     ctx->base.is_jmp = DISAS_EXIT_UPDATE;
> }
>
> -#define MEMOP_GET_SIZE(x)  (1 << ((x) & MO_SIZE))
> -
> static void gen_load_locked(DisasContext *ctx, MemOp memop)
> {
>     TCGv gpr = cpu_gpr[rD(ctx->opcode)];
> @@ -2938,7 +2936,7 @@ static void gen_fetch_inc_conditional(DisasContext *ctx, MemOp memop,
>     TCGv u = tcg_temp_new();
>
>     tcg_gen_qemu_ld_tl(t, EA, ctx->mem_idx, memop);
> -    tcg_gen_addi_tl(t2, EA, MEMOP_GET_SIZE(memop));
> +    tcg_gen_addi_tl(t2, EA, memop_size(memop));
>     tcg_gen_qemu_ld_tl(t2, t2, ctx->mem_idx, memop);
>     tcg_gen_addi_tl(u, t, addend);
>
> @@ -2948,7 +2946,7 @@ static void gen_fetch_inc_conditional(DisasContext *ctx, MemOp memop,
>     tcg_gen_qemu_st_tl(u, EA, ctx->mem_idx, memop);
>
>     /* RT = (t != t2 ? t : u = 1<<(s*8-1)) */
> -    tcg_gen_movi_tl(u, 1 << (MEMOP_GET_SIZE(memop) * 8 - 1));
> +    tcg_gen_movi_tl(u, 1 << (memop_size(memop) * 8 - 1));
>     tcg_gen_movcond_tl(cond, cpu_gpr[rD(ctx->opcode)], t, t2, t, u);
> }
>
> @@ -3110,7 +3108,7 @@ static void gen_st_atomic(DisasContext *ctx, MemOp memop)
>             TCGv ea_plus_s = tcg_temp_new();
>
>             tcg_gen_qemu_ld_tl(t, EA, ctx->mem_idx, memop);
> -            tcg_gen_addi_tl(ea_plus_s, EA, MEMOP_GET_SIZE(memop));
> +            tcg_gen_addi_tl(ea_plus_s, EA, memop_size(memop));
>             tcg_gen_qemu_ld_tl(t2, ea_plus_s, ctx->mem_idx, memop);
>             tcg_gen_movcond_tl(TCG_COND_EQ, s, t, t2, src, t);
>             tcg_gen_movcond_tl(TCG_COND_EQ, s2, t, t2, src, t2);
>


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 01/14] target/ppc: larx/stcx generation need only apply DEF_MEMOP() once
  2024-05-18  9:31 ` [PATCH 01/14] target/ppc: larx/stcx generation need only apply DEF_MEMOP() once Nicholas Piggin
@ 2024-05-18 10:58   ` Richard Henderson
  0 siblings, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2024-05-18 10:58 UTC (permalink / raw)
  To: Nicholas Piggin, qemu-ppc
  Cc: qemu-devel, Daniel Henrique Barboza, Glenn Miles

On 5/18/24 11:31, Nicholas Piggin wrote:
> Use DEF_MEMOP() consistently in larx and stcx. generation, and apply it
> once when it's used rather than where the macros are expanded, to reduce
> typing.
> 
> Signed-off-by: Nicholas Piggin<npiggin@gmail.com>
> ---
>   target/ppc/translate.c | 18 +++++++++---------
>   1 file changed, 9 insertions(+), 9 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 02/14] target/ppc: Remove redundant MEMOP_GET_SIZE macro
  2024-05-18  9:31 ` [PATCH 02/14] target/ppc: Remove redundant MEMOP_GET_SIZE macro Nicholas Piggin
  2024-05-18  9:57   ` BALATON Zoltan
@ 2024-05-18 10:59   ` Richard Henderson
  1 sibling, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2024-05-18 10:59 UTC (permalink / raw)
  To: Nicholas Piggin, qemu-ppc
  Cc: qemu-devel, Daniel Henrique Barboza, Glenn Miles

On 5/18/24 11:31, Nicholas Piggin wrote:
> There is a memop_size() function for this.
> 
> Signed-off-by: Nicholas Piggin<npiggin@gmail.com>
> ---
>   target/ppc/translate.c | 8 +++-----
>   1 file changed, 3 insertions(+), 5 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 05/14] target/ppc: Implement attn instruction on BookS 64-bit processors
  2024-05-18  9:31 ` [PATCH 05/14] target/ppc: Implement attn instruction on BookS 64-bit processors Nicholas Piggin
@ 2024-05-18 11:05   ` Richard Henderson
  2024-05-20  7:18     ` Nicholas Piggin
  2024-05-18 11:07   ` Richard Henderson
  1 sibling, 1 reply; 24+ messages in thread
From: Richard Henderson @ 2024-05-18 11:05 UTC (permalink / raw)
  To: Nicholas Piggin, qemu-ppc
  Cc: qemu-devel, Daniel Henrique Barboza, Glenn Miles

On 5/18/24 11:31, Nicholas Piggin wrote:
> @@ -425,17 +426,17 @@ static void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector,
>       env->reserve_addr = -1;
>   }
>   
> -static void powerpc_mcheck_checkstop(CPUPPCState *env)
> -{
> -    /* KVM guests always have MSR[ME] enabled */
>   #ifdef CONFIG_TCG
> +/*
> + * This stops the machine and logs CPU state without killing QEMU (like
> + * cpu_abort()) because it is often a guest error as opposed to a QEMU error,
> + * so the machine can still be debugged.
> + */
> +static G_NORETURN void powerpc_checkstop(CPUPPCState *env, const char *reason)
> +{
>       CPUState *cs = env_cpu(env);
>       FILE *f;
>   
> -    if (FIELD_EX64(env->msr, MSR, ME)) {
> -        return;
> -    }
> -
>       f = qemu_log_trylock();
>       if (f) {
>           fprintf(f, "Entering checkstop state: "
> @@ -451,6 +452,30 @@ static void powerpc_mcheck_checkstop(CPUPPCState *env)
>        */
>       qemu_system_guest_panicked(NULL);
>       cpu_loop_exit_noexc(cs);
> +}

Looks like you're not using reason.
Missed swapping out in the logging block?


r~


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 05/14] target/ppc: Implement attn instruction on BookS 64-bit processors
  2024-05-18  9:31 ` [PATCH 05/14] target/ppc: Implement attn instruction on BookS 64-bit processors Nicholas Piggin
  2024-05-18 11:05   ` Richard Henderson
@ 2024-05-18 11:07   ` Richard Henderson
  2024-05-20  7:22     ` Nicholas Piggin
  1 sibling, 1 reply; 24+ messages in thread
From: Richard Henderson @ 2024-05-18 11:07 UTC (permalink / raw)
  To: Nicholas Piggin, qemu-ppc
  Cc: qemu-devel, Daniel Henrique Barboza, Glenn Miles

On 5/18/24 11:31, Nicholas Piggin wrote:
> +static void gen_attn(DisasContext *ctx)
> +{
> +#if defined(CONFIG_USER_ONLY)
> +    GEN_PRIV(ctx);
> +#else
> +    gen_helper_attn(tcg_env);
> +#endif
> +}

You forgot to check priv in system mode.
Better as

     GEN_PRIV(ctx);
#ifndef CONFIG_USER_ONLY
     gen_helper_attn(...)
#endif


r~


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 09/14] target/ppc: add helper to write per-LPAR SPRs
  2024-05-18  9:31 ` [PATCH 09/14] target/ppc: add helper to write per-LPAR SPRs Nicholas Piggin
@ 2024-05-18 11:26   ` Richard Henderson
  2024-05-20  7:23     ` Nicholas Piggin
  0 siblings, 1 reply; 24+ messages in thread
From: Richard Henderson @ 2024-05-18 11:26 UTC (permalink / raw)
  To: Nicholas Piggin, qemu-ppc
  Cc: qemu-devel, Daniel Henrique Barboza, Glenn Miles

On 5/18/24 11:31, Nicholas Piggin wrote:
> +void spr_core_write_generic32(DisasContext *ctx, int sprn, int gprn)
> +{
> +    TCGv t0 = tcg_temp_new();
> +    if (!(ctx->flags & POWERPC_FLAG_SMT)) {
> +        spr_write_generic32(ctx, sprn, gprn);
> +        return;
> +    }
> +
> +    if (!gen_serialize(ctx)) {
> +        return;
> +    }
> +
> +    tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);

Better to delay allocating the temp until needed, so that you don't allocate one along the 
return paths.

r~


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 05/14] target/ppc: Implement attn instruction on BookS 64-bit processors
  2024-05-18 11:05   ` Richard Henderson
@ 2024-05-20  7:18     ` Nicholas Piggin
  0 siblings, 0 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-20  7:18 UTC (permalink / raw)
  To: Richard Henderson, qemu-ppc
  Cc: qemu-devel, Daniel Henrique Barboza, Glenn Miles

On Sat May 18, 2024 at 9:05 PM AEST, Richard Henderson wrote:
> On 5/18/24 11:31, Nicholas Piggin wrote:
> > @@ -425,17 +426,17 @@ static void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector,
> >       env->reserve_addr = -1;
> >   }
> >   
> > -static void powerpc_mcheck_checkstop(CPUPPCState *env)
> > -{
> > -    /* KVM guests always have MSR[ME] enabled */
> >   #ifdef CONFIG_TCG
> > +/*
> > + * This stops the machine and logs CPU state without killing QEMU (like
> > + * cpu_abort()) because it is often a guest error as opposed to a QEMU error,
> > + * so the machine can still be debugged.
> > + */
> > +static G_NORETURN void powerpc_checkstop(CPUPPCState *env, const char *reason)
> > +{
> >       CPUState *cs = env_cpu(env);
> >       FILE *f;
> >   
> > -    if (FIELD_EX64(env->msr, MSR, ME)) {
> > -        return;
> > -    }
> > -
> >       f = qemu_log_trylock();
> >       if (f) {
> >           fprintf(f, "Entering checkstop state: "
> > @@ -451,6 +452,30 @@ static void powerpc_mcheck_checkstop(CPUPPCState *env)
> >        */
> >       qemu_system_guest_panicked(NULL);
> >       cpu_loop_exit_noexc(cs);
> > +}
>
> Looks like you're not using reason.
> Missed swapping out in the logging block?

Good catch thanks, I lost the hunk in a rebase.

Thanks,
Nick


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 05/14] target/ppc: Implement attn instruction on BookS 64-bit processors
  2024-05-18 11:07   ` Richard Henderson
@ 2024-05-20  7:22     ` Nicholas Piggin
  0 siblings, 0 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-20  7:22 UTC (permalink / raw)
  To: Richard Henderson, qemu-ppc
  Cc: qemu-devel, Daniel Henrique Barboza, Glenn Miles

On Sat May 18, 2024 at 9:07 PM AEST, Richard Henderson wrote:
> On 5/18/24 11:31, Nicholas Piggin wrote:
> > +static void gen_attn(DisasContext *ctx)
> > +{
> > +#if defined(CONFIG_USER_ONLY)
> > +    GEN_PRIV(ctx);
> > +#else
> > +    gen_helper_attn(tcg_env);
> > +#endif
> > +}
>
> You forgot to check priv in system mode.
> Better as
>
>      GEN_PRIV(ctx);
> #ifndef CONFIG_USER_ONLY
>      gen_helper_attn(...)
> #endif

Good catch again.

I'm actually wrong there too, it should be treated as illegal
unless it is enabled with a system SPR, in which case it's
unprivileged (it can be inserted by external hardware debuggers
to stop the CPU and get notified).

Thanks,
Nick


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 09/14] target/ppc: add helper to write per-LPAR SPRs
  2024-05-18 11:26   ` Richard Henderson
@ 2024-05-20  7:23     ` Nicholas Piggin
  0 siblings, 0 replies; 24+ messages in thread
From: Nicholas Piggin @ 2024-05-20  7:23 UTC (permalink / raw)
  To: Richard Henderson, qemu-ppc
  Cc: qemu-devel, Daniel Henrique Barboza, Glenn Miles

On Sat May 18, 2024 at 9:26 PM AEST, Richard Henderson wrote:
> On 5/18/24 11:31, Nicholas Piggin wrote:
> > +void spr_core_write_generic32(DisasContext *ctx, int sprn, int gprn)
> > +{
> > +    TCGv t0 = tcg_temp_new();
> > +    if (!(ctx->flags & POWERPC_FLAG_SMT)) {
> > +        spr_write_generic32(ctx, sprn, gprn);
> > +        return;
> > +    }
> > +
> > +    if (!gen_serialize(ctx)) {
> > +        return;
> > +    }
> > +
> > +    tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);
>
> Better to delay allocating the temp until needed, so that you don't allocate one along the 
> return paths.

Will fix.

Thanks,
Nick


^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2024-05-20  7:24 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-18  9:31 [PATCH 00/14] target/ppc: Various TCG emulation patches Nicholas Piggin
2024-05-18  9:31 ` [PATCH 01/14] target/ppc: larx/stcx generation need only apply DEF_MEMOP() once Nicholas Piggin
2024-05-18 10:58   ` Richard Henderson
2024-05-18  9:31 ` [PATCH 02/14] target/ppc: Remove redundant MEMOP_GET_SIZE macro Nicholas Piggin
2024-05-18  9:57   ` BALATON Zoltan
2024-05-18 10:59   ` Richard Henderson
2024-05-18  9:31 ` [PATCH 03/14] target/ppc: Make checkstop actually stop the system Nicholas Piggin
2024-05-18  9:31 ` [PATCH 04/14] target/ppc: improve checkstop logging Nicholas Piggin
2024-05-18  9:31 ` [PATCH 05/14] target/ppc: Implement attn instruction on BookS 64-bit processors Nicholas Piggin
2024-05-18 11:05   ` Richard Henderson
2024-05-20  7:18     ` Nicholas Piggin
2024-05-18 11:07   ` Richard Henderson
2024-05-20  7:22     ` Nicholas Piggin
2024-05-18  9:31 ` [PATCH 06/14] target/ppc: BookE DECAR SPR is 32-bit Nicholas Piggin
2024-05-18  9:31 ` [PATCH 07/14] target/ppc: Wire up BookE ATB registers for e500 family Nicholas Piggin
2024-05-18  9:31 ` [PATCH 08/14] target/ppc: Add PPR32 SPR Nicholas Piggin
2024-05-18  9:31 ` [PATCH 09/14] target/ppc: add helper to write per-LPAR SPRs Nicholas Piggin
2024-05-18 11:26   ` Richard Henderson
2024-05-20  7:23     ` Nicholas Piggin
2024-05-18  9:31 ` [PATCH 10/14] target/ppc: Add SMT support to simple SPRs Nicholas Piggin
2024-05-18  9:31 ` [PATCH 11/14] target/ppc: Add SMT support to PTCR SPR Nicholas Piggin
2024-05-18  9:31 ` [PATCH 12/14] target/ppc: Implement LDBAR, TTR SPRs Nicholas Piggin
2024-05-18  9:31 ` [PATCH 13/14] target/ppc: Implement SPRC/SPRD SPRs Nicholas Piggin
2024-05-18  9:31 ` [PATCH 14/14] target/ppc: add SMT support to msgsnd broadcast Nicholas Piggin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).