On Jan 25, 2011, at 12:02 AM, Liu Yu wrote: > This errata can occur if a single-precision floating-point, double-precision > floating-point or vector floating-point instruction on a mispredicted branch > path signals one of the floating-point data interrupts which are enabled by > the > SPEFSCR (FINVE, FDBZE, FUNFE or FOVFE bits). This interrupt must be recorded > in a one-cycle window when the misprediction is resolved. If this extremely > rare event should occur, the result could be: > > The SPE Data Exception from the mispredicted path may be reported > erroneously if a single-precision floating-point, double-precision > floating-point or vector floating-point instruction is the second instruction > on the correct branch path. > > According to errata description, some efp instructions > which are not supposed to trigger SPE exceptions > can trigger the exceptions in this case. > However, as we haven't emulated these instructions here, > a signal will send to userspace, and userspace application would exit. > > This patch re-issue the efp instruction that we haven't emulated, > so that hardware can properly execute it again if this case happen. > > Signed-off-by: Liu Yu <yu....@freescale.com> > --- > This is an erratum workaround patch. > It would be better if the patch can go into 2.6.38. > > arch/powerpc/include/asm/reg.h | 2 + > arch/powerpc/math-emu/math_efp.c | 53 +++++++++++++++++++++++++++++++++++++- > 2 files changed, 54 insertions(+), 1 deletions(-) > > diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h > index 6315edc..0abfd91 100644 > --- a/arch/powerpc/include/asm/reg.h > +++ b/arch/powerpc/include/asm/reg.h > @@ -833,6 +833,8 @@ > #define PVR_7450 0x80000000 > #define PVR_8540 0x80200000 > #define PVR_8560 0x80200000 > +#define PVR_VER_E500V1 0x8020 > +#define PVR_VER_E500V2 0x8021 > /* > * For the 8xx processors, all of them report the same PVR family for > * the PowerPC core. The various versions of these processors must be > diff --git a/arch/powerpc/math-emu/math_efp.c > b/arch/powerpc/math-emu/math_efp.c > index 41f4ef3..634830b 100644 > --- a/arch/powerpc/math-emu/math_efp.c > +++ b/arch/powerpc/math-emu/math_efp.c > @@ -1,7 +1,7 @@ > /* > * arch/powerpc/math-emu/math_efp.c > * > - * Copyright (C) 2006-2008 Freescale Semiconductor, Inc. All rights reserved. > + * Copyright (C) 2006-2008, 2010 Freescale Semiconductor, Inc. > * > * Author: Ebony Zhu, <ebony....@freescale.com> > * Yu Liu, <yu....@freescale.com> > @@ -104,6 +104,8 @@ > #define FP_EX_MASK (FP_EX_INEXACT | FP_EX_INVALID | FP_EX_DIVZERO | \ > FP_EX_UNDERFLOW | FP_EX_OVERFLOW) > > +static int have_e500_cpu_a005_erratum; > + > union dw_union { > u64 dp[1]; > u32 wp[2]; > @@ -652,6 +654,15 @@ update_regs: > return 0; > > illegal: > + if (have_e500_cpu_a005_erratum) { > + /* according to e500 cpu a005 erratum, reissue efp inst */ > + regs->nip -= 4; > +#ifdef DEBUG > + printk(KERN_DEBUG "re-issue efp inst: %08lx\n", speinsn); > +#endif > + return 0; > + } > + > printk(KERN_ERR "\nOoops! IEEE-754 compliance handler encountered > un-supported instruction.\ninst code: %08lx\n", speinsn); > return -ENOSYS; > } > @@ -718,3 +729,43 @@ int speround_handler(struct pt_regs *regs) > > return 0; > } > + > +int __init spe_mathemu_init(void) > +{ > + u32 pvr, maj, min; > + > + pvr = mfspr(SPRN_PVR); > + > + if ((PVR_VER(pvr) == PVR_VER_E500V1) || > + (PVR_VER(pvr) == PVR_VER_E500V2)) { > + maj = PVR_MAJ(pvr); > + min = PVR_MIN(pvr); > + > + /* > + * E500 revision below 1.1, 2.3, 3.1, 4.1, 5.1 > + * need cpu a005 errata workaround > + */
This isn't the way to do this. We normally add entries in cputable.c an add a new cpu_feature_bit for the errata. Than above we'd do: if (cur_cpu_spec->cpu_features & CPU_FTR_E500_A005_ERRATUM) > + switch (maj) { > + case 1: > + if (min < 1) > + have_e500_cpu_a005_erratum = 1; > + break; > + case 2: > + if (min < 3) > + have_e500_cpu_a005_erratum = 1; > + break; > + case 3: > + case 4: > + case 5: > + if (min < 1) > + have_e500_cpu_a005_erratum = 1; > + break; > + default: > + break; > + } > + } > + > + return 0; > +} > + > +module_init(spe_mathemu_init); > -- > 1.6.4 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev