aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/reg.h2
-rw-r--r--arch/powerpc/math-emu/math_efp.c53
2 files changed, 54 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index bd0d36e1c945..1bc6a12f3725 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -862,6 +862,8 @@
862#define PVR_7450 0x80000000 862#define PVR_7450 0x80000000
863#define PVR_8540 0x80200000 863#define PVR_8540 0x80200000
864#define PVR_8560 0x80200000 864#define PVR_8560 0x80200000
865#define PVR_VER_E500V1 0x8020
866#define PVR_VER_E500V2 0x8021
865/* 867/*
866 * For the 8xx processors, all of them report the same PVR family for 868 * For the 8xx processors, all of them report the same PVR family for
867 * the PowerPC core. The various versions of these processors must be 869 * 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 41f4ef30e480..634830bdc0be 100644
--- a/arch/powerpc/math-emu/math_efp.c
+++ b/arch/powerpc/math-emu/math_efp.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * arch/powerpc/math-emu/math_efp.c 2 * arch/powerpc/math-emu/math_efp.c
3 * 3 *
4 * Copyright (C) 2006-2008 Freescale Semiconductor, Inc. All rights reserved. 4 * Copyright (C) 2006-2008, 2010 Freescale Semiconductor, Inc.
5 * 5 *
6 * Author: Ebony Zhu, <ebony.zhu@freescale.com> 6 * Author: Ebony Zhu, <ebony.zhu@freescale.com>
7 * Yu Liu, <yu.liu@freescale.com> 7 * Yu Liu, <yu.liu@freescale.com>
@@ -104,6 +104,8 @@
104#define FP_EX_MASK (FP_EX_INEXACT | FP_EX_INVALID | FP_EX_DIVZERO | \ 104#define FP_EX_MASK (FP_EX_INEXACT | FP_EX_INVALID | FP_EX_DIVZERO | \
105 FP_EX_UNDERFLOW | FP_EX_OVERFLOW) 105 FP_EX_UNDERFLOW | FP_EX_OVERFLOW)
106 106
107static int have_e500_cpu_a005_erratum;
108
107union dw_union { 109union dw_union {
108 u64 dp[1]; 110 u64 dp[1];
109 u32 wp[2]; 111 u32 wp[2];
@@ -652,6 +654,15 @@ update_regs:
652 return 0; 654 return 0;
653 655
654illegal: 656illegal:
657 if (have_e500_cpu_a005_erratum) {
658 /* according to e500 cpu a005 erratum, reissue efp inst */
659 regs->nip -= 4;
660#ifdef DEBUG
661 printk(KERN_DEBUG "re-issue efp inst: %08lx\n", speinsn);
662#endif
663 return 0;
664 }
665
655 printk(KERN_ERR "\nOoops! IEEE-754 compliance handler encountered un-supported instruction.\ninst code: %08lx\n", speinsn); 666 printk(KERN_ERR "\nOoops! IEEE-754 compliance handler encountered un-supported instruction.\ninst code: %08lx\n", speinsn);
656 return -ENOSYS; 667 return -ENOSYS;
657} 668}
@@ -718,3 +729,43 @@ int speround_handler(struct pt_regs *regs)
718 729
719 return 0; 730 return 0;
720} 731}
732
733int __init spe_mathemu_init(void)
734{
735 u32 pvr, maj, min;
736
737 pvr = mfspr(SPRN_PVR);
738
739 if ((PVR_VER(pvr) == PVR_VER_E500V1) ||
740 (PVR_VER(pvr) == PVR_VER_E500V2)) {
741 maj = PVR_MAJ(pvr);
742 min = PVR_MIN(pvr);
743
744 /*
745 * E500 revision below 1.1, 2.3, 3.1, 4.1, 5.1
746 * need cpu a005 errata workaround
747 */
748 switch (maj) {
749 case 1:
750 if (min < 1)
751 have_e500_cpu_a005_erratum = 1;
752 break;
753 case 2:
754 if (min < 3)
755 have_e500_cpu_a005_erratum = 1;
756 break;
757 case 3:
758 case 4:
759 case 5:
760 if (min < 1)
761 have_e500_cpu_a005_erratum = 1;
762 break;
763 default:
764 break;
765 }
766 }
767
768 return 0;
769}
770
771module_init(spe_mathemu_init);