aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/i7core_edac.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-07-09 21:14:35 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-10 10:44:50 -0400
commite9bd2e73793bf0f7fcd8f94b532bb8f5c5b44171 (patch)
tree850cc08ec621dea67cdaf8bb5ef03f14ee452815 /drivers/edac/i7core_edac.c
parentd5381642ab01b084787925acdf26b5524d434476 (diff)
i7core_edac: Adds write unlock to MC registers
The public Intel Xeon 5500 volume 2 datasheet describes, on page 53, session 2.6.7 a register that can lock/unlock Memory Controller the configuration register, called MC_CFG_CONTROL. Adds support for it in the hope that software error injection would work. With my tests with Xeon 35xx, there's still something missing. With a program that does sequencial bit writes at dev 0.0, sometimes, it produces error injection, after unblocking the MC_CFG_CONTROL (and, sometimes, it just locks my testing machine). I'll try later to discover by trial and error what's the register that solves this issue on Xeon 35xx. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac/i7core_edac.c')
-rw-r--r--drivers/edac/i7core_edac.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 3c7bb5f405f6..26cd5c924d56 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -33,7 +33,7 @@
33#include "edac_core.h" 33#include "edac_core.h"
34 34
35/* To use the new pci_[read/write]_config_qword instead of two dword */ 35/* To use the new pci_[read/write]_config_qword instead of two dword */
36#define USE_QWORD 1 36#define USE_QWORD 0
37 37
38/* 38/*
39 * Alter this version for the module when modifications are made 39 * Alter this version for the module when modifications are made
@@ -58,6 +58,10 @@
58 * i7core Memory Controller Registers 58 * i7core Memory Controller Registers
59 */ 59 */
60 60
61 /* OFFSETS for Device 0 Function 0 */
62
63#define MC_CFG_CONTROL 0x90
64
61 /* OFFSETS for Device 3 Function 0 */ 65 /* OFFSETS for Device 3 Function 0 */
62 66
63#define MC_CONTROL 0x48 67#define MC_CONTROL 0x48
@@ -186,6 +190,7 @@ struct pci_id_descr {
186}; 190};
187 191
188struct i7core_pvt { 192struct i7core_pvt {
193 struct pci_dev *pci_noncore;
189 struct pci_dev *pci_mcr[MAX_MCR_FUNC + 1]; 194 struct pci_dev *pci_mcr[MAX_MCR_FUNC + 1];
190 struct pci_dev *pci_ch[NUM_CHANS][MAX_CHAN_FUNC + 1]; 195 struct pci_dev *pci_ch[NUM_CHANS][MAX_CHAN_FUNC + 1];
191 struct i7core_info info; 196 struct i7core_info info;
@@ -222,6 +227,9 @@ struct pci_id_descr pci_devs[] = {
222 { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS) }, /* if RDIMM is supported */ 227 { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS) }, /* if RDIMM is supported */
223 { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) }, 228 { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) },
224 229
230 /* Generic Non-core registers */
231 { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NOCORE) },
232
225 /* Channel 0 */ 233 /* Channel 0 */
226 { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL) }, 234 { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL) },
227 { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH0_ADDR) }, 235 { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH0_ADDR) },
@@ -882,6 +890,16 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci,
882 else 890 else
883 mask |= (pvt->inject.col & 0x3fffL); 891 mask |= (pvt->inject.col & 0x3fffL);
884 892
893 /* Unlock writes to registers */
894 pci_write_config_dword(pvt->pci_noncore, MC_CFG_CONTROL, 0x2);
895 msleep(100);
896
897 /* Zeroes error count registers */
898 pci_write_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV1, 0);
899 pci_write_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV0, 0);
900 pvt->ce_count_available = 0;
901
902
885#if USE_QWORD 903#if USE_QWORD
886 pci_write_config_qword(pvt->pci_ch[pvt->inject.channel][0], 904 pci_write_config_qword(pvt->pci_ch[pvt->inject.channel][0],
887 MC_CHANNEL_ADDR_MATCH, mask); 905 MC_CHANNEL_ADDR_MATCH, mask);
@@ -929,12 +947,15 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci,
929 pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], 947 pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
930 MC_CHANNEL_ERROR_MASK, injectmask); 948 MC_CHANNEL_ERROR_MASK, injectmask);
931 949
950#if 0
951 /* lock writes to registers */
952 pci_write_config_dword(pvt->pci_noncore, MC_CFG_CONTROL, 0);
953#endif
932 debugf0("Error inject addr match 0x%016llx, ecc 0x%08x," 954 debugf0("Error inject addr match 0x%016llx, ecc 0x%08x,"
933 " inject 0x%08x\n", 955 " inject 0x%08x\n",
934 mask, pvt->inject.eccmask, injectmask); 956 mask, pvt->inject.eccmask, injectmask);
935 957
936 958
937
938 return count; 959 return count;
939} 960}
940 961
@@ -1124,12 +1145,15 @@ static int mci_bind_devs(struct mem_ctl_info *mci)
1124 if (unlikely(func > MAX_CHAN_FUNC)) 1145 if (unlikely(func > MAX_CHAN_FUNC))
1125 goto error; 1146 goto error;
1126 pvt->pci_ch[slot - 4][func] = pdev; 1147 pvt->pci_ch[slot - 4][func] = pdev;
1127 } else 1148 } else if (!slot && !func)
1149 pvt->pci_noncore = pdev;
1150 else
1128 goto error; 1151 goto error;
1129 1152
1130 debugf0("Associated fn %d.%d, dev = %p\n", 1153 debugf0("Associated fn %d.%d, dev = %p\n",
1131 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev); 1154 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev);
1132 } 1155 }
1156
1133 return 0; 1157 return 0;
1134 1158
1135error: 1159error: