From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58790) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WsF0N-0008D4-Fi for qemu-devel@nongnu.org; Wed, 04 Jun 2014 13:29:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WsF0G-0005fr-S4 for qemu-devel@nongnu.org; Wed, 04 Jun 2014 13:29:39 -0400 Message-ID: <538F5776.3020901@gmail.com> Date: Wed, 04 Jun 2014 12:29:26 -0500 From: Tom Musta MIME-Version: 1.0 References: <1401886265-6589-1-git-send-email-aik@ozlabs.ru> <1401886265-6589-22-git-send-email-aik@ozlabs.ru> In-Reply-To: <1401886265-6589-22-git-send-email-aik@ozlabs.ru> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH v5 21/30] target-ppc: Add POWER8's FSCR SPR List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alexey Kardashevskiy , qemu-devel@nongnu.org Cc: qemu-ppc@nongnu.org, Alexander Graf , Greg Kurz On 6/4/2014 7:50 AM, Alexey Kardashevskiy wrote: > This adds an FSCR (Facility Status and Control Register) SPR. This defines > names for FSCR bits. > > This defines new exception type - POWERPC_EXCP_FU - "facility unavailable" (FU). > This registers an interrupt vector for it at 0xF60 as PowerISA defines. > > This adds a TCG helper_fscr_facility_check() helper to raise an exception > if the facility is not enabled. It updates the interrupt cause field > in FSCR. This adds a TCG translation block generation code. The helper > may be used for HFSCR too as it has the same format. > > The helper raising FU exceptions is not used by this patch but will be > in the next ones. > > This adds gen_update_current_nip() to update NIP in DisasContext. > This helper is not used now and will be called before checking for > a condition for throwing an FU exception. > > Signed-off-by: Alexey Kardashevskiy > --- > Changes: > v4: > * added gen_update_current_nip() > * it is gen_spr_power8_fscr() now instead of gen_spr_power8_common() > * added "facility unavailable" exception vector at 0xF60 > --- > target-ppc/cpu.h | 16 ++++++++++++++++ > target-ppc/excp_helper.c | 5 +++++ > target-ppc/helper.h | 1 + > target-ppc/misc_helper.c | 27 +++++++++++++++++++++++++++ > target-ppc/translate.c | 7 +++++++ > target-ppc/translate_init.c | 10 ++++++++++ > 6 files changed, 66 insertions(+) > > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > index 3a578e6..7d566f3 100644 > --- a/target-ppc/cpu.h > +++ b/target-ppc/cpu.h > @@ -238,6 +238,7 @@ enum { > POWERPC_EXCP_DTLBE = 93, /* Data TLB error */ > /* VSX Unavailable (Power ISA 2.06 and later) */ > POWERPC_EXCP_VSXU = 94, /* VSX Unavailable */ > + POWERPC_EXCP_FU = 95, /* Facility Unavailable */ > /* EOL */ > POWERPC_EXCP_NB = 96, > /* QEMU exceptions: used internally during code translation */ > @@ -516,6 +517,19 @@ struct ppc_slb_t { > #endif > #endif > > +/* Facility Status and Control (FSCR) bits */ > +#define FSCR_EBB (63 - 56) /* Event-Based Branch Facility */ > +#define FSCR_TAR (63 - 55) /* Target Address Register */ > +/* Interrupt cause mask and position in FSCR. HFSCR has the same format */ > +#define FSCR_IC_MASK (0xFFULL) > +#define FSCR_IC_POS (63 - 7) > +#define FSCR_IC_DSCR_SPR3 2 > +#define FSCR_IC_PMU 3 > +#define FSCR_IC_BHRB 4 > +#define FSCR_IC_TM 5 > +#define FSCR_IC_EBB 7 > +#define FSCR_IC_TAR 8 > + > /* Exception state register bits definition */ > #define ESR_PIL (1 << (63 - 36)) /* Illegal Instruction */ > #define ESR_PPR (1 << (63 - 37)) /* Privileged Instruction */ > @@ -1104,6 +1118,7 @@ do { \ > /*****************************************************************************/ > PowerPCCPU *cpu_ppc_init(const char *cpu_model); > void ppc_translate_init(void); > +void gen_update_current_nip(void *opaque); > int cpu_ppc_exec (CPUPPCState *s); > /* you can call this signal handler from your SIGBUS and SIGSEGV > signal handlers to inform the virtual CPU of exceptions. non zero > @@ -1272,6 +1287,7 @@ static inline int cpu_mmu_index (CPUPPCState *env) > #define SPR_CTRL (0x098) > #define SPR_MPC_CMPE (0x098) > #define SPR_MPC_CMPF (0x099) > +#define SPR_FSCR (0x099) > #define SPR_MPC_CMPG (0x09A) > #define SPR_MPC_CMPH (0x09B) > #define SPR_MPC_LCTRL1 (0x09C) > diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c > index a0c9fdc..4b9e8fc 100644 > --- a/target-ppc/excp_helper.c > +++ b/target-ppc/excp_helper.c > @@ -398,6 +398,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) > new_msr |= (target_ulong)MSR_HVB; > } > goto store_current; > + case POWERPC_EXCP_FU: /* Facility unavailable exception */ > + if (lpes1 == 0) { > + new_msr |= (target_ulong)MSR_HVB; > + } > + goto store_current; > case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */ > LOG_EXCP("PIT exception\n"); > goto store_next; > diff --git a/target-ppc/helper.h b/target-ppc/helper.h > index 5ee4706..c1417ea 100644 > --- a/target-ppc/helper.h > +++ b/target-ppc/helper.h > @@ -577,6 +577,7 @@ DEF_HELPER_3(store_dcr, void, env, tl, tl) > > DEF_HELPER_2(load_dump_spr, void, env, i32) > DEF_HELPER_2(store_dump_spr, void, env, i32) > +DEF_HELPER_4(fscr_facility_check, void, env, i32, i32, i32) > DEF_HELPER_1(load_tbl, tl, env) > DEF_HELPER_1(load_tbu, tl, env) > DEF_HELPER_1(load_atbl, tl, env) > diff --git a/target-ppc/misc_helper.c b/target-ppc/misc_helper.c > index 7331b1b..554831f 100644 > --- a/target-ppc/misc_helper.c > +++ b/target-ppc/misc_helper.c > @@ -34,6 +34,33 @@ void helper_store_dump_spr(CPUPPCState *env, uint32_t sprn) > qemu_log("Write SPR %d %03x <= " TARGET_FMT_lx "\n", sprn, sprn, > env->spr[sprn]); > } > + > +#ifdef TARGET_PPC64 > +static void raise_fu_exception(CPUPPCState *env, uint32_t bit, > + uint32_t sprn, uint32_t cause) > +{ > + qemu_log("Facility SPR %d is unavailable (SPR FSCR:%d)\n", sprn, bit); > + > + env->spr[SPR_FSCR] &= ~((target_ulong)FSCR_IC_MASK << FSCR_IC_POS); > + cause &= FSCR_IC_MASK; > + env->spr[SPR_FSCR] |= (target_ulong)cause << FSCR_IC_POS; > + > + helper_raise_exception_err(env, POWERPC_EXCP_FU, 0); > +} > +#endif > + > +void helper_fscr_facility_check(CPUPPCState *env, uint32_t bit, > + uint32_t sprn, uint32_t cause) > +{ > +#ifdef TARGET_PPC64 > + if (env->spr[SPR_FSCR] & (1ULL << bit)) { > + /* Facility is enabled, continue */ > + return; > + } > + raise_fu_exception(env, bit, sprn, cause); > +#endif > +} > + > #if !defined(CONFIG_USER_ONLY) > > void helper_store_sdr1(CPUPPCState *env, target_ulong val) > diff --git a/target-ppc/translate.c b/target-ppc/translate.c > index 5407300..2de362c 100644 > --- a/target-ppc/translate.c > +++ b/target-ppc/translate.c > @@ -289,6 +289,13 @@ static inline void gen_update_nip(DisasContext *ctx, target_ulong nip) > tcg_gen_movi_tl(cpu_nip, nip); > } > > +void gen_update_current_nip(void *opaque) > +{ > + DisasContext *ctx = opaque; > + > + tcg_gen_movi_tl(cpu_nip, ctx->nip); > +} > + > static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error) > { > TCGv_i32 t0, t1; > diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c > index 1df69e0..4e139b4 100644 > --- a/target-ppc/translate_init.c > +++ b/target-ppc/translate_init.c > @@ -3080,6 +3080,7 @@ static void init_excp_POWER7 (CPUPPCState *env) > env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; > env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20; > env->excp_vectors[POWERPC_EXCP_VSXU] = 0x00000F40; > + env->excp_vectors[POWERPC_EXCP_FU] = 0x00000F60; > env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; > env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600; > env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700; > @@ -7586,6 +7587,14 @@ static void gen_spr_power8_tce_address_control(CPUPPCState *env) > 0x00000000); > } > > +static void gen_spr_power8_fscr(CPUPPCState *env) > +{ > + spr_register_kvm(env, SPR_FSCR, "FSCR", > + SPR_NOACCESS, SPR_NOACCESS, > + &spr_read_generic, &spr_write_generic, > + KVM_REG_PPC_FSCR, 0x00000000); > +} > + > static void init_proc_book3s_64(CPUPPCState *env, int version) > { > gen_spr_ne_601(env); > @@ -7631,6 +7640,7 @@ static void init_proc_book3s_64(CPUPPCState *env, int version) > if (version >= BOOK3S_CPU_POWER8) { > gen_spr_power8_tce_address_control(env); > gen_spr_power8_ids(env); > + gen_spr_power8_fscr(env); > } > #if !defined(CONFIG_USER_ONLY) > switch (version) { > Reviewed-by: Tom Musta