aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/i5100_edac.c
diff options
context:
space:
mode:
authorNiklas Söderlund <niklas.soderlund@ericsson.com>2012-08-08 11:30:57 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-02-21 09:06:33 -0500
commit53ceafd6a27f3e15dc83e8865f9f20029f6dfc66 (patch)
tree60fce8eb39210959f30fe008af04d3308167075b /drivers/edac/i5100_edac.c
parent52608ba20546139dc76cca8a46c1d901455d5450 (diff)
i5100_edac: add fault injection code
Add fault injection based on information datasheet for i5100, see 1. In addition to the i5100 datasheet some missing information on injection functions where found through experimentation and the i7300 datasheet, see 2. [1] Intel 5100 Memory Controller Hub Chipset Doc.Nr: 318378 http://www.intel.com/content/dam/doc/datasheet/5100- memory-controller-hub-chipset-datasheet.pdf [2] Intel 7300 Chipset MemoryController Hub (MCH) Doc.Nr: 318082 http://www.intel.com/assets/pdf/datasheet/318082.pdf Signed-off-by: Niklas Söderlund <niklas.soderlund@ericsson.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac/i5100_edac.c')
-rw-r--r--drivers/edac/i5100_edac.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/drivers/edac/i5100_edac.c b/drivers/edac/i5100_edac.c
index 33c5c8e663f2..0a0345bd7432 100644
--- a/drivers/edac/i5100_edac.c
+++ b/drivers/edac/i5100_edac.c
@@ -68,6 +68,14 @@
68 I5100_FERR_NF_MEM_M1ERR_MASK) 68 I5100_FERR_NF_MEM_M1ERR_MASK)
69#define I5100_NERR_NF_MEM 0xa4 /* MC Next Non-Fatal Errors */ 69#define I5100_NERR_NF_MEM 0xa4 /* MC Next Non-Fatal Errors */
70#define I5100_EMASK_MEM 0xa8 /* MC Error Mask Register */ 70#define I5100_EMASK_MEM 0xa8 /* MC Error Mask Register */
71#define I5100_MEM0EINJMSK0 0x200 /* Injection Mask0 Register Channel 0 */
72#define I5100_MEM1EINJMSK0 0x208 /* Injection Mask0 Register Channel 1 */
73#define I5100_MEMXEINJMSK0_EINJEN (1 << 27)
74#define I5100_MEM0EINJMSK1 0x204 /* Injection Mask1 Register Channel 0 */
75#define I5100_MEM1EINJMSK1 0x206 /* Injection Mask1 Register Channel 1 */
76
77/* Device 19, Function 0 */
78#define I5100_DINJ0 0x9a
71 79
72/* device 21 and 22, func 0 */ 80/* device 21 and 22, func 0 */
73#define I5100_MTR_0 0x154 /* Memory Technology Registers 0-3 */ 81#define I5100_MTR_0 0x154 /* Memory Technology Registers 0-3 */
@@ -344,6 +352,14 @@ struct i5100_priv {
344 352
345 struct delayed_work i5100_scrubbing; 353 struct delayed_work i5100_scrubbing;
346 int scrub_enable; 354 int scrub_enable;
355
356 /* Error injection */
357 u8 inject_channel;
358 u8 inject_hlinesel;
359 u8 inject_deviceptr1;
360 u8 inject_deviceptr2;
361 u16 inject_eccmask1;
362 u16 inject_eccmask2;
347}; 363};
348 364
349/* map a rank/chan to a slot number on the mainboard */ 365/* map a rank/chan to a slot number on the mainboard */
@@ -864,6 +880,70 @@ static void i5100_init_csrows(struct mem_ctl_info *mci)
864 } 880 }
865} 881}
866 882
883/****************************************************************************
884 * Error injection routines
885 ****************************************************************************/
886
887static void i5100_do_inject(struct mem_ctl_info *mci)
888{
889 struct i5100_priv *priv = mci->pvt_info;
890 u32 mask0;
891 u16 mask1;
892
893 /* MEM[1:0]EINJMSK0
894 * 31 - ADDRMATCHEN
895 * 29:28 - HLINESEL
896 * 00 Reserved
897 * 01 Lower half of cache line
898 * 10 Upper half of cache line
899 * 11 Both upper and lower parts of cache line
900 * 27 - EINJEN
901 * 25:19 - XORMASK1 for deviceptr1
902 * 9:5 - SEC2RAM for deviceptr2
903 * 4:0 - FIR2RAM for deviceptr1
904 */
905 mask0 = ((priv->inject_hlinesel & 0x3) << 28) |
906 I5100_MEMXEINJMSK0_EINJEN |
907 ((priv->inject_eccmask1 & 0xffff) << 10) |
908 ((priv->inject_deviceptr2 & 0x1f) << 5) |
909 (priv->inject_deviceptr1 & 0x1f);
910
911 /* MEM[1:0]EINJMSK1
912 * 15:0 - XORMASK2 for deviceptr2
913 */
914 mask1 = priv->inject_eccmask2;
915
916 if (priv->inject_channel == 0) {
917 pci_write_config_dword(priv->mc, I5100_MEM0EINJMSK0, mask0);
918 pci_write_config_word(priv->mc, I5100_MEM0EINJMSK1, mask1);
919 } else {
920 pci_write_config_dword(priv->mc, I5100_MEM1EINJMSK0, mask0);
921 pci_write_config_word(priv->mc, I5100_MEM1EINJMSK1, mask1);
922 }
923
924 /* Error Injection Response Function
925 * Intel 5100 Memory Controller Hub Chipset (318378) datasheet
926 * hints about this register but carry no data about them. All
927 * data regarding device 19 is based on experimentation and the
928 * Intel 7300 Chipset Memory Controller Hub (318082) datasheet
929 * which appears to be accurate for the i5100 in this area.
930 *
931 * The injection code don't work without setting this register.
932 * The register needs to be flipped off then on else the hardware
933 * will only preform the first injection.
934 *
935 * Stop condition bits 7:4
936 * 1010 - Stop after one injection
937 * 1011 - Never stop injecting faults
938 *
939 * Start condition bits 3:0
940 * 1010 - Never start
941 * 1011 - Start immediately
942 */
943 pci_write_config_byte(priv->einj, I5100_DINJ0, 0xaa);
944 pci_write_config_byte(priv->einj, I5100_DINJ0, 0xab);
945}
946
867static int i5100_init_one(struct pci_dev *pdev, const struct pci_device_id *id) 947static int i5100_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
868{ 948{
869 int rc; 949 int rc;
@@ -993,6 +1073,13 @@ static int i5100_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
993 mci->set_sdram_scrub_rate = i5100_set_scrub_rate; 1073 mci->set_sdram_scrub_rate = i5100_set_scrub_rate;
994 mci->get_sdram_scrub_rate = i5100_get_scrub_rate; 1074 mci->get_sdram_scrub_rate = i5100_get_scrub_rate;
995 1075
1076 priv->inject_channel = 0;
1077 priv->inject_hlinesel = 0;
1078 priv->inject_deviceptr1 = 0;
1079 priv->inject_deviceptr2 = 0;
1080 priv->inject_eccmask1 = 0;
1081 priv->inject_eccmask2 = 0;
1082
996 i5100_init_csrows(mci); 1083 i5100_init_csrows(mci);
997 1084
998 /* this strange construction seems to be in every driver, dunno why */ 1085 /* this strange construction seems to be in every driver, dunno why */