From: Nicholas Piggin <npiggin@gmail.com>
To: qemu-ppc@nongnu.org
Cc: Nicholas Piggin <npiggin@gmail.com>,
qemu-devel@nongnu.org,
Daniel Henrique Barboza <danielhb413@gmail.com>,
Glenn Miles <milesg@linux.vnet.ibm.com>,
Richard Henderson <richard.henderson@linaro.org>,
Chinmay Rath <rathc@linux.ibm.com>
Subject: [PATCH v2 03/12] target/ppc: Implement attn instruction on BookS 64-bit processors
Date: Tue, 21 May 2024 11:30:19 +1000 [thread overview]
Message-ID: <20240521013029.30082-4-npiggin@gmail.com> (raw)
In-Reply-To: <20240521013029.30082-1-npiggin@gmail.com>
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 | 12 +++++
target/ppc/helper.h | 1 +
target/ppc/insn32.decode | 4 ++
target/ppc/cpu_init.c | 69 ++++++++++++++++++++++++++++
target/ppc/excp_helper.c | 43 +++++++++++++----
target/ppc/translate/misc-impl.c.inc | 10 ++++
6 files changed, 130 insertions(+), 9 deletions(-)
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index c358927211..2532408be0 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 */
@@ -3025,6 +3031,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/insn32.decode b/target/ppc/insn32.decode
index d4dd022df4..ee33141476 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -1198,3 +1198,7 @@ EIEIO 011111 ----- ----- ----- 1101010110 -
MFBHRBE 011111 ..... ..... ..... 0100101110 - @XFX_bhrbe
CLRBHRB 011111 ----- ----- ----- 0110101110 -
+
+## Misc POWER instructions
+
+ATTN 000000 00000 00000 00000 0100000000 0
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 1ec84b5ddc..ee01415c32 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 |
@@ -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 |
@@ -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 |
@@ -6247,6 +6307,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 |
@@ -6439,6 +6500,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 |
@@ -6618,6 +6680,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 |
@@ -6856,6 +6919,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 +7385,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 17bf8df9d7..e786a9044b 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,21 +426,20 @@ 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: "
- "machine check with MSR[ME]=0\n");
+ fprintf(f, "Entering checkstop state: %s\n", reason);
cpu_dump_state(cs, f, CPU_DUMP_FPU | CPU_DUMP_CCOP);
qemu_log_unlock(f);
}
@@ -451,6 +451,31 @@ static void powerpc_mcheck_checkstop(CPUPPCState *env)
*/
qemu_system_guest_panicked(NULL);
cpu_loop_exit_noexc(cs);
+}
+
+#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
+void helper_attn(CPUPPCState *env)
+{
+ /* POWER attn is unprivileged when enabled by HID, otherwise illegal */
+ 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/misc-impl.c.inc b/target/ppc/translate/misc-impl.c.inc
index c1661d2f43..cbf82b1ea0 100644
--- a/target/ppc/translate/misc-impl.c.inc
+++ b/target/ppc/translate/misc-impl.c.inc
@@ -145,3 +145,13 @@ static bool trans_EIEIO(DisasContext *ctx, arg_EIEIO *a)
return true;
}
+
+static bool trans_ATTN(DisasContext *ctx, arg_ATTN *a)
+{
+#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
+ gen_helper_attn(tcg_env);
+ return true;
+#else
+ return false;
+#endif
+}
--
2.43.0
next prev parent reply other threads:[~2024-05-21 1:32 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-21 1:30 [PATCH v2 00/12] target/ppc: Various TCG emulation patches Nicholas Piggin
2024-05-21 1:30 ` [PATCH v2 01/12] target/ppc: Make checkstop actually stop the system Nicholas Piggin
2024-05-21 15:32 ` Miles Glenn
2024-05-21 1:30 ` [PATCH v2 02/12] target/ppc: improve checkstop logging Nicholas Piggin
2024-05-21 15:37 ` Miles Glenn
2024-05-21 17:29 ` Richard Henderson
2025-04-29 6:49 ` Philippe Mathieu-Daudé
2024-05-21 1:30 ` Nicholas Piggin [this message]
2024-05-21 15:41 ` [PATCH v2 03/12] target/ppc: Implement attn instruction on BookS 64-bit processors Miles Glenn
2024-05-22 1:30 ` Nicholas Piggin
2024-05-21 17:34 ` Richard Henderson
2024-05-22 1:32 ` Nicholas Piggin
2024-05-21 1:30 ` [PATCH v2 04/12] target/ppc: BookE DECAR SPR is 32-bit Nicholas Piggin
2024-05-21 15:44 ` Miles Glenn
2024-05-21 1:30 ` [PATCH v2 05/12] target/ppc: Wire up BookE ATB registers for e500 family Nicholas Piggin
2024-05-21 1:30 ` [PATCH v2 06/12] target/ppc: Add PPR32 SPR Nicholas Piggin
2024-05-21 15:52 ` Miles Glenn
2024-05-21 17:40 ` Richard Henderson
2024-05-22 1:43 ` Nicholas Piggin
2024-05-21 1:30 ` [PATCH v2 07/12] target/ppc: add helper to write per-LPAR SPRs Nicholas Piggin
2024-05-21 16:50 ` Miles Glenn
2024-05-21 1:30 ` [PATCH v2 08/12] target/ppc: Add SMT support to simple SPRs Nicholas Piggin
2024-05-21 15:56 ` Miles Glenn
2024-05-21 1:30 ` [PATCH v2 09/12] target/ppc: Add SMT support to PTCR SPR Nicholas Piggin
2024-05-21 16:02 ` Miles Glenn
2024-05-21 1:30 ` [PATCH v2 10/12] target/ppc: Implement LDBAR, TTR SPRs Nicholas Piggin
2024-05-21 16:41 ` Miles Glenn
2024-05-21 1:30 ` [PATCH v2 11/12] target/ppc: Implement SPRC/SPRD SPRs Nicholas Piggin
2024-05-21 16:37 ` Miles Glenn
2024-05-21 1:30 ` [PATCH v2 12/12] target/ppc: add SMT support to msgsnd broadcast Nicholas Piggin
2024-05-21 17:07 ` Miles Glenn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240521013029.30082-4-npiggin@gmail.com \
--to=npiggin@gmail.com \
--cc=danielhb413@gmail.com \
--cc=milesg@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
--cc=rathc@linux.ibm.com \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.