aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/mpc85xx_edac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/mpc85xx_edac.c')
-rw-r--r--drivers/edac/mpc85xx_edac.c146
1 files changed, 138 insertions, 8 deletions
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 6d0114a1b77..517042fafa7 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -668,6 +668,111 @@ static struct of_platform_driver mpc85xx_l2_err_driver = {
668 668
669/**************************** MC Err device ***************************/ 669/**************************** MC Err device ***************************/
670 670
671/*
672 * Taken from table 8-55 in the MPC8641 User's Manual and/or 9-61 in the
673 * MPC8572 User's Manual. Each line represents a syndrome bit column as a
674 * 64-bit value, but split into an upper and lower 32-bit chunk. The labels
675 * below correspond to Freescale's manuals.
676 */
677static unsigned int ecc_table[16] = {
678 /* MSB LSB */
679 /* [0:31] [32:63] */
680 0xf00fe11e, 0xc33c0ff7, /* Syndrome bit 7 */
681 0x00ff00ff, 0x00fff0ff,
682 0x0f0f0f0f, 0x0f0fff00,
683 0x11113333, 0x7777000f,
684 0x22224444, 0x8888222f,
685 0x44448888, 0xffff4441,
686 0x8888ffff, 0x11118882,
687 0xffff1111, 0x22221114, /* Syndrome bit 0 */
688};
689
690/*
691 * Calculate the correct ECC value for a 64-bit value specified by high:low
692 */
693static u8 calculate_ecc(u32 high, u32 low)
694{
695 u32 mask_low;
696 u32 mask_high;
697 int bit_cnt;
698 u8 ecc = 0;
699 int i;
700 int j;
701
702 for (i = 0; i < 8; i++) {
703 mask_high = ecc_table[i * 2];
704 mask_low = ecc_table[i * 2 + 1];
705 bit_cnt = 0;
706
707 for (j = 0; j < 32; j++) {
708 if ((mask_high >> j) & 1)
709 bit_cnt ^= (high >> j) & 1;
710 if ((mask_low >> j) & 1)
711 bit_cnt ^= (low >> j) & 1;
712 }
713
714 ecc |= bit_cnt << i;
715 }
716
717 return ecc;
718}
719
720/*
721 * Create the syndrome code which is generated if the data line specified by
722 * 'bit' failed. Eg generate an 8-bit codes seen in Table 8-55 in the MPC8641
723 * User's Manual and 9-61 in the MPC8572 User's Manual.
724 */
725static u8 syndrome_from_bit(unsigned int bit) {
726 int i;
727 u8 syndrome = 0;
728
729 /*
730 * Cycle through the upper or lower 32-bit portion of each value in
731 * ecc_table depending on if 'bit' is in the upper or lower half of
732 * 64-bit data.
733 */
734 for (i = bit < 32; i < 16; i += 2)
735 syndrome |= ((ecc_table[i] >> (bit % 32)) & 1) << (i / 2);
736
737 return syndrome;
738}
739
740/*
741 * Decode data and ecc syndrome to determine what went wrong
742 * Note: This can only decode single-bit errors
743 */
744static void sbe_ecc_decode(u32 cap_high, u32 cap_low, u32 cap_ecc,
745 int *bad_data_bit, int *bad_ecc_bit)
746{
747 int i;
748 u8 syndrome;
749
750 *bad_data_bit = -1;
751 *bad_ecc_bit = -1;
752
753 /*
754 * Calculate the ECC of the captured data and XOR it with the captured
755 * ECC to find an ECC syndrome value we can search for
756 */
757 syndrome = calculate_ecc(cap_high, cap_low) ^ cap_ecc;
758
759 /* Check if a data line is stuck... */
760 for (i = 0; i < 64; i++) {
761 if (syndrome == syndrome_from_bit(i)) {
762 *bad_data_bit = i;
763 return;
764 }
765 }
766
767 /* If data is correct, check ECC bits for errors... */
768 for (i = 0; i < 8; i++) {
769 if ((syndrome >> i) & 0x1) {
770 *bad_ecc_bit = i;
771 return;
772 }
773 }
774}
775
671static void mpc85xx_mc_check(struct mem_ctl_info *mci) 776static void mpc85xx_mc_check(struct mem_ctl_info *mci)
672{ 777{
673 struct mpc85xx_mc_pdata *pdata = mci->pvt_info; 778 struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
@@ -678,6 +783,10 @@ static void mpc85xx_mc_check(struct mem_ctl_info *mci)
678 u32 err_addr; 783 u32 err_addr;
679 u32 pfn; 784 u32 pfn;
680 int row_index; 785 int row_index;
786 u32 cap_high;
787 u32 cap_low;
788 int bad_data_bit;
789 int bad_ecc_bit;
681 790
682 err_detect = in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT); 791 err_detect = in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT);
683 if (!err_detect) 792 if (!err_detect)
@@ -711,14 +820,35 @@ static void mpc85xx_mc_check(struct mem_ctl_info *mci)
711 break; 820 break;
712 } 821 }
713 822
714 mpc85xx_mc_printk(mci, KERN_ERR, "Capture Data High: %#8.8x\n", 823 cap_high = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_DATA_HI);
715 in_be32(pdata->mc_vbase + 824 cap_low = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_DATA_LO);
716 MPC85XX_MC_CAPTURE_DATA_HI)); 825
717 mpc85xx_mc_printk(mci, KERN_ERR, "Capture Data Low: %#8.8x\n", 826 /*
718 in_be32(pdata->mc_vbase + 827 * Analyze single-bit errors on 64-bit wide buses
719 MPC85XX_MC_CAPTURE_DATA_LO)); 828 * TODO: Add support for 32-bit wide buses
720 mpc85xx_mc_printk(mci, KERN_ERR, "syndrome: %#2.2x\n", syndrome); 829 */
721 mpc85xx_mc_printk(mci, KERN_ERR, "err addr: %#8.8x\n", err_addr); 830 if ((err_detect & DDR_EDE_SBE) && (bus_width == 64)) {
831 sbe_ecc_decode(cap_high, cap_low, syndrome,
832 &bad_data_bit, &bad_ecc_bit);
833
834 if (bad_data_bit != -1)
835 mpc85xx_mc_printk(mci, KERN_ERR,
836 "Faulty Data bit: %d\n", bad_data_bit);
837 if (bad_ecc_bit != -1)
838 mpc85xx_mc_printk(mci, KERN_ERR,
839 "Faulty ECC bit: %d\n", bad_ecc_bit);
840
841 mpc85xx_mc_printk(mci, KERN_ERR,
842 "Expected Data / ECC:\t%#8.8x_%08x / %#2.2x\n",
843 cap_high ^ (1 << (bad_data_bit - 32)),
844 cap_low ^ (1 << bad_data_bit),
845 syndrome ^ (1 << bad_ecc_bit));
846 }
847
848 mpc85xx_mc_printk(mci, KERN_ERR,
849 "Captured Data / ECC:\t%#8.8x_%08x / %#2.2x\n",
850 cap_high, cap_low, syndrome);
851 mpc85xx_mc_printk(mci, KERN_ERR, "Err addr: %#8.8x\n", err_addr);
722 mpc85xx_mc_printk(mci, KERN_ERR, "PFN: %#8.8x\n", pfn); 852 mpc85xx_mc_printk(mci, KERN_ERR, "PFN: %#8.8x\n", pfn);
723 853
724 /* we are out of range */ 854 /* we are out of range */