1 /* Intel 7 core Memory Controller kernel module (Nehalem)
3 * This file may be distributed under the terms of the
4 * GNU General Public License version 2 only.
6 * Copyright (c) 2009 by:
7 * Mauro Carvalho Chehab <mchehab@redhat.com>
9 * Red Hat Inc. http://www.redhat.com
11 * Forked and adapted from the i5400_edac driver
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
20 * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
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>
31 #include "edac_core.h"
33 /* To use the new pci_[read/write]_config_qword instead of two dword */
37 * Alter this version for the module when modifications are made
39 #define I7CORE_REVISION " Ver: 1.0.0 " __DATE__
40 #define EDAC_MOD_STR "i7core_edac"
42 /* HACK: temporary, just to enable all logs, for now */
44 #define debugf0(fmt, arg...) edac_printk(KERN_INFO, "i7core", fmt, ##arg)
49 #define i7core_printk(level, fmt, arg...) \
50 edac_printk(level, "i7core", fmt, ##arg)
52 #define i7core_mc_printk(mci, level, fmt, arg...) \
53 edac_mc_chipset_printk(mci, level, "i7core", fmt, ##arg)
56 * i7core Memory Controller Registers
59 /* OFFSETS for Device 3 Function 0 */
61 #define MC_CONTROL 0x48
62 #define MC_STATUS 0x4c
63 #define MC_MAX_DOD 0x64
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
70 #define MC_TEST_ERR_RCV1 0x60
71 #define DIMM2_COR_ERR(r) ((r) & 0x7fff)
73 #define MC_TEST_ERR_RCV0 0x64
74 #define DIMM1_COR_ERR(r) (((r) >> 16) & 0x7fff)
75 #define DIMM0_COR_ERR(r) ((r) & 0x7fff)
77 /* OFFSETS for Devices 4,5 and 6 Function 0 */
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)
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)
89 #define MC_CHANNEL_RANK_PRESENT 0x7c
90 #define RANK_PRESENT_MASK 0xffff
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
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 MC_DOD_NUMBANK_MASK ((1 << 8) | (1 << 7))
113 #define MC_DOD_NUMBANK(x) (((x) & MC_DOD_NUMBANK_MASK) >> 7)
114 #define MC_DOD_NUMRANK_MASK ((1 << 6) | (1 << 5))
115 #define MC_DOD_NUMRANK(x) (((x) & MC_DOD_NUMRANK_MASK) >> 5)
116 #define MC_DOD_NUMROW_MASK ((1 << 4) | (1 << 3) | (1 << 2))
117 #define MC_DOD_NUMROW(x) (((x) & MC_DOD_NUMROW_MASK) >> 2)
118 #define MC_DOD_NUMCOL_MASK 3
119 #define MC_DOD_NUMCOL(x) ((x) & MC_DOD_NUMCOL_MASK)
121 #define MC_RANK_PRESENT 0x7c
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
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)
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
151 #define MAX_DIMMS 3 /* Max DIMMS per channel */
152 #define MAX_MCR_FUNC 4
153 #define MAX_CHAN_FUNC 3
163 struct i7core_inject {
170 /* Error address mask */
171 int channel, dimm, rank, bank, page, col;
174 struct i7core_channel {
179 struct pci_id_descr {
183 struct pci_dev *pdev;
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 */
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];
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 */
206 #define PCI_DESCR(device, function, device_id) \
208 .func = (function), \
209 .dev_id = (device_id)
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) },
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) },
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) },
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) },
236 #define N_DEVS ARRAY_SIZE(pci_devs)
239 * pci_device_id table for which devices we are looking for
240 * This should match the first device at pci_devs table
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. */
248 /* Table of devices attributes supported by this driver */
249 static const struct i7core_dev_info i7core_devs[] = {
251 .ctl_name = "i7 Core",
252 .fsb_mapping_errors = PCI_DEVICE_ID_INTEL_I7_MCR,
256 static struct edac_pci_ctl_info *i7core_pci;
258 /****************************************************************************
259 Anciliary status routines
260 ****************************************************************************/
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))
267 #define ECC_ENABLED(pvt) ((pvt)->info.mc_status & (1 << 3))
268 #define CH_DISABLED(pvt, ch) ((pvt)->info.mc_status & (1 << ch))
270 /* MC_MAX_DOD read functions */
271 static inline int numdimms(u32 dimms)
273 return (dimms & 0x3) + 1;
276 static inline int numrank(u32 rank)
278 static int ranks[4] = { 1, 2, 4, -EINVAL };
280 return ranks[rank & 0x3];
283 static inline int numbank(u32 bank)
285 static int banks[4] = { 4, 8, 16, -EINVAL };
287 return banks[bank & 0x3];
290 static inline int numrow(u32 row)
292 static int rows[8] = {
293 1 << 12, 1 << 13, 1 << 14, 1 << 15,
294 1 << 16, -EINVAL, -EINVAL, -EINVAL,
297 return rows[row & 0x7];
300 static inline int numcol(u32 col)
302 static int cols[8] = {
303 1 << 10, 1 << 11, 1 << 12, -EINVAL,
305 return cols[col & 0x3];
309 /****************************************************************************
310 Memory check routines
311 ****************************************************************************/
312 static struct pci_dev *get_pdev_slot_func(int slot, int func)
316 for (i = 0; i < N_DEVS; i++) {
317 if (!pci_devs[i].pdev)
320 if (PCI_SLOT(pci_devs[i].pdev->devfn) == slot &&
321 PCI_FUNC(pci_devs[i].pdev->devfn) == func) {
322 return pci_devs[i].pdev;
329 static int i7core_get_active_channels(int *channels, int *csrows)
331 struct pci_dev *pdev = NULL;
338 pdev = get_pdev_slot_func(3, 0);
340 i7core_printk(KERN_ERR, "Couldn't find fn 3.0!!!\n");
344 /* Device 3 function 0 reads */
345 pci_read_config_dword(pdev, MC_STATUS, &status);
346 pci_read_config_dword(pdev, MC_CONTROL, &control);
348 for (i = 0; i < NUM_CHANS; i++) {
350 /* Check if the channel is active */
351 if (!(control & (1 << (8 + i))))
354 /* Check if the channel is disabled */
355 if (status & (1 << i))
358 pdev = get_pdev_slot_func(i + 4, 1);
360 i7core_printk(KERN_ERR, "Couldn't find fn %d.%d!!!\n",
364 /* Devices 4-6 function 1 */
365 pci_read_config_dword(pdev,
366 MC_DOD_CH_DIMM0, &dimm_dod[0]);
367 pci_read_config_dword(pdev,
368 MC_DOD_CH_DIMM1, &dimm_dod[1]);
369 pci_read_config_dword(pdev,
370 MC_DOD_CH_DIMM2, &dimm_dod[2]);
374 for (j = 0; j < 3; j++) {
375 if (!DIMM_PRESENT(dimm_dod[j]))
381 debugf0("Number of active channels: %d\n", *channels);
386 static int get_dimm_config(struct mem_ctl_info *mci)
388 struct i7core_pvt *pvt = mci->pvt_info;
389 struct csrow_info *csr;
390 struct pci_dev *pdev;
392 unsigned long last_page = 0;
396 /* Get data from the MC register, function 0 */
397 pdev = pvt->pci_mcr[0];
401 /* Device 3 function 0 reads */
402 pci_read_config_dword(pdev, MC_CONTROL, &pvt->info.mc_control);
403 pci_read_config_dword(pdev, MC_STATUS, &pvt->info.mc_status);
404 pci_read_config_dword(pdev, MC_MAX_DOD, &pvt->info.max_dod);
405 pci_read_config_dword(pdev, MC_CHANNEL_MAPPER, &pvt->info.ch_map);
407 debugf0("MC control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n",
408 pvt->info.mc_control, pvt->info.mc_status,
409 pvt->info.max_dod, pvt->info.ch_map);
411 if (ECC_ENABLED(pvt)) {
412 debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt) ? 8 : 4);
414 mode = EDAC_S8ECD8ED;
416 mode = EDAC_S4ECD4ED;
418 debugf0("ECC disabled\n");
422 /* FIXME: need to handle the error codes */
423 debugf0("DOD Max limits: DIMMS: %d, %d-ranked, %d-banked\n",
424 numdimms(pvt->info.max_dod),
425 numrank(pvt->info.max_dod >> 2),
426 numbank(pvt->info.max_dod >> 4));
427 debugf0("DOD Max rows x colums = 0x%x x 0x%x\n",
428 numrow(pvt->info.max_dod >> 6),
429 numcol(pvt->info.max_dod >> 9));
431 debugf0("Memory channel configuration:\n");
433 for (i = 0; i < NUM_CHANS; i++) {
434 u32 data, dimm_dod[3], value[8];
436 if (!CH_ACTIVE(pvt, i)) {
437 debugf0("Channel %i is not active\n", i);
440 if (CH_DISABLED(pvt, i)) {
441 debugf0("Channel %i is disabled\n", i);
445 /* Devices 4-6 function 0 */
446 pci_read_config_dword(pvt->pci_ch[i][0],
447 MC_CHANNEL_DIMM_INIT_PARAMS, &data);
449 pvt->channel[i].ranks = (data & QUAD_RANK_PRESENT) ? 4 : 2;
451 if (data & REGISTERED_DIMM)
456 if (data & THREE_DIMMS_PRESENT)
457 pvt->channel[i].dimms = 3;
458 else if (data & SINGLE_QUAD_RANK_PRESENT)
459 pvt->channel[i].dimms = 1;
461 pvt->channel[i].dimms = 2;
464 /* Devices 4-6 function 1 */
465 pci_read_config_dword(pvt->pci_ch[i][1],
466 MC_DOD_CH_DIMM0, &dimm_dod[0]);
467 pci_read_config_dword(pvt->pci_ch[i][1],
468 MC_DOD_CH_DIMM1, &dimm_dod[1]);
469 pci_read_config_dword(pvt->pci_ch[i][1],
470 MC_DOD_CH_DIMM2, &dimm_dod[2]);
472 debugf0("Ch%d phy rd%d, wr%d (0x%08x): "
473 "%d ranks, %cDIMMs\n",
475 RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i),
477 pvt->channel[i].ranks,
478 (data & REGISTERED_DIMM) ? 'R' : 'U');
480 for (j = 0; j < 3; j++) {
481 u32 banks, ranks, rows, cols;
484 if (!DIMM_PRESENT(dimm_dod[j]))
487 banks = numbank(MC_DOD_NUMBANK(dimm_dod[j]));
488 ranks = numrank(MC_DOD_NUMRANK(dimm_dod[j]));
489 rows = numrow(MC_DOD_NUMROW(dimm_dod[j]));
490 cols = numcol(MC_DOD_NUMCOL(dimm_dod[j]));
492 /* DDR3 has 8 I/O banks */
493 size = (rows * cols * banks * ranks) >> (20 - 3);
495 pvt->channel[i].dimms++;
497 debugf0("\tdimm %d (0x%08x) %d Mb offset: %x, "
499 "numrank: %d, numrow: %#x, numcol: %#x\n",
500 j, dimm_dod[j], size,
501 RANKOFFSET(dimm_dod[j]),
502 banks, ranks, rows, cols);
505 npages = size >> (PAGE_SHIFT - 20);
507 npages = size << (20 - PAGE_SHIFT);
510 csr = &mci->csrows[csrow];
511 csr->first_page = last_page + 1;
513 csr->last_page = last_page;
514 csr->nr_pages = npages;
518 csr->csrow_idx = csrow;
519 csr->nr_channels = 1;
521 csr->channels[0].chan_idx = i;
522 csr->channels[0].ce_count = 0;
532 csr->dtype = DEV_X16;
535 csr->dtype = DEV_UNKNOWN;
538 csr->edac_mode = mode;
544 pci_read_config_dword(pdev, MC_SAG_CH_0, &value[0]);
545 pci_read_config_dword(pdev, MC_SAG_CH_1, &value[1]);
546 pci_read_config_dword(pdev, MC_SAG_CH_2, &value[2]);
547 pci_read_config_dword(pdev, MC_SAG_CH_3, &value[3]);
548 pci_read_config_dword(pdev, MC_SAG_CH_4, &value[4]);
549 pci_read_config_dword(pdev, MC_SAG_CH_5, &value[5]);
550 pci_read_config_dword(pdev, MC_SAG_CH_6, &value[6]);
551 pci_read_config_dword(pdev, MC_SAG_CH_7, &value[7]);
552 debugf0("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i);
553 for (j = 0; j < 8; j++)
554 debugf0("\t\t%#x\t%#x\t%#x\n",
555 (value[j] >> 27) & 0x1,
556 (value[j] >> 24) & 0x7,
557 (value[j] && ((1 << 24) - 1)));
563 /****************************************************************************
564 Error insertion routines
565 ****************************************************************************/
567 /* The i7core has independent error injection features per channel.
568 However, to have a simpler code, we don't allow enabling error injection
569 on more than one channel.
570 Also, since a change at an inject parameter will be applied only at enable,
571 we're disabling error injection on all write calls to the sysfs nodes that
572 controls the error code injection.
574 static int disable_inject(struct mem_ctl_info *mci)
576 struct i7core_pvt *pvt = mci->pvt_info;
578 pvt->inject.enable = 0;
580 if (!pvt->pci_ch[pvt->inject.channel][0])
583 pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
584 MC_CHANNEL_ERROR_MASK, 0);
590 * i7core inject inject.section
592 * accept and store error injection inject.section value
593 * bit 0 - refers to the lower 32-byte half cacheline
594 * bit 1 - refers to the upper 32-byte half cacheline
596 static ssize_t i7core_inject_section_store(struct mem_ctl_info *mci,
597 const char *data, size_t count)
599 struct i7core_pvt *pvt = mci->pvt_info;
603 if (pvt->inject.enable)
606 rc = strict_strtoul(data, 10, &value);
607 if ((rc < 0) || (value > 3))
610 pvt->inject.section = (u32) value;
614 static ssize_t i7core_inject_section_show(struct mem_ctl_info *mci,
617 struct i7core_pvt *pvt = mci->pvt_info;
618 return sprintf(data, "0x%08x\n", pvt->inject.section);
624 * accept and store error injection inject.section value
625 * bit 0 - repeat enable - Enable error repetition
626 * bit 1 - inject ECC error
627 * bit 2 - inject parity error
629 static ssize_t i7core_inject_type_store(struct mem_ctl_info *mci,
630 const char *data, size_t count)
632 struct i7core_pvt *pvt = mci->pvt_info;
636 if (pvt->inject.enable)
639 rc = strict_strtoul(data, 10, &value);
640 if ((rc < 0) || (value > 7))
643 pvt->inject.type = (u32) value;
647 static ssize_t i7core_inject_type_show(struct mem_ctl_info *mci,
650 struct i7core_pvt *pvt = mci->pvt_info;
651 return sprintf(data, "0x%08x\n", pvt->inject.type);
655 * i7core_inject_inject.eccmask_store
657 * The type of error (UE/CE) will depend on the inject.eccmask value:
658 * Any bits set to a 1 will flip the corresponding ECC bit
659 * Correctable errors can be injected by flipping 1 bit or the bits within
660 * a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or
661 * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an
662 * uncorrectable error to be injected.
664 static ssize_t i7core_inject_eccmask_store(struct mem_ctl_info *mci,
665 const char *data, size_t count)
667 struct i7core_pvt *pvt = mci->pvt_info;
671 if (pvt->inject.enable)
674 rc = strict_strtoul(data, 10, &value);
678 pvt->inject.eccmask = (u32) value;
682 static ssize_t i7core_inject_eccmask_show(struct mem_ctl_info *mci,
685 struct i7core_pvt *pvt = mci->pvt_info;
686 return sprintf(data, "0x%08x\n", pvt->inject.eccmask);
692 * The type of error (UE/CE) will depend on the inject.eccmask value:
693 * Any bits set to a 1 will flip the corresponding ECC bit
694 * Correctable errors can be injected by flipping 1 bit or the bits within
695 * a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or
696 * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an
697 * uncorrectable error to be injected.
699 static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci,
700 const char *data, size_t count)
702 struct i7core_pvt *pvt = mci->pvt_info;
707 if (pvt->inject.enable)
711 cmd = strsep((char **) &data, ":");
714 val = strsep((char **) &data, " \n\t");
718 if (!strcasecmp(val, "any"))
721 rc = strict_strtol(val, 10, &value);
722 if ((rc < 0) || (value < 0))
726 if (!strcasecmp(cmd, "channel")) {
728 pvt->inject.channel = value;
731 } else if (!strcasecmp(cmd, "dimm")) {
733 pvt->inject.dimm = value;
736 } else if (!strcasecmp(cmd, "rank")) {
738 pvt->inject.rank = value;
741 } else if (!strcasecmp(cmd, "bank")) {
743 pvt->inject.bank = value;
746 } else if (!strcasecmp(cmd, "page")) {
748 pvt->inject.page = value;
751 } else if (!strcasecmp(cmd, "col") ||
752 !strcasecmp(cmd, "column")) {
754 pvt->inject.col = value;
763 static ssize_t i7core_inject_addrmatch_show(struct mem_ctl_info *mci,
766 struct i7core_pvt *pvt = mci->pvt_info;
767 char channel[4], dimm[4], bank[4], rank[4], page[7], col[7];
769 if (pvt->inject.channel < 0)
770 sprintf(channel, "any");
772 sprintf(channel, "%d", pvt->inject.channel);
773 if (pvt->inject.dimm < 0)
774 sprintf(dimm, "any");
776 sprintf(dimm, "%d", pvt->inject.dimm);
777 if (pvt->inject.bank < 0)
778 sprintf(bank, "any");
780 sprintf(bank, "%d", pvt->inject.bank);
781 if (pvt->inject.rank < 0)
782 sprintf(rank, "any");
784 sprintf(rank, "%d", pvt->inject.rank);
785 if (pvt->inject.page < 0)
786 sprintf(page, "any");
788 sprintf(page, "0x%04x", pvt->inject.page);
789 if (pvt->inject.col < 0)
792 sprintf(col, "0x%04x", pvt->inject.col);
794 return sprintf(data, "channel: %s\ndimm: %s\nbank: %s\n"
795 "rank: %s\npage: %s\ncolumn: %s\n",
796 channel, dimm, bank, rank, page, col);
800 * This routine prepares the Memory Controller for error injection.
801 * The error will be injected when some process tries to write to the
802 * memory that matches the given criteria.
803 * The criteria can be set in terms of a mask where dimm, rank, bank, page
804 * and col can be specified.
805 * A -1 value for any of the mask items will make the MCU to ignore
806 * that matching criteria for error injection.
808 * It should be noticed that the error will only happen after a write operation
809 * on a memory that matches the condition. if REPEAT_EN is not enabled at
810 * inject mask, then it will produce just one error. Otherwise, it will repeat
811 * until the injectmask would be cleaned.
813 * FIXME: This routine assumes that MAXNUMDIMMS value of MC_MAX_DOD
814 * is reliable enough to check if the MC is using the
815 * three channels. However, this is not clear at the datasheet.
817 static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci,
818 const char *data, size_t count)
820 struct i7core_pvt *pvt = mci->pvt_info;
826 if (!pvt->pci_ch[pvt->inject.channel][0])
829 rc = strict_strtoul(data, 10, &enable);
834 pvt->inject.enable = 1;
840 /* Sets pvt->inject.dimm mask */
841 if (pvt->inject.dimm < 0)
844 if (pvt->channel[pvt->inject.channel].dimms > 2)
845 mask |= (pvt->inject.dimm & 0x3L) << 35;
847 mask |= (pvt->inject.dimm & 0x1L) << 36;
850 /* Sets pvt->inject.rank mask */
851 if (pvt->inject.rank < 0)
854 if (pvt->channel[pvt->inject.channel].dimms > 2)
855 mask |= (pvt->inject.rank & 0x1L) << 34;
857 mask |= (pvt->inject.rank & 0x3L) << 34;
860 /* Sets pvt->inject.bank mask */
861 if (pvt->inject.bank < 0)
864 mask |= (pvt->inject.bank & 0x15L) << 30;
866 /* Sets pvt->inject.page mask */
867 if (pvt->inject.page < 0)
870 mask |= (pvt->inject.page & 0xffffL) << 14;
872 /* Sets pvt->inject.column mask */
873 if (pvt->inject.col < 0)
876 mask |= (pvt->inject.col & 0x3fffL);
879 pci_write_config_qword(pvt->pci_ch[pvt->inject.channel][0],
880 MC_CHANNEL_ADDR_MATCH, mask);
882 pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
883 MC_CHANNEL_ADDR_MATCH, mask);
884 pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
885 MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L);
891 pci_read_config_qword(pvt->pci_ch[pvt->inject.channel][0],
892 MC_CHANNEL_ADDR_MATCH, &rdmask);
893 debugf0("Inject addr match write 0x%016llx, read: 0x%016llx\n",
896 u32 rdmask1, rdmask2;
898 pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0],
899 MC_CHANNEL_ADDR_MATCH, &rdmask1);
900 pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0],
901 MC_CHANNEL_ADDR_MATCH + 4, &rdmask2);
903 debugf0("Inject addr match write 0x%016llx, read: 0x%08x%08x\n",
904 mask, rdmask1, rdmask2);
908 pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
909 MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask);
913 * bits 1-2: MASK_HALF_CACHELINE
915 * bit 4: INJECT_ADDR_PARITY
918 injectmask = (pvt->inject.type & 1) |
919 (pvt->inject.section & 0x3) << 1 |
920 (pvt->inject.type & 0x6) << (3 - 1);
922 pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
923 MC_CHANNEL_ERROR_MASK, injectmask);
925 debugf0("Error inject addr match 0x%016llx, ecc 0x%08x,"
927 mask, pvt->inject.eccmask, injectmask);
934 static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci,
937 struct i7core_pvt *pvt = mci->pvt_info;
940 pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0],
941 MC_CHANNEL_ERROR_MASK, &injectmask);
943 debugf0("Inject error read: 0x%018x\n", injectmask);
945 if (injectmask & 0x0c)
946 pvt->inject.enable = 1;
948 return sprintf(data, "%d\n", pvt->inject.enable);
951 static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data)
953 struct i7core_pvt *pvt = mci->pvt_info;
955 if (!pvt->ce_count_available)
956 return sprintf(data, "unavailable\n");
958 return sprintf(data, "dimm0: %lu\ndimm1: %lu\ndimm2: %lu\n",
967 static struct mcidev_sysfs_attribute i7core_inj_attrs[] = {
971 .name = "inject_section",
972 .mode = (S_IRUGO | S_IWUSR)
974 .show = i7core_inject_section_show,
975 .store = i7core_inject_section_store,
978 .name = "inject_type",
979 .mode = (S_IRUGO | S_IWUSR)
981 .show = i7core_inject_type_show,
982 .store = i7core_inject_type_store,
985 .name = "inject_eccmask",
986 .mode = (S_IRUGO | S_IWUSR)
988 .show = i7core_inject_eccmask_show,
989 .store = i7core_inject_eccmask_store,
992 .name = "inject_addrmatch",
993 .mode = (S_IRUGO | S_IWUSR)
995 .show = i7core_inject_addrmatch_show,
996 .store = i7core_inject_addrmatch_store,
999 .name = "inject_enable",
1000 .mode = (S_IRUGO | S_IWUSR)
1002 .show = i7core_inject_enable_show,
1003 .store = i7core_inject_enable_store,
1006 .name = "corrected_error_counts",
1007 .mode = (S_IRUGO | S_IWUSR)
1009 .show = i7core_ce_regs_show,
1014 /****************************************************************************
1015 Device initialization routines: put/get, init/exit
1016 ****************************************************************************/
1019 * i7core_put_devices 'put' all the devices that we have
1020 * reserved via 'get'
1022 static void i7core_put_devices(void)
1026 for (i = 0; i < N_DEVS; i++)
1027 pci_dev_put(pci_devs[i].pdev);
1031 * i7core_get_devices Find and perform 'get' operation on the MCH's
1032 * device/functions we want to reference for this driver
1034 * Need to 'get' device 16 func 1 and func 2
1036 static int i7core_get_devices(void)
1039 struct pci_dev *pdev = NULL;
1041 for (i = 0; i < N_DEVS; i++) {
1042 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1043 pci_devs[i].dev_id, NULL);
1045 pci_devs[i].pdev = pdev;
1047 i7core_printk(KERN_ERR,
1048 "Device not found: PCI ID %04x:%04x "
1049 "(dev %d, func %d)\n",
1050 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
1051 pci_devs[i].dev, pci_devs[i].func);
1053 /* Dev 3 function 2 only exists on chips with RDIMMs */
1054 if ((pci_devs[i].dev == 3) && (pci_devs[i].func == 2))
1057 /* End of list, leave */
1063 if (unlikely(PCI_SLOT(pdev->devfn) != pci_devs[i].dev ||
1064 PCI_FUNC(pdev->devfn) != pci_devs[i].func)) {
1065 i7core_printk(KERN_ERR,
1066 "Device PCI ID %04x:%04x "
1067 "has fn %d.%d instead of fn %d.%d\n",
1068 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
1069 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
1070 pci_devs[i].dev, pci_devs[i].func);
1075 /* Be sure that the device is enabled */
1076 rc = pci_enable_device(pdev);
1077 if (unlikely(rc < 0)) {
1078 i7core_printk(KERN_ERR,
1079 "Couldn't enable PCI ID %04x:%04x "
1081 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
1082 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
1086 i7core_printk(KERN_INFO,
1087 "Registered device %0x:%0x fn %d.%d\n",
1088 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
1089 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
1095 i7core_put_devices();
1099 static int mci_bind_devs(struct mem_ctl_info *mci)
1101 struct i7core_pvt *pvt = mci->pvt_info;
1102 struct pci_dev *pdev;
1105 for (i = 0; i < N_DEVS; i++) {
1106 pdev = pci_devs[i].pdev;
1110 func = PCI_FUNC(pdev->devfn);
1111 slot = PCI_SLOT(pdev->devfn);
1113 if (unlikely(func > MAX_MCR_FUNC))
1115 pvt->pci_mcr[func] = pdev;
1116 } else if (likely(slot >= 4 && slot < 4 + NUM_CHANS)) {
1117 if (unlikely(func > MAX_CHAN_FUNC))
1119 pvt->pci_ch[slot - 4][func] = pdev;
1123 debugf0("Associated fn %d.%d, dev = %p\n",
1124 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev);
1129 i7core_printk(KERN_ERR, "Device %d, function %d "
1130 "is out of the expected range\n",
1135 /****************************************************************************
1136 Error check routines
1137 ****************************************************************************/
1139 /* This function is based on the device 3 function 4 registers as described on:
1140 * Intel Xeon Processor 5500 Series Datasheet Volume 2
1141 * http://www.intel.com/Assets/PDF/datasheet/321322.pdf
1142 * also available at:
1143 * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
1145 static void check_mc_test_err(struct mem_ctl_info *mci)
1147 struct i7core_pvt *pvt = mci->pvt_info;
1149 int new0, new1, new2;
1151 if (!pvt->pci_mcr[4]) {
1152 debugf0("%s MCR registers not found\n",__func__);
1156 /* Corrected error reads */
1157 pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV1, &rcv1);
1158 pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV0, &rcv0);
1160 /* Store the new values */
1161 new2 = DIMM2_COR_ERR(rcv1);
1162 new1 = DIMM1_COR_ERR(rcv0);
1163 new0 = DIMM0_COR_ERR(rcv0);
1165 debugf2("%s CE rcv1=0x%08x rcv0=0x%08x, %d %d %d\n",
1166 (pvt->ce_count_available ? "UPDATE" : "READ"),
1167 rcv1, rcv0, new0, new1, new2);
1169 /* Updates CE counters if it is not the first time here */
1170 if (pvt->ce_count_available) {
1171 /* Updates CE counters */
1172 int add0, add1, add2;
1174 add2 = new2 - pvt->last_ce_count[2];
1175 add1 = new1 - pvt->last_ce_count[1];
1176 add0 = new0 - pvt->last_ce_count[0];
1180 pvt->ce_count[2] += add2;
1184 pvt->ce_count[1] += add1;
1188 pvt->ce_count[0] += add0;
1190 pvt->ce_count_available = 1;
1192 /* Store the new values */
1193 pvt->last_ce_count[2] = new2;
1194 pvt->last_ce_count[1] = new1;
1195 pvt->last_ce_count[0] = new0;
1199 * i7core_check_error Retrieve and process errors reported by the
1200 * hardware. Called by the Core module.
1202 static void i7core_check_error(struct mem_ctl_info *mci)
1204 check_mc_test_err(mci);
1208 * i7core_probe Probe for ONE instance of device to see if it is
1211 * 0 for FOUND a device
1212 * < 0 for error code
1214 static int __devinit i7core_probe(struct pci_dev *pdev,
1215 const struct pci_device_id *id)
1217 struct mem_ctl_info *mci;
1218 struct i7core_pvt *pvt;
1221 int dev_idx = id->driver_data;
1224 if (unlikely(dev_idx >= ARRAY_SIZE(i7core_devs)))
1227 /* get the pci devices we want to reserve for our use */
1228 rc = i7core_get_devices();
1229 if (unlikely(rc < 0))
1232 /* Check the number of active and not disabled channels */
1233 rc = i7core_get_active_channels(&num_channels, &num_csrows);
1234 if (unlikely(rc < 0))
1237 /* allocate a new MC control structure */
1238 mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0);
1239 if (unlikely(!mci)) {
1244 debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci);
1246 mci->dev = &pdev->dev; /* record ptr to the generic device */
1248 pvt = mci->pvt_info;
1249 memset(pvt, 0, sizeof(*pvt));
1253 * FIXME: how to handle RDDR3 at MCI level? It is possible to have
1254 * Mixed RDDR3/UDDR3 with Nehalem, provided that they are on different
1257 mci->mtype_cap = MEM_FLAG_DDR3;
1258 mci->edac_ctl_cap = EDAC_FLAG_NONE;
1259 mci->edac_cap = EDAC_FLAG_NONE;
1260 mci->mod_name = "i7core_edac.c";
1261 mci->mod_ver = I7CORE_REVISION;
1262 mci->ctl_name = i7core_devs[dev_idx].ctl_name;
1263 mci->dev_name = pci_name(pdev);
1264 mci->ctl_page_to_phys = NULL;
1265 mci->mc_driver_sysfs_attributes = i7core_inj_attrs;
1266 /* Set the function pointer to an actual operation function */
1267 mci->edac_check = i7core_check_error;
1269 /* Store pci devices at mci for faster access */
1270 rc = mci_bind_devs(mci);
1271 if (unlikely(rc < 0))
1274 /* Get dimm basic config */
1275 get_dimm_config(mci);
1277 /* add this new MC control structure to EDAC's list of MCs */
1278 if (unlikely(edac_mc_add_mc(mci))) {
1279 debugf0("MC: " __FILE__
1280 ": %s(): failed edac_mc_add_mc()\n", __func__);
1281 /* FIXME: perhaps some code should go here that disables error
1282 * reporting if we just enabled it
1289 /* allocating generic PCI control info */
1290 i7core_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
1291 if (unlikely(!i7core_pci)) {
1293 "%s(): Unable to create PCI control\n",
1296 "%s(): PCI error report via EDAC not setup\n",
1300 /* Default error mask is any memory */
1301 pvt->inject.channel = 0;
1302 pvt->inject.dimm = -1;
1303 pvt->inject.rank = -1;
1304 pvt->inject.bank = -1;
1305 pvt->inject.page = -1;
1306 pvt->inject.col = -1;
1308 i7core_printk(KERN_INFO, "Driver loaded.\n");
1316 i7core_put_devices();
1321 * i7core_remove destructor for one instance of device
1324 static void __devexit i7core_remove(struct pci_dev *pdev)
1326 struct mem_ctl_info *mci;
1328 debugf0(__FILE__ ": %s()\n", __func__);
1331 edac_pci_release_generic_ctl(i7core_pci);
1333 mci = edac_mc_del_mc(&pdev->dev);
1338 /* retrieve references to resources, and free those resources */
1339 i7core_put_devices();
1344 MODULE_DEVICE_TABLE(pci, i7core_pci_tbl);
1347 * i7core_driver pci_driver structure for this module
1350 static struct pci_driver i7core_driver = {
1351 .name = "i7core_edac",
1352 .probe = i7core_probe,
1353 .remove = __devexit_p(i7core_remove),
1354 .id_table = i7core_pci_tbl,
1358 * i7core_init Module entry function
1359 * Try to initialize this module for its devices
1361 static int __init i7core_init(void)
1365 debugf2("MC: " __FILE__ ": %s()\n", __func__);
1367 /* Ensure that the OPSTATE is set correctly for POLL or NMI */
1370 pci_rc = pci_register_driver(&i7core_driver);
1372 return (pci_rc < 0) ? pci_rc : 0;
1376 * i7core_exit() Module exit function
1377 * Unregister the driver
1379 static void __exit i7core_exit(void)
1381 debugf2("MC: " __FILE__ ": %s()\n", __func__);
1382 pci_unregister_driver(&i7core_driver);
1385 module_init(i7core_init);
1386 module_exit(i7core_exit);
1388 MODULE_LICENSE("GPL");
1389 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
1390 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
1391 MODULE_DESCRIPTION("MC Driver for Intel i7 Core memory controllers - "
1394 module_param(edac_op_state, int, 0444);
1395 MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");