From: Alexander Graf <agraf@suse.de>
To: David Gibson <david@gibson.dropbear.id.au>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 2/6] Implement POWER7's CFAR in TCG
Date: Wed, 10 Aug 2011 17:10:11 +0200 [thread overview]
Message-ID: <4E429F53.9030108@suse.de> (raw)
In-Reply-To: <1312441339-22477-3-git-send-email-david@gibson.dropbear.id.au>
On 08/04/2011 09:02 AM, David Gibson wrote:
> This patch implements support for the CFAR SPR on POWER7 (Come From
> Address Register), which snapshots the PC value at the time of a branch or
> an rfid. The latest powerpc-next kernel also catches it and can show it in
> xmon or in the signal frames.
>
> This works well enough to let recent kernels boot (which otherwise oops
> on the CFAR access). It hasn't been tested enough to be confident that the
> CFAR values are actually accurate, but one thing at a time.
>
> Signed-off-by: Ben Herrenschmidt<benh@kernel.crashing.org>
> Signed-off-by: David Gibson<david@gibson.dropbear.id.au>
> ---
> target-ppc/cpu.h | 8 ++++++++
> target-ppc/translate.c | 33 +++++++++++++++++++++++++++++++--
> target-ppc/translate_init.c | 21 ++++++++++++++++++++-
> 3 files changed, 59 insertions(+), 3 deletions(-)
>
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index d903366..8cf029f 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -540,6 +540,8 @@ enum {
> /* Decrementer clock: RTC clock (POWER, 601) or bus clock */
> POWERPC_FLAG_RTC_CLK = 0x00010000,
> POWERPC_FLAG_BUS_CLK = 0x00020000,
> + /* Has CFAR */
> + POWERPC_FLAG_CFAR = 0x00040000,
> };
>
> /*****************************************************************************/
> @@ -857,6 +859,10 @@ struct CPUPPCState {
> target_ulong ctr;
> /* condition register */
> uint32_t crf[8];
> +#if defined(TARGET_PPC64)
> + /* CFAR */
> + target_ulong cfar;
> +#endif
> /* XER */
> target_ulong xer;
> /* Reservation address */
> @@ -1187,6 +1193,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
> #define SPR_601_UDECR (0x006)
> #define SPR_LR (0x008)
> #define SPR_CTR (0x009)
> +#define SPR_DSCR (0x011)
> #define SPR_DSISR (0x012)
> #define SPR_DAR (0x013) /* DAE for PowerPC 601 */
> #define SPR_601_RTCU (0x014)
> @@ -1195,6 +1202,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
> #define SPR_SDR1 (0x019)
> #define SPR_SRR0 (0x01A)
> #define SPR_SRR1 (0x01B)
> +#define SPR_CFAR (0x01C)
> #define SPR_AMR (0x01D)
> #define SPR_BOOKE_PID (0x030)
> #define SPR_BOOKE_DECAR (0x036)
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index fd7c208..cb49c7d 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -69,6 +69,9 @@ static TCGv cpu_nip;
> static TCGv cpu_msr;
> static TCGv cpu_ctr;
> static TCGv cpu_lr;
> +#if defined(TARGET_PPC64)
> +static TCGv cpu_cfar;
> +#endif
> static TCGv cpu_xer;
> static TCGv cpu_reserve;
> static TCGv_i32 cpu_fpscr;
> @@ -154,6 +157,11 @@ void ppc_translate_init(void)
> cpu_lr = tcg_global_mem_new(TCG_AREG0,
> offsetof(CPUState, lr), "lr");
>
> +#if defined(TARGET_PPC64)
> + cpu_cfar = tcg_global_mem_new(TCG_AREG0,
> + offsetof(CPUState, cfar), "cfar");
> +#endif
> +
> cpu_xer = tcg_global_mem_new(TCG_AREG0,
> offsetof(CPUState, xer), "xer");
>
> @@ -187,12 +195,13 @@ typedef struct DisasContext {
> int le_mode;
> #if defined(TARGET_PPC64)
> int sf_mode;
> + int has_cfar;
> #endif
> int fpu_enabled;
> int altivec_enabled;
> int spe_enabled;
> ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
> - int singlestep_enabled;
> + int singlestep_enabled;
Fairly sure this isn't intended :)
> } DisasContext;
>
> struct opc_handler_t {
> @@ -3345,6 +3354,14 @@ static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
> /* stfiwx */
> GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
>
> +static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
> +{
> +#if defined(TARGET_PPC64)
> + if (ctx->has_cfar)
> + tcg_gen_movi_tl(cpu_cfar, nip);
> +#endif
> +}
> +
> /*** Branch ***/
> static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
> {
> @@ -3352,7 +3369,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
> tb = ctx->tb;
> #if defined(TARGET_PPC64)
> if (!ctx->sf_mode)
> - dest = (uint32_t) dest;
> + dest = (uint32_t) dest;
Same here
> #endif
> if ((tb->pc& TARGET_PAGE_MASK) == (dest& TARGET_PAGE_MASK)&&
> likely(!ctx->singlestep_enabled)) {
> @@ -3407,6 +3424,7 @@ static void gen_b(DisasContext *ctx)
> target = li;
> if (LK(ctx->opcode))
> gen_setlr(ctx, ctx->nip);
> + gen_update_cfar(ctx, ctx->nip);
> gen_goto_tb(ctx, 0, target);
> }
>
> @@ -3469,6 +3487,7 @@ static inline void gen_bcond(DisasContext *ctx, int type)
> }
> tcg_temp_free_i32(temp);
> }
> + gen_update_cfar(ctx, ctx->nip);
> if (type == BCOND_IM) {
> target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
> if (likely(AA(ctx->opcode) == 0)) {
> @@ -3569,6 +3588,7 @@ static void gen_mcrf(DisasContext *ctx)
>
> /*** System linkage ***/
>
> +
Or here
> /* rfi (mem_idx only) */
> static void gen_rfi(DisasContext *ctx)
> {
> @@ -3580,6 +3600,7 @@ static void gen_rfi(DisasContext *ctx)
> gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> return;
> }
> + gen_update_cfar(ctx, ctx->nip);
> gen_helper_rfi();
> gen_sync_exception(ctx);
> #endif
> @@ -3596,6 +3617,7 @@ static void gen_rfid(DisasContext *ctx)
> gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> return;
> }
> + gen_update_cfar(ctx, ctx->nip);
> gen_helper_rfid();
> gen_sync_exception(ctx);
> #endif
> @@ -9263,6 +9285,12 @@ void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
> */
> }
>
> +#if defined(TARGET_PPC64)
> + if (env->flags& POWERPC_FLAG_CFAR) {
> + cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
> + }
> +#endif
> +
> switch (env->mmu_model) {
> case POWERPC_MMU_32B:
> case POWERPC_MMU_601:
> @@ -9371,6 +9399,7 @@ static inline void gen_intermediate_code_internal(CPUState *env,
> ctx.le_mode = env->hflags& (1<< MSR_LE) ? 1 : 0;
> #if defined(TARGET_PPC64)
> ctx.sf_mode = msr_sf;
> + ctx.has_cfar = !!(env->flags& POWERPC_FLAG_CFAR);
> #endif
> ctx.fpu_enabled = msr_fp;
> if ((env->flags& POWERPC_FLAG_SPE)&& msr_spe)
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index f542b8e..510d9dd 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -129,6 +129,17 @@ static void spr_write_lr (void *opaque, int sprn, int gprn)
> tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
> }
>
> +/* CFAR */
> +static void spr_read_cfar (void *opaque, int gprn, int sprn)
> +{
> + tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar);
> +}
> +
> +static void spr_write_cfar (void *opaque, int sprn, int gprn)
> +{
> + tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]);
> +}
> +
> /* CTR */
> static void spr_read_ctr (void *opaque, int gprn, int sprn)
> {
> @@ -6489,7 +6500,7 @@ static void init_proc_970MP (CPUPPCState *env)
> #define POWERPC_BFDM_POWER7 (bfd_mach_ppc64)
> #define POWERPC_FLAG_POWER7 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
> POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
> - POWERPC_FLAG_BUS_CLK)
> + POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR)
> #define check_pow_POWER7 check_pow_nocheck
>
> static void init_proc_POWER7 (CPUPPCState *env)
> @@ -6508,6 +6519,14 @@ static void init_proc_POWER7 (CPUPPCState *env)
> &spr_read_purr, SPR_NOACCESS,
> &spr_read_purr, SPR_NOACCESS,
> 0x00000000);
> + spr_register(env, SPR_CFAR, "SPR_CFAR",
> + SPR_NOACCESS, SPR_NOACCESS,
> +&spr_read_cfar,&spr_write_cfar,
> + 0x00000000);
> + spr_register(env, SPR_DSCR, "SPR_DSCR",
> + SPR_NOACCESS, SPR_NOACCESS,
> +&spr_read_generic,&spr_write_generic,
> + 0x00000000);
Are you sure this is only present on POWER7 and no machines before that?
Does 970 have CFAR?
Alex
next prev parent reply other threads:[~2011-08-10 15:10 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-04 7:02 [Qemu-devel] pseries machine updates David Gibson
2011-08-04 7:02 ` [Qemu-devel] [PATCH 1/6] pseries: Bugfixes for interrupt numbering in XICS code David Gibson
2011-08-04 7:02 ` [Qemu-devel] [PATCH 2/6] Implement POWER7's CFAR in TCG David Gibson
2011-08-10 15:10 ` Alexander Graf [this message]
2011-08-11 0:35 ` David Gibson
2011-08-04 7:02 ` [Qemu-devel] [PATCH 3/6] pseries: Add real mode debugging hcalls David Gibson
2011-08-10 15:19 ` Alexander Graf
2011-08-04 7:02 ` [Qemu-devel] [PATCH 4/6] pseries: Add a phandle to the xicp interrupt controller device tree node David Gibson
2011-08-04 7:02 ` [Qemu-devel] [PATCH 5/6] pseries: interrupt controller should not have a 'reg' property David Gibson
2011-08-04 7:02 ` [Qemu-devel] [PATCH 6/6] pseries: More complete WIMG validation in H_ENTER code David Gibson
2011-08-10 15:16 ` [Qemu-devel] pseries machine updates Alexander Graf
2011-08-10 15:24 ` Alexander Graf
2011-08-11 0:44 ` David Gibson
2011-08-31 9:18 ` Alexander Graf
2011-08-11 0:39 ` David Gibson
2011-08-31 9:17 ` Alexander Graf
2011-09-01 1:45 ` David Gibson
2011-09-02 13:20 ` Alexander Graf
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=4E429F53.9030108@suse.de \
--to=agraf@suse.de \
--cc=david@gibson.dropbear.id.au \
--cc=qemu-devel@nongnu.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 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).