Message ID | 20131022220617.798f5c53@kryten |
---|---|
State | New |
Headers | show |
On 10/22/2013 04:06 AM, Anton Blanchard wrote: > From: Tom Musta <tommusta@gmail.com> > > This patch adds support for the VSX bit of the PowerPC Machine > State Register (MSR) as well as the corresponding VSX Unavailable > exception. > > The VSX bit is added to the defined bits masks of the Power7 and > Power8 CPU models. > > Signed-off-by: Tom Musta <tommusta@gmail.com> > Signed-off-by: Anton Blanchard <anton@samba.org> > --- > > Index: b/target-ppc/cpu.h > =================================================================== > --- a/target-ppc/cpu.h > +++ b/target-ppc/cpu.h > @@ -236,6 +236,8 @@ enum { > POWERPC_EXCP_NMEXTBR = 91, /* Non maskable external breakpoint */ > POWERPC_EXCP_ITLBE = 92, /* Instruction TLB error */ > POWERPC_EXCP_DTLBE = 93, /* Data TLB error */ > + /* VSX Unavailable (Power ISA 2.06 and later) */ > + POWERPC_EXCP_VSXU = 94, /* VSX Unavailable */ > /* EOL */ > POWERPC_EXCP_NB = 96, > /* QEMU exceptions: used internally during code translation */ > @@ -427,6 +429,7 @@ struct ppc_slb_t { > #define MSR_VR 25 /* altivec available x hflags */ > #define MSR_SPE 25 /* SPE enable for BookE x hflags */ > #define MSR_AP 23 /* Access privilege state on 602 hflags */ > +#define MSR_VSX 23 /* Vector Scalar Extension (ISA 2.06 and later) x hflags */ > #define MSR_SA 22 /* Supervisor access mode on 602 hflags */ > #define MSR_KEY 19 /* key bit on 603e */ > #define MSR_POW 18 /* Power management */ > @@ -467,6 +470,7 @@ struct ppc_slb_t { > #define msr_vr ((env->msr >> MSR_VR) & 1) > #define msr_spe ((env->msr >> MSR_SPE) & 1) > #define msr_ap ((env->msr >> MSR_AP) & 1) > +#define msr_vsx ((env->msr >> MSR_VSX) & 1) > #define msr_sa ((env->msr >> MSR_SA) & 1) > #define msr_key ((env->msr >> MSR_KEY) & 1) > #define msr_pow ((env->msr >> MSR_POW) & 1) > Index: b/target-ppc/excp_helper.c > =================================================================== > --- a/target-ppc/excp_helper.c > +++ b/target-ppc/excp_helper.c > @@ -390,6 +390,11 @@ static inline void powerpc_excp(PowerPCC > new_msr |= (target_ulong)MSR_HVB; > } > goto store_current; > + case POWERPC_EXCP_VSXU: /* VSX 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; > Index: b/target-ppc/translate.c > =================================================================== > --- a/target-ppc/translate.c > +++ b/target-ppc/translate.c > @@ -199,6 +199,7 @@ typedef struct DisasContext { > #endif > int fpu_enabled; > int altivec_enabled; > + int vsx_enabled; > int spe_enabled; > ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ > int singlestep_enabled; > @@ -9763,6 +9764,11 @@ static inline void gen_intermediate_code > ctx.altivec_enabled = msr_vr; > else > ctx.altivec_enabled = 0; > + if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) { > + ctx.vsx_enabled = msr_vsx; > + } else { > + ctx.vsx_enabled = 0; > + } In order to get correct code generation when the msr changes, one has to adjust the TB flags. Which for target-ppc means adjusting env->hflags. See hreg_compute_hflags. Ideally, target-ppc would initialize these ctx bits from tb->flags instead of env->msr to make this obvious. But so long as the two are in sync it's not technically a bug. r~
Index: b/target-ppc/cpu.h =================================================================== --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -236,6 +236,8 @@ enum { POWERPC_EXCP_NMEXTBR = 91, /* Non maskable external breakpoint */ POWERPC_EXCP_ITLBE = 92, /* Instruction TLB error */ POWERPC_EXCP_DTLBE = 93, /* Data TLB error */ + /* VSX Unavailable (Power ISA 2.06 and later) */ + POWERPC_EXCP_VSXU = 94, /* VSX Unavailable */ /* EOL */ POWERPC_EXCP_NB = 96, /* QEMU exceptions: used internally during code translation */ @@ -427,6 +429,7 @@ struct ppc_slb_t { #define MSR_VR 25 /* altivec available x hflags */ #define MSR_SPE 25 /* SPE enable for BookE x hflags */ #define MSR_AP 23 /* Access privilege state on 602 hflags */ +#define MSR_VSX 23 /* Vector Scalar Extension (ISA 2.06 and later) x hflags */ #define MSR_SA 22 /* Supervisor access mode on 602 hflags */ #define MSR_KEY 19 /* key bit on 603e */ #define MSR_POW 18 /* Power management */ @@ -467,6 +470,7 @@ struct ppc_slb_t { #define msr_vr ((env->msr >> MSR_VR) & 1) #define msr_spe ((env->msr >> MSR_SPE) & 1) #define msr_ap ((env->msr >> MSR_AP) & 1) +#define msr_vsx ((env->msr >> MSR_VSX) & 1) #define msr_sa ((env->msr >> MSR_SA) & 1) #define msr_key ((env->msr >> MSR_KEY) & 1) #define msr_pow ((env->msr >> MSR_POW) & 1) Index: b/target-ppc/excp_helper.c =================================================================== --- a/target-ppc/excp_helper.c +++ b/target-ppc/excp_helper.c @@ -390,6 +390,11 @@ static inline void powerpc_excp(PowerPCC new_msr |= (target_ulong)MSR_HVB; } goto store_current; + case POWERPC_EXCP_VSXU: /* VSX 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; Index: b/target-ppc/translate.c =================================================================== --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -199,6 +199,7 @@ typedef struct DisasContext { #endif int fpu_enabled; int altivec_enabled; + int vsx_enabled; int spe_enabled; ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ int singlestep_enabled; @@ -9763,6 +9764,11 @@ static inline void gen_intermediate_code ctx.altivec_enabled = msr_vr; else ctx.altivec_enabled = 0; + if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) { + ctx.vsx_enabled = msr_vsx; + } else { + ctx.vsx_enabled = 0; + } if ((env->flags & POWERPC_FLAG_SE) && msr_se) ctx.singlestep_enabled = CPU_SINGLE_STEP; else Index: b/target-ppc/translate_init.c =================================================================== --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -3061,6 +3061,7 @@ static void init_excp_POWER7 (CPUPPCStat env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; 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_IABR] = 0x00001300; env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600; env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700; @@ -7232,7 +7233,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD; pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205; - pcc->msr_mask = 0x800000000204FF37ULL; + pcc->msr_mask = 0x800000000284FF37ULL; pcc->mmu_model = POWERPC_MMU_2_06; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; @@ -7267,7 +7268,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD; pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX; - pcc->msr_mask = 0x800000000204FF36ULL; + pcc->msr_mask = 0x800000000284FF36ULL; pcc->mmu_model = POWERPC_MMU_2_06; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;