qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2 03/12] target/ppc: Implement attn instruction on BookS 64-


From: Miles Glenn
Subject: Re: [PATCH v2 03/12] target/ppc: Implement attn instruction on BookS 64-bit processors
Date: Tue, 21 May 2024 10:41:23 -0500

Looks like this patch is failing to apply to the current master head?

Thanks,

Glenn

On Tue, 2024-05-21 at 11:30 +1000, Nicholas Piggin wrote:
> 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
> +}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]