From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:42100) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QrAQN-0003va-Fi for qemu-devel@nongnu.org; Wed, 10 Aug 2011 11:10:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QrAQJ-0005HA-19 for qemu-devel@nongnu.org; Wed, 10 Aug 2011 11:10:27 -0400 Received: from cantor2.suse.de ([195.135.220.15]:48303 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QrAQI-0005Go-Jc for qemu-devel@nongnu.org; Wed, 10 Aug 2011 11:10:22 -0400 Message-ID: <4E429F53.9030108@suse.de> Date: Wed, 10 Aug 2011 17:10:11 +0200 From: Alexander Graf MIME-Version: 1.0 References: <1312441339-22477-1-git-send-email-david@gibson.dropbear.id.au> <1312441339-22477-3-git-send-email-david@gibson.dropbear.id.au> In-Reply-To: <1312441339-22477-3-git-send-email-david@gibson.dropbear.id.au> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH 2/6] Implement POWER7's CFAR in TCG List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: David Gibson Cc: qemu-devel@nongnu.org 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 > Signed-off-by: David Gibson > --- > 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