i7core_edac: Add additional tests for error detection
[safe/jmp/linux-2.6] / drivers / edac / i7core_edac.c
1 /* Intel 7 core  Memory Controller kernel module (Nehalem)
2  *
3  * This file may be distributed under the terms of the
4  * GNU General Public License version 2 only.
5  *
6  * Copyright (c) 2009 by:
7  *       Mauro Carvalho Chehab <mchehab@redhat.com>
8  *
9  * Red Hat Inc. http://www.redhat.com
10  *
11  * Forked and adapted from the i5400_edac driver
12  *
13  * Based on the following public Intel datasheets:
14  * Intel Core i7 Processor Extreme Edition and Intel Core i7 Processor
15  * Datasheet, Volume 2:
16  *      http://download.intel.com/design/processor/datashts/320835.pdf
17  * Intel Xeon Processor 5500 Series Datasheet Volume 2
18  *      http://www.intel.com/Assets/PDF/datasheet/321322.pdf
19  * also available at:
20  *      http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
21  */
22
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/pci.h>
26 #include <linux/pci_ids.h>
27 #include <linux/slab.h>
28 #include <linux/edac.h>
29 #include <linux/mmzone.h>
30
31 #include "edac_core.h"
32
33 /* To use the new pci_[read/write]_config_qword instead of two dword */
34 #define USE_QWORD 1
35
36 /*
37  * Alter this version for the module when modifications are made
38  */
39 #define I7CORE_REVISION    " Ver: 1.0.0 " __DATE__
40 #define EDAC_MOD_STR      "i7core_edac"
41
42 /* HACK: temporary, just to enable all logs, for now */
43 #undef debugf0
44 #define debugf0(fmt, arg...)  edac_printk(KERN_INFO, "i7core", fmt, ##arg)
45
46 /*
47  * Debug macros
48  */
49 #define i7core_printk(level, fmt, arg...)                       \
50         edac_printk(level, "i7core", fmt, ##arg)
51
52 #define i7core_mc_printk(mci, level, fmt, arg...)               \
53         edac_mc_chipset_printk(mci, level, "i7core", fmt, ##arg)
54
55 /*
56  * i7core Memory Controller Registers
57  */
58
59         /* OFFSETS for Device 3 Function 0 */
60
61 #define MC_CONTROL      0x48
62 #define MC_STATUS       0x4c
63 #define MC_MAX_DOD      0x64
64
65 /*
66  * OFFSETS for Device 3 Function 4, as inicated on Xeon 5500 datasheet:
67  * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
68  */
69
70 #define MC_TEST_ERR_RCV1        0x60
71   #define DIMM2_COR_ERR(r)                      ((r) & 0x7fff)
72
73 #define MC_TEST_ERR_RCV0        0x64
74   #define DIMM1_COR_ERR(r)                      (((r) >> 16) & 0x7fff)
75   #define DIMM0_COR_ERR(r)                      ((r) & 0x7fff)
76
77         /* OFFSETS for Devices 4,5 and 6 Function 0 */
78
79 #define MC_CHANNEL_DIMM_INIT_PARAMS 0x58
80   #define THREE_DIMMS_PRESENT           (1 << 24)
81   #define SINGLE_QUAD_RANK_PRESENT      (1 << 23)
82   #define QUAD_RANK_PRESENT             (1 << 22)
83   #define REGISTERED_DIMM               (1 << 15)
84
85 #define MC_CHANNEL_MAPPER       0x60
86   #define RDLCH(r, ch)          ((((r) >> (3 + (ch * 6))) & 0x07) - 1)
87   #define WRLCH(r, ch)          ((((r) >> (ch * 6)) & 0x07) - 1)
88
89 #define MC_CHANNEL_RANK_PRESENT 0x7c
90   #define RANK_PRESENT_MASK             0xffff
91
92 #define MC_CHANNEL_ADDR_MATCH   0xf0
93 #define MC_CHANNEL_ERROR_MASK   0xf8
94 #define MC_CHANNEL_ERROR_INJECT 0xfc
95   #define INJECT_ADDR_PARITY    0x10
96   #define INJECT_ECC            0x08
97   #define MASK_CACHELINE        0x06
98   #define MASK_FULL_CACHELINE   0x06
99   #define MASK_MSB32_CACHELINE  0x04
100   #define MASK_LSB32_CACHELINE  0x02
101   #define NO_MASK_CACHELINE     0x00
102   #define REPEAT_EN             0x01
103
104         /* OFFSETS for Devices 4,5 and 6 Function 1 */
105 #define MC_DOD_CH_DIMM0         0x48
106 #define MC_DOD_CH_DIMM1         0x4c
107 #define MC_DOD_CH_DIMM2         0x50
108   #define RANKOFFSET_MASK       ((1 << 12) | (1 << 11) | (1 << 10))
109   #define RANKOFFSET(x)         ((x & RANKOFFSET_MASK) >> 10)
110   #define DIMM_PRESENT_MASK     (1 << 9)
111   #define DIMM_PRESENT(x)       (((x) & DIMM_PRESENT_MASK) >> 9)
112   #define NUMBANK_MASK          ((1 << 8) | (1 << 7))
113   #define NUMBANK(x)            (((x) & NUMBANK_MASK) >> 7)
114   #define NUMRANK_MASK          ((1 << 6) | (1 << 5))
115   #define NUMRANK(x)            (((x) & NUMRANK_MASK) >> 5)
116   #define NUMROW_MASK           ((1 << 4) | (1 << 3))
117   #define NUMROW(x)             (((x) & NUMROW_MASK) >> 3)
118   #define NUMCOL_MASK           3
119   #define NUMCOL(x)             ((x) & NUMCOL_MASK)
120
121 #define MC_RANK_PRESENT         0x7c
122
123 #define MC_SAG_CH_0     0x80
124 #define MC_SAG_CH_1     0x84
125 #define MC_SAG_CH_2     0x88
126 #define MC_SAG_CH_3     0x8c
127 #define MC_SAG_CH_4     0x90
128 #define MC_SAG_CH_5     0x94
129 #define MC_SAG_CH_6     0x98
130 #define MC_SAG_CH_7     0x9c
131
132 #define MC_RIR_LIMIT_CH_0       0x40
133 #define MC_RIR_LIMIT_CH_1       0x44
134 #define MC_RIR_LIMIT_CH_2       0x48
135 #define MC_RIR_LIMIT_CH_3       0x4C
136 #define MC_RIR_LIMIT_CH_4       0x50
137 #define MC_RIR_LIMIT_CH_5       0x54
138 #define MC_RIR_LIMIT_CH_6       0x58
139 #define MC_RIR_LIMIT_CH_7       0x5C
140 #define MC_RIR_LIMIT_MASK       ((1 << 10) - 1)
141
142 #define MC_RIR_WAY_CH           0x80
143   #define MC_RIR_WAY_OFFSET_MASK        (((1 << 14) - 1) & ~0x7)
144   #define MC_RIR_WAY_RANK_MASK          0x7
145
146 /*
147  * i7core structs
148  */
149
150 #define NUM_CHANS 3
151 #define MAX_DIMMS 3             /* Max DIMMS per channel */
152 #define MAX_MCR_FUNC  4
153 #define MAX_CHAN_FUNC 3
154
155 struct i7core_info {
156         u32     mc_control;
157         u32     mc_status;
158         u32     max_dod;
159         u32     ch_map;
160 };
161
162
163 struct i7core_inject {
164         int     enable;
165
166         u32     section;
167         u32     type;
168         u32     eccmask;
169
170         /* Error address mask */
171         int channel, dimm, rank, bank, page, col;
172 };
173
174 struct i7core_channel {
175         u32             ranks;
176         u32             dimms;
177 };
178
179 struct pci_id_descr {
180         int             dev;
181         int             func;
182         int             dev_id;
183         struct pci_dev  *pdev;
184 };
185
186 struct i7core_pvt {
187         struct pci_dev          *pci_mcr[MAX_MCR_FUNC + 1];
188         struct pci_dev          *pci_ch[NUM_CHANS][MAX_CHAN_FUNC + 1];
189         struct i7core_info      info;
190         struct i7core_inject    inject;
191         struct i7core_channel   channel[NUM_CHANS];
192         int                     channels; /* Number of active channels */
193
194         int             ce_count_available;
195         unsigned long   ce_count[MAX_DIMMS];    /* ECC corrected errors counts per dimm */
196         int             last_ce_count[MAX_DIMMS];
197
198 };
199
200 /* Device name and register DID (Device ID) */
201 struct i7core_dev_info {
202         const char *ctl_name;   /* name for this device */
203         u16 fsb_mapping_errors; /* DID for the branchmap,control */
204 };
205
206 #define PCI_DESCR(device, function, device_id)  \
207         .dev = (device),                        \
208         .func = (function),                     \
209         .dev_id = (device_id)
210
211 struct pci_id_descr pci_devs[] = {
212                 /* Memory controller */
213         { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR)     },
214         { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD)  },
215         { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS)  }, /* if RDIMM is supported */
216         { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) },
217
218                 /* Channel 0 */
219         { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL) },
220         { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH0_ADDR) },
221         { PCI_DESCR(4, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH0_RANK) },
222         { PCI_DESCR(4, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH0_TC)   },
223
224                 /* Channel 1 */
225         { PCI_DESCR(5, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH1_CTRL) },
226         { PCI_DESCR(5, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH1_ADDR) },
227         { PCI_DESCR(5, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH1_RANK) },
228         { PCI_DESCR(5, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH1_TC)   },
229
230                 /* Channel 2 */
231         { PCI_DESCR(6, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH2_CTRL) },
232         { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR) },
233         { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK) },
234         { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC)   },
235 };
236 #define N_DEVS ARRAY_SIZE(pci_devs)
237
238 /*
239  *      pci_device_id   table for which devices we are looking for
240  * This should match the first device at pci_devs table
241  */
242 static const struct pci_device_id i7core_pci_tbl[] __devinitdata = {
243         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_MCR)},
244         {0,}                    /* 0 terminated list. */
245 };
246
247
248 /* Table of devices attributes supported by this driver */
249 static const struct i7core_dev_info i7core_devs[] = {
250         {
251                 .ctl_name = "i7 Core",
252                 .fsb_mapping_errors = PCI_DEVICE_ID_INTEL_I7_MCR,
253         },
254 };
255
256 static struct edac_pci_ctl_info *i7core_pci;
257
258 /****************************************************************************
259                         Anciliary status routines
260  ****************************************************************************/
261
262         /* MC_CONTROL bits */
263 #define CH_ACTIVE(pvt, ch)      ((pvt)->info.mc_control & (1 << (8 + ch)))
264 #define ECCx8(pvt)              ((pvt)->info.mc_control & (1 << 1))
265
266         /* MC_STATUS bits */
267 #define ECC_ENABLED(pvt)        ((pvt)->info.mc_status & (1 << 3))
268 #define CH_DISABLED(pvt, ch)    ((pvt)->info.mc_status & (1 << ch))
269
270         /* MC_MAX_DOD read functions */
271 static inline int maxnumdimms(struct i7core_pvt *pvt)
272 {
273         return (pvt->info.max_dod & 0x3) + 1;
274 }
275
276 static inline int maxnumrank(struct i7core_pvt *pvt)
277 {
278         static int ranks[4] = { 1, 2, 4, -EINVAL };
279
280         return ranks[(pvt->info.max_dod >> 2) & 0x3];
281 }
282
283 static inline int maxnumbank(struct i7core_pvt *pvt)
284 {
285         static int banks[4] = { 4, 8, 16, -EINVAL };
286
287         return banks[(pvt->info.max_dod >> 4) & 0x3];
288 }
289
290 static inline int maxnumrow(struct i7core_pvt *pvt)
291 {
292         static int rows[8] = {
293                 1 << 12, 1 << 13, 1 << 14, 1 << 15,
294                 1 << 16, -EINVAL, -EINVAL, -EINVAL,
295         };
296
297         return rows[((pvt->info.max_dod >> 6) & 0x7)];
298 }
299
300 static inline int maxnumcol(struct i7core_pvt *pvt)
301 {
302         static int cols[8] = {
303                 1 << 10, 1 << 11, 1 << 12, -EINVAL,
304         };
305         return cols[((pvt->info.max_dod >> 9) & 0x3) << 12];
306 }
307
308
309 /****************************************************************************
310                         Memory check routines
311  ****************************************************************************/
312 static int i7core_get_active_channels(int *channels)
313 {
314         struct pci_dev *pdev = NULL;
315         int i;
316         u32 status, control;
317
318         *channels = 0;
319
320         for (i = 0; i < N_DEVS; i++) {
321                 if (!pci_devs[i].pdev)
322                         continue;
323
324                 if (PCI_SLOT(pci_devs[i].pdev->devfn) == 3 &&
325                     PCI_FUNC(pci_devs[i].pdev->devfn) == 0) {
326                         pdev = pci_devs[i].pdev;
327                         break;
328                 }
329         }
330
331         if (!pdev)
332                 return -ENODEV;
333
334         /* Device 3 function 0 reads */
335         pci_read_config_dword(pdev, MC_STATUS, &status);
336         pci_read_config_dword(pdev, MC_CONTROL, &control);
337
338         for (i = 0; i < NUM_CHANS; i++) {
339                 /* Check if the channel is active */
340                 if (!(control & (1 << (8 + i))))
341                         continue;
342
343                 /* Check if the channel is disabled */
344                 if (status & (1 << i)) {
345                         continue;
346                 }
347
348                 (*channels)++;
349         }
350
351         return 0;
352 }
353
354 static int get_dimm_config(struct mem_ctl_info *mci)
355 {
356         struct i7core_pvt *pvt = mci->pvt_info;
357         int i;
358
359         if (!pvt->pci_mcr[0])
360                 return -ENODEV;
361
362         /* Device 3 function 0 reads */
363         pci_read_config_dword(pvt->pci_mcr[0], MC_CONTROL,
364                                                &pvt->info.mc_control);
365         pci_read_config_dword(pvt->pci_mcr[0], MC_STATUS,
366                                                &pvt->info.mc_status);
367         pci_read_config_dword(pvt->pci_mcr[0], MC_MAX_DOD,
368                                                &pvt->info.max_dod);
369         pci_read_config_dword(pvt->pci_mcr[0], MC_CHANNEL_MAPPER,
370                                                &pvt->info.ch_map);
371
372         debugf0("MC control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n",
373                 pvt->info.mc_control, pvt->info.mc_status,
374                 pvt->info.max_dod, pvt->info.ch_map);
375
376         if (ECC_ENABLED(pvt))
377                 debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt)?8:4);
378         else
379                 debugf0("ECC disabled\n");
380
381         /* FIXME: need to handle the error codes */
382         debugf0("DOD Maximum limits: DIMMS: %d, %d-ranked, %d-banked\n",
383                 maxnumdimms(pvt), maxnumrank(pvt), maxnumbank(pvt));
384         debugf0("DOD Maximum rows x colums = 0x%x x 0x%x\n",
385                 maxnumrow(pvt), maxnumcol(pvt));
386
387         debugf0("Memory channel configuration:\n");
388
389         for (i = 0; i < NUM_CHANS; i++) {
390                 u32 data;
391
392                 if (!CH_ACTIVE(pvt, i)) {
393                         debugf0("Channel %i is not active\n", i);
394                         continue;
395                 }
396                 if (CH_DISABLED(pvt, i)) {
397                         debugf0("Channel %i is disabled\n", i);
398                         continue;
399                 }
400
401                 /* Devices 4-6 function 0 */
402                 pci_read_config_dword(pvt->pci_ch[i][0],
403                                 MC_CHANNEL_DIMM_INIT_PARAMS, &data);
404
405                 pvt->channel[i].ranks = (data & QUAD_RANK_PRESENT)? 4 : 2;
406
407                 if (data & THREE_DIMMS_PRESENT)
408                         pvt->channel[i].dimms = 3;
409                 else if (data & SINGLE_QUAD_RANK_PRESENT)
410                         pvt->channel[i].dimms = 1;
411                 else
412                         pvt->channel[i].dimms = 2;
413
414                 debugf0("Ch%d (0x%08x): rd ch %d, wr ch %d, "
415                         "%d ranks, %d %cDIMMs\n",
416                         i, data,
417                         RDLCH(pvt->info.ch_map, i),
418                         WRLCH(pvt->info.ch_map, i),
419                         pvt->channel[i].ranks, pvt->channel[i].dimms,
420                         (data & REGISTERED_DIMM)? 'R' : 'U' );
421         }
422
423         return 0;
424 }
425
426 /****************************************************************************
427                         Error insertion routines
428  ****************************************************************************/
429
430 /* The i7core has independent error injection features per channel.
431    However, to have a simpler code, we don't allow enabling error injection
432    on more than one channel.
433    Also, since a change at an inject parameter will be applied only at enable,
434    we're disabling error injection on all write calls to the sysfs nodes that
435    controls the error code injection.
436  */
437 static int disable_inject(struct mem_ctl_info *mci)
438 {
439         struct i7core_pvt *pvt = mci->pvt_info;
440
441         pvt->inject.enable = 0;
442
443         if (!pvt->pci_ch[pvt->inject.channel][0])
444                 return -ENODEV;
445
446         pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
447                                 MC_CHANNEL_ERROR_MASK, 0);
448
449         return 0;
450 }
451
452 /*
453  * i7core inject inject.section
454  *
455  *      accept and store error injection inject.section value
456  *      bit 0 - refers to the lower 32-byte half cacheline
457  *      bit 1 - refers to the upper 32-byte half cacheline
458  */
459 static ssize_t i7core_inject_section_store(struct mem_ctl_info *mci,
460                                            const char *data, size_t count)
461 {
462         struct i7core_pvt *pvt = mci->pvt_info;
463         unsigned long value;
464         int rc;
465
466         if (pvt->inject.enable)
467                  disable_inject(mci);
468
469         rc = strict_strtoul(data, 10, &value);
470         if ((rc < 0) || (value > 3))
471                 return 0;
472
473         pvt->inject.section = (u32) value;
474         return count;
475 }
476
477 static ssize_t i7core_inject_section_show(struct mem_ctl_info *mci,
478                                               char *data)
479 {
480         struct i7core_pvt *pvt = mci->pvt_info;
481         return sprintf(data, "0x%08x\n", pvt->inject.section);
482 }
483
484 /*
485  * i7core inject.type
486  *
487  *      accept and store error injection inject.section value
488  *      bit 0 - repeat enable - Enable error repetition
489  *      bit 1 - inject ECC error
490  *      bit 2 - inject parity error
491  */
492 static ssize_t i7core_inject_type_store(struct mem_ctl_info *mci,
493                                         const char *data, size_t count)
494 {
495         struct i7core_pvt *pvt = mci->pvt_info;
496         unsigned long value;
497         int rc;
498
499         if (pvt->inject.enable)
500                  disable_inject(mci);
501
502         rc = strict_strtoul(data, 10, &value);
503         if ((rc < 0) || (value > 7))
504                 return 0;
505
506         pvt->inject.type = (u32) value;
507         return count;
508 }
509
510 static ssize_t i7core_inject_type_show(struct mem_ctl_info *mci,
511                                               char *data)
512 {
513         struct i7core_pvt *pvt = mci->pvt_info;
514         return sprintf(data, "0x%08x\n", pvt->inject.type);
515 }
516
517 /*
518  * i7core_inject_inject.eccmask_store
519  *
520  * The type of error (UE/CE) will depend on the inject.eccmask value:
521  *   Any bits set to a 1 will flip the corresponding ECC bit
522  *   Correctable errors can be injected by flipping 1 bit or the bits within
523  *   a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or
524  *   23:16 and 31:24). Flipping bits in two symbol pairs will cause an
525  *   uncorrectable error to be injected.
526  */
527 static ssize_t i7core_inject_eccmask_store(struct mem_ctl_info *mci,
528                                         const char *data, size_t count)
529 {
530         struct i7core_pvt *pvt = mci->pvt_info;
531         unsigned long value;
532         int rc;
533
534         if (pvt->inject.enable)
535                  disable_inject(mci);
536
537         rc = strict_strtoul(data, 10, &value);
538         if (rc < 0)
539                 return 0;
540
541         pvt->inject.eccmask = (u32) value;
542         return count;
543 }
544
545 static ssize_t i7core_inject_eccmask_show(struct mem_ctl_info *mci,
546                                               char *data)
547 {
548         struct i7core_pvt *pvt = mci->pvt_info;
549         return sprintf(data, "0x%08x\n", pvt->inject.eccmask);
550 }
551
552 /*
553  * i7core_addrmatch
554  *
555  * The type of error (UE/CE) will depend on the inject.eccmask value:
556  *   Any bits set to a 1 will flip the corresponding ECC bit
557  *   Correctable errors can be injected by flipping 1 bit or the bits within
558  *   a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or
559  *   23:16 and 31:24). Flipping bits in two symbol pairs will cause an
560  *   uncorrectable error to be injected.
561  */
562 static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci,
563                                         const char *data, size_t count)
564 {
565         struct i7core_pvt *pvt = mci->pvt_info;
566         char *cmd, *val;
567         long value;
568         int rc;
569
570         if (pvt->inject.enable)
571                  disable_inject(mci);
572
573         do {
574                 cmd = strsep((char **) &data, ":");
575                 if (!cmd)
576                         break;
577                 val = strsep((char **) &data, " \n\t");
578                 if (!val)
579                         return cmd - data;
580
581                 if (!strcasecmp(val,"any"))
582                         value = -1;
583                 else {
584                         rc = strict_strtol(val, 10, &value);
585                         if ((rc < 0) || (value < 0))
586                                 return cmd - data;
587                 }
588
589                 if (!strcasecmp(cmd,"channel")) {
590                         if (value < 3)
591                                 pvt->inject.channel = value;
592                         else
593                                 return cmd - data;
594                 } else if (!strcasecmp(cmd,"dimm")) {
595                         if (value < 4)
596                                 pvt->inject.dimm = value;
597                         else
598                                 return cmd - data;
599                 } else if (!strcasecmp(cmd,"rank")) {
600                         if (value < 4)
601                                 pvt->inject.rank = value;
602                         else
603                                 return cmd - data;
604                 } else if (!strcasecmp(cmd,"bank")) {
605                         if (value < 4)
606                                 pvt->inject.bank = value;
607                         else
608                                 return cmd - data;
609                 } else if (!strcasecmp(cmd,"page")) {
610                         if (value <= 0xffff)
611                                 pvt->inject.page = value;
612                         else
613                                 return cmd - data;
614                 } else if (!strcasecmp(cmd,"col") ||
615                            !strcasecmp(cmd,"column")) {
616                         if (value <= 0x3fff)
617                                 pvt->inject.col = value;
618                         else
619                                 return cmd - data;
620                 }
621         } while (1);
622
623         return count;
624 }
625
626 static ssize_t i7core_inject_addrmatch_show(struct mem_ctl_info *mci,
627                                               char *data)
628 {
629         struct i7core_pvt *pvt = mci->pvt_info;
630         char channel[4], dimm[4], bank[4], rank[4], page[7], col[7];
631
632         if (pvt->inject.channel < 0)
633                 sprintf(channel, "any");
634         else
635                 sprintf(channel, "%d", pvt->inject.channel);
636         if (pvt->inject.dimm < 0)
637                 sprintf(dimm, "any");
638         else
639                 sprintf(dimm, "%d", pvt->inject.dimm);
640         if (pvt->inject.bank < 0)
641                 sprintf(bank, "any");
642         else
643                 sprintf(bank, "%d", pvt->inject.bank);
644         if (pvt->inject.rank < 0)
645                 sprintf(rank, "any");
646         else
647                 sprintf(rank, "%d", pvt->inject.rank);
648         if (pvt->inject.page < 0)
649                 sprintf(page, "any");
650         else
651                 sprintf(page, "0x%04x", pvt->inject.page);
652         if (pvt->inject.col < 0)
653                 sprintf(col, "any");
654         else
655                 sprintf(col, "0x%04x", pvt->inject.col);
656
657         return sprintf(data, "channel: %s\ndimm: %s\nbank: %s\n"
658                              "rank: %s\npage: %s\ncolumn: %s\n",
659                        channel, dimm, bank, rank, page, col);
660 }
661
662 /*
663  * This routine prepares the Memory Controller for error injection.
664  * The error will be injected when some process tries to write to the
665  * memory that matches the given criteria.
666  * The criteria can be set in terms of a mask where dimm, rank, bank, page
667  * and col can be specified.
668  * A -1 value for any of the mask items will make the MCU to ignore
669  * that matching criteria for error injection.
670  *
671  * It should be noticed that the error will only happen after a write operation
672  * on a memory that matches the condition. if REPEAT_EN is not enabled at
673  * inject mask, then it will produce just one error. Otherwise, it will repeat
674  * until the injectmask would be cleaned.
675  *
676  * FIXME: This routine assumes that MAXNUMDIMMS value of MC_MAX_DOD
677  *    is reliable enough to check if the MC is using the
678  *    three channels. However, this is not clear at the datasheet.
679  */
680 static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci,
681                                        const char *data, size_t count)
682 {
683         struct i7core_pvt *pvt = mci->pvt_info;
684         u32 injectmask;
685         u64 mask = 0;
686         int  rc;
687         long enable;
688
689         if (!pvt->pci_ch[pvt->inject.channel][0])
690                 return 0;
691
692         rc = strict_strtoul(data, 10, &enable);
693         if ((rc < 0))
694                 return 0;
695
696         if (enable) {
697                 pvt->inject.enable = 1;
698         } else {
699                 disable_inject(mci);
700                 return count;
701         }
702
703         /* Sets pvt->inject.dimm mask */
704         if (pvt->inject.dimm < 0)
705                 mask |= 1L << 41;
706         else {
707                 if (pvt->channel[pvt->inject.channel].dimms > 2)
708                         mask |= (pvt->inject.dimm & 0x3L) << 35;
709                 else
710                         mask |= (pvt->inject.dimm & 0x1L) << 36;
711         }
712
713         /* Sets pvt->inject.rank mask */
714         if (pvt->inject.rank < 0)
715                 mask |= 1L << 40;
716         else {
717                 if (pvt->channel[pvt->inject.channel].dimms > 2)
718                         mask |= (pvt->inject.rank & 0x1L) << 34;
719                 else
720                         mask |= (pvt->inject.rank & 0x3L) << 34;
721         }
722
723         /* Sets pvt->inject.bank mask */
724         if (pvt->inject.bank < 0)
725                 mask |= 1L << 39;
726         else
727                 mask |= (pvt->inject.bank & 0x15L) << 30;
728
729         /* Sets pvt->inject.page mask */
730         if (pvt->inject.page < 0)
731                 mask |= 1L << 38;
732         else
733                 mask |= (pvt->inject.page & 0xffffL) << 14;
734
735         /* Sets pvt->inject.column mask */
736         if (pvt->inject.col < 0)
737                 mask |= 1L << 37;
738         else
739                 mask |= (pvt->inject.col & 0x3fffL);
740
741 #if USE_QWORD
742         pci_write_config_qword(pvt->pci_ch[pvt->inject.channel][0],
743                                MC_CHANNEL_ADDR_MATCH, mask);
744 #else
745         pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
746                                MC_CHANNEL_ADDR_MATCH, mask);
747         pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
748                                MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L);
749 #endif
750
751 #if 1
752 #if USE_QWORD
753         u64 rdmask;
754         pci_read_config_qword(pvt->pci_ch[pvt->inject.channel][0],
755                                MC_CHANNEL_ADDR_MATCH, &rdmask);
756         debugf0("Inject addr match write 0x%016llx, read: 0x%016llx\n",
757                 mask, rdmask);
758 #else
759         u32 rdmask1, rdmask2;
760
761         pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0],
762                                MC_CHANNEL_ADDR_MATCH, &rdmask1);
763         pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0],
764                                MC_CHANNEL_ADDR_MATCH + 4, &rdmask2);
765
766         debugf0("Inject addr match write 0x%016llx, read: 0x%08x%08x\n",
767                 mask, rdmask1, rdmask2);
768 #endif
769 #endif
770
771         pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
772                                MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask);
773
774         /*
775          * bit    0: REPEAT_EN
776          * bits 1-2: MASK_HALF_CACHELINE
777          * bit    3: INJECT_ECC
778          * bit    4: INJECT_ADDR_PARITY
779          */
780
781         injectmask = (pvt->inject.type & 1) |
782                      (pvt->inject.section & 0x3) << 1 |
783                      (pvt->inject.type & 0x6) << (3 - 1);
784
785         pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
786                                MC_CHANNEL_ERROR_MASK, injectmask);
787
788         debugf0("Error inject addr match 0x%016llx, ecc 0x%08x, inject 0x%08x\n",
789                 mask, pvt->inject.eccmask, injectmask);
790
791
792
793         return count;
794 }
795
796 static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci,
797                                         char *data)
798 {
799         struct i7core_pvt *pvt = mci->pvt_info;
800         u32 injectmask;
801
802         pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0],
803                                MC_CHANNEL_ERROR_MASK, &injectmask);
804
805         debugf0("Inject error read: 0x%018x\n", injectmask);
806
807         if (injectmask & 0x0c)
808                 pvt->inject.enable = 1;
809
810         return sprintf(data, "%d\n", pvt->inject.enable);
811 }
812
813 static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data)
814 {
815         struct i7core_pvt *pvt = mci->pvt_info;
816
817         if (!pvt->ce_count_available)
818                 return sprintf(data, "unavailable\n");
819
820         return sprintf(data, "dimm0: %lu\ndimm1: %lu\ndimm2: %lu\n",
821                         pvt->ce_count[0],
822                         pvt->ce_count[1],
823                         pvt->ce_count[2]);
824 }
825
826 /*
827  * Sysfs struct
828  */
829 static struct mcidev_sysfs_attribute i7core_inj_attrs[] = {
830
831         {
832                 .attr = {
833                         .name = "inject_section",
834                         .mode = (S_IRUGO | S_IWUSR)
835                 },
836                 .show  = i7core_inject_section_show,
837                 .store = i7core_inject_section_store,
838         }, {
839                 .attr = {
840                         .name = "inject_type",
841                         .mode = (S_IRUGO | S_IWUSR)
842                 },
843                 .show  = i7core_inject_type_show,
844                 .store = i7core_inject_type_store,
845         }, {
846                 .attr = {
847                         .name = "inject_eccmask",
848                         .mode = (S_IRUGO | S_IWUSR)
849                 },
850                 .show  = i7core_inject_eccmask_show,
851                 .store = i7core_inject_eccmask_store,
852         }, {
853                 .attr = {
854                         .name = "inject_addrmatch",
855                         .mode = (S_IRUGO | S_IWUSR)
856                 },
857                 .show  = i7core_inject_addrmatch_show,
858                 .store = i7core_inject_addrmatch_store,
859         }, {
860                 .attr = {
861                         .name = "inject_enable",
862                         .mode = (S_IRUGO | S_IWUSR)
863                 },
864                 .show  = i7core_inject_enable_show,
865                 .store = i7core_inject_enable_store,
866         }, {
867                 .attr = {
868                         .name = "corrected_error_counts",
869                         .mode = (S_IRUGO | S_IWUSR)
870                 },
871                 .show  = i7core_ce_regs_show,
872                 .store = NULL,
873         },
874 };
875
876 /****************************************************************************
877         Device initialization routines: put/get, init/exit
878  ****************************************************************************/
879
880 /*
881  *      i7core_put_devices      'put' all the devices that we have
882  *                              reserved via 'get'
883  */
884 static void i7core_put_devices(void)
885 {
886         int i;
887
888         for (i = 0; i < N_DEVS; i++)
889                 pci_dev_put(pci_devs[i].pdev);
890 }
891
892 /*
893  *      i7core_get_devices      Find and perform 'get' operation on the MCH's
894  *                      device/functions we want to reference for this driver
895  *
896  *                      Need to 'get' device 16 func 1 and func 2
897  */
898 static int i7core_get_devices(void)
899 {
900         int rc, i;
901         struct pci_dev *pdev = NULL;
902
903         for (i = 0; i < N_DEVS; i++) {
904                 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
905                                         pci_devs[i].dev_id, NULL);
906                 if (likely(pdev))
907                         pci_devs[i].pdev = pdev;
908                 else {
909                         i7core_printk(KERN_ERR,
910                                 "Device not found: PCI ID %04x:%04x "
911                                 "(dev %d, func %d)\n",
912                                 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
913                                 pci_devs[i].dev,pci_devs[i].func);
914
915                         /* Dev 3 function 2 only exists on chips with RDIMMs */
916                         if ((pci_devs[i].dev == 3) && (pci_devs[i].func == 2))
917                                 continue;
918
919                         /* End of list, leave */
920                         rc = -ENODEV;
921                         goto error;
922                 }
923
924                 /* Sanity check */
925                 if (unlikely(PCI_SLOT(pdev->devfn) != pci_devs[i].dev ||
926                              PCI_FUNC(pdev->devfn) != pci_devs[i].func)) {
927                         i7core_printk(KERN_ERR,
928                                 "Device PCI ID %04x:%04x "
929                                 "has fn %d.%d instead of fn %d.%d\n",
930                                 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
931                                 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
932                                 pci_devs[i].dev, pci_devs[i].func);
933                         rc = -EINVAL;
934                         goto error;
935                 }
936
937                 /* Be sure that the device is enabled */
938                 rc = pci_enable_device(pdev);
939                 if (unlikely(rc < 0)) {
940                         i7core_printk(KERN_ERR,
941                                 "Couldn't enable PCI ID %04x:%04x "
942                                 "fn %d.%d\n",
943                                 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
944                                 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
945                         goto error;
946                 }
947
948                 i7core_printk(KERN_INFO,
949                                 "Registered device %0x:%0x fn %d.%d\n",
950                                 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
951                                 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
952         }
953
954         return 0;
955
956 error:
957         i7core_put_devices();
958         return -EINVAL;
959 }
960
961 static int mci_bind_devs(struct mem_ctl_info *mci)
962 {
963         struct i7core_pvt *pvt = mci->pvt_info;
964         struct pci_dev *pdev;
965         int i, func, slot;
966
967         for (i = 0; i < N_DEVS; i++) {
968                 pdev = pci_devs[i].pdev;
969                 if (!pdev)
970                         continue;
971
972                 func = PCI_FUNC(pdev->devfn);
973                 slot = PCI_SLOT(pdev->devfn);
974                 if (slot == 3) {
975                         if (unlikely(func > MAX_MCR_FUNC))
976                                 goto error;
977                         pvt->pci_mcr[func] = pdev;
978                 } else if (likely(slot >= 4 && slot < 4 + NUM_CHANS)) {
979                         if (unlikely(func > MAX_CHAN_FUNC))
980                                 goto error;
981                         pvt->pci_ch[slot - 4][func] = pdev;
982                 } else
983                         goto error;
984
985                 debugf0("Associated fn %d.%d, dev = %p\n",
986                         PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev);
987         }
988         return 0;
989
990 error:
991         i7core_printk(KERN_ERR, "Device %d, function %d "
992                       "is out of the expected range\n",
993                       slot, func);
994         return -EINVAL;
995 }
996
997 /****************************************************************************
998                         Error check routines
999  ****************************************************************************/
1000
1001 /* This function is based on the device 3 function 4 registers as described on:
1002  * Intel Xeon Processor 5500 Series Datasheet Volume 2
1003  *      http://www.intel.com/Assets/PDF/datasheet/321322.pdf
1004  * also available at:
1005  *      http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
1006  */
1007 static void check_mc_test_err(struct mem_ctl_info *mci)
1008 {
1009         struct i7core_pvt *pvt = mci->pvt_info;
1010         u32 rcv1, rcv0;
1011         int new0, new1, new2;
1012
1013         if (!pvt->pci_mcr[4]) {
1014                 debugf0("%s MCR registers not found\n",__func__);
1015                 return;
1016         }
1017
1018         /* Corrected error reads */
1019         pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV1, &rcv1);
1020         pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV0, &rcv0);
1021
1022         /* Store the new values */
1023         new2 = DIMM2_COR_ERR(rcv1);
1024         new1 = DIMM1_COR_ERR(rcv0);
1025         new0 = DIMM0_COR_ERR(rcv0);
1026
1027         debugf2("%s CE rcv1=0x%08x rcv0=0x%08x, %d %d %d\n",
1028                 (pvt->ce_count_available ? "UPDATE" : "READ"),
1029                 rcv1, rcv0, new0, new1, new2);
1030
1031         /* Updates CE counters if it is not the first time here */
1032         if (pvt->ce_count_available) {
1033                 /* Updates CE counters */
1034                 int add0, add1, add2;
1035
1036                 add2 = new2 - pvt->last_ce_count[2];
1037                 add1 = new1 - pvt->last_ce_count[1];
1038                 add0 = new0 - pvt->last_ce_count[0];
1039
1040                 if (add2 < 0)
1041                         add2 += 0x7fff;
1042                 pvt->ce_count[2] += add2;
1043
1044                 if (add1 < 0)
1045                         add1 += 0x7fff;
1046                 pvt->ce_count[1] += add1;
1047
1048                 if (add0 < 0)
1049                         add0 += 0x7fff;
1050                 pvt->ce_count[0] += add0;
1051         } else
1052                 pvt->ce_count_available = 1;
1053
1054         /* Store the new values */
1055         pvt->last_ce_count[2] = new2;
1056         pvt->last_ce_count[1] = new1;
1057         pvt->last_ce_count[0] = new0;
1058 }
1059
1060 /*
1061  *      i7core_check_error      Retrieve and process errors reported by the
1062  *                              hardware. Called by the Core module.
1063  */
1064 static void i7core_check_error(struct mem_ctl_info *mci)
1065 {
1066         check_mc_test_err(mci);
1067 }
1068
1069 /*
1070  *      i7core_probe    Probe for ONE instance of device to see if it is
1071  *                      present.
1072  *      return:
1073  *              0 for FOUND a device
1074  *              < 0 for error code
1075  */
1076 static int __devinit i7core_probe(struct pci_dev *pdev,
1077                                   const struct pci_device_id *id)
1078 {
1079         struct mem_ctl_info *mci;
1080         struct i7core_pvt *pvt;
1081         int num_channels = 0;
1082         int num_csrows;
1083         int dev_idx = id->driver_data;
1084
1085         if (unlikely(dev_idx >= ARRAY_SIZE(i7core_devs)))
1086                 return -EINVAL;
1087
1088         /* get the pci devices we want to reserve for our use */
1089         if (unlikely(i7core_get_devices() < 0))
1090                 return -ENODEV;
1091
1092         /* Check the number of active and not disabled channels */
1093         if (unlikely (i7core_get_active_channels(&num_channels)) < 0)
1094                 goto fail0;
1095
1096         /* FIXME: we currently don't know the number of csrows */
1097         num_csrows = num_channels;
1098
1099         /* allocate a new MC control structure */
1100         mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0);
1101         if (unlikely (!mci))
1102                 return -ENOMEM;
1103
1104         debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci);
1105
1106         mci->dev = &pdev->dev;  /* record ptr to the generic device */
1107
1108         pvt = mci->pvt_info;
1109         memset(pvt, 0, sizeof(*pvt));
1110
1111         mci->mc_idx = 0;
1112         mci->mtype_cap = MEM_FLAG_DDR3;         /* FIXME: how to handle RDDR3? */
1113         mci->edac_ctl_cap = EDAC_FLAG_NONE;
1114         mci->edac_cap = EDAC_FLAG_NONE;
1115         mci->mod_name = "i7core_edac.c";
1116         mci->mod_ver = I7CORE_REVISION;
1117         mci->ctl_name = i7core_devs[dev_idx].ctl_name;
1118         mci->dev_name = pci_name(pdev);
1119         mci->ctl_page_to_phys = NULL;
1120         mci->mc_driver_sysfs_attributes = i7core_inj_attrs;
1121         /* Set the function pointer to an actual operation function */
1122         mci->edac_check = i7core_check_error;
1123
1124         /* Store pci devices at mci for faster access */
1125         if (unlikely (mci_bind_devs(mci)) < 0)
1126                 goto fail1;
1127
1128         /* Get dimm basic config */
1129         get_dimm_config(mci);
1130
1131         /* add this new MC control structure to EDAC's list of MCs */
1132         if (unlikely(edac_mc_add_mc(mci)) < 0) {
1133                 debugf0("MC: " __FILE__
1134                         ": %s(): failed edac_mc_add_mc()\n", __func__);
1135                 /* FIXME: perhaps some code should go here that disables error
1136                  * reporting if we just enabled it
1137                  */
1138                 goto fail1;
1139         }
1140
1141         /* allocating generic PCI control info */
1142         i7core_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
1143         if (unlikely (!i7core_pci)) {
1144                 printk(KERN_WARNING
1145                         "%s(): Unable to create PCI control\n",
1146                         __func__);
1147                 printk(KERN_WARNING
1148                         "%s(): PCI error report via EDAC not setup\n",
1149                         __func__);
1150         }
1151
1152         /* Default error mask is any memory */
1153         pvt->inject.channel = 0;
1154         pvt->inject.dimm = -1;
1155         pvt->inject.rank = -1;
1156         pvt->inject.bank = -1;
1157         pvt->inject.page = -1;
1158         pvt->inject.col = -1;
1159
1160         i7core_printk(KERN_INFO, "Driver loaded.\n");
1161
1162         return 0;
1163
1164 fail1:
1165         i7core_put_devices();
1166
1167 fail0:
1168         edac_mc_free(mci);
1169         return -ENODEV;
1170 }
1171
1172 /*
1173  *      i7core_remove   destructor for one instance of device
1174  *
1175  */
1176 static void __devexit i7core_remove(struct pci_dev *pdev)
1177 {
1178         struct mem_ctl_info *mci;
1179
1180         debugf0(__FILE__ ": %s()\n", __func__);
1181
1182         if (i7core_pci)
1183                 edac_pci_release_generic_ctl(i7core_pci);
1184
1185         mci = edac_mc_del_mc(&pdev->dev);
1186
1187         if (!mci)
1188                 return;
1189
1190         /* retrieve references to resources, and free those resources */
1191         i7core_put_devices();
1192
1193         edac_mc_free(mci);
1194 }
1195
1196 MODULE_DEVICE_TABLE(pci, i7core_pci_tbl);
1197
1198 /*
1199  *      i7core_driver   pci_driver structure for this module
1200  *
1201  */
1202 static struct pci_driver i7core_driver = {
1203         .name     = "i7core_edac",
1204         .probe    = i7core_probe,
1205         .remove   = __devexit_p(i7core_remove),
1206         .id_table = i7core_pci_tbl,
1207 };
1208
1209 /*
1210  *      i7core_init             Module entry function
1211  *                      Try to initialize this module for its devices
1212  */
1213 static int __init i7core_init(void)
1214 {
1215         int pci_rc;
1216
1217         debugf2("MC: " __FILE__ ": %s()\n", __func__);
1218
1219         /* Ensure that the OPSTATE is set correctly for POLL or NMI */
1220         opstate_init();
1221
1222         pci_rc = pci_register_driver(&i7core_driver);
1223
1224         return (pci_rc < 0) ? pci_rc : 0;
1225 }
1226
1227 /*
1228  *      i7core_exit()   Module exit function
1229  *                      Unregister the driver
1230  */
1231 static void __exit i7core_exit(void)
1232 {
1233         debugf2("MC: " __FILE__ ": %s()\n", __func__);
1234         pci_unregister_driver(&i7core_driver);
1235 }
1236
1237 module_init(i7core_init);
1238 module_exit(i7core_exit);
1239
1240 MODULE_LICENSE("GPL");
1241 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
1242 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
1243 MODULE_DESCRIPTION("MC Driver for Intel i7 Core memory controllers - "
1244                    I7CORE_REVISION);
1245
1246 module_param(edac_op_state, int, 0444);
1247 MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");