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>
30 #include <linux/edac_mce.h>
31 #include <linux/spinlock.h>
33 #include "edac_core.h"
35 /* To use the new pci_[read/write]_config_qword instead of two dword */
39 * Alter this version for the module when modifications are made
41 #define I7CORE_REVISION " Ver: 1.0.0 " __DATE__
42 #define EDAC_MOD_STR "i7core_edac"
44 /* HACK: temporary, just to enable all logs, for now */
46 #define debugf0(fmt, arg...) edac_printk(KERN_INFO, "i7core", fmt, ##arg)
51 #define i7core_printk(level, fmt, arg...) \
52 edac_printk(level, "i7core", fmt, ##arg)
54 #define i7core_mc_printk(mci, level, fmt, arg...) \
55 edac_mc_chipset_printk(mci, level, "i7core", fmt, ##arg)
58 * i7core Memory Controller Registers
61 /* OFFSETS for Device 3 Function 0 */
63 #define MC_CONTROL 0x48
64 #define MC_STATUS 0x4c
65 #define MC_MAX_DOD 0x64
68 * OFFSETS for Device 3 Function 4, as inicated on Xeon 5500 datasheet:
69 * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
72 #define MC_TEST_ERR_RCV1 0x60
73 #define DIMM2_COR_ERR(r) ((r) & 0x7fff)
75 #define MC_TEST_ERR_RCV0 0x64
76 #define DIMM1_COR_ERR(r) (((r) >> 16) & 0x7fff)
77 #define DIMM0_COR_ERR(r) ((r) & 0x7fff)
79 /* OFFSETS for Devices 4,5 and 6 Function 0 */
81 #define MC_CHANNEL_DIMM_INIT_PARAMS 0x58
82 #define THREE_DIMMS_PRESENT (1 << 24)
83 #define SINGLE_QUAD_RANK_PRESENT (1 << 23)
84 #define QUAD_RANK_PRESENT (1 << 22)
85 #define REGISTERED_DIMM (1 << 15)
87 #define MC_CHANNEL_MAPPER 0x60
88 #define RDLCH(r, ch) ((((r) >> (3 + (ch * 6))) & 0x07) - 1)
89 #define WRLCH(r, ch) ((((r) >> (ch * 6)) & 0x07) - 1)
91 #define MC_CHANNEL_RANK_PRESENT 0x7c
92 #define RANK_PRESENT_MASK 0xffff
94 #define MC_CHANNEL_ADDR_MATCH 0xf0
95 #define MC_CHANNEL_ERROR_MASK 0xf8
96 #define MC_CHANNEL_ERROR_INJECT 0xfc
97 #define INJECT_ADDR_PARITY 0x10
98 #define INJECT_ECC 0x08
99 #define MASK_CACHELINE 0x06
100 #define MASK_FULL_CACHELINE 0x06
101 #define MASK_MSB32_CACHELINE 0x04
102 #define MASK_LSB32_CACHELINE 0x02
103 #define NO_MASK_CACHELINE 0x00
104 #define REPEAT_EN 0x01
106 /* OFFSETS for Devices 4,5 and 6 Function 1 */
107 #define MC_DOD_CH_DIMM0 0x48
108 #define MC_DOD_CH_DIMM1 0x4c
109 #define MC_DOD_CH_DIMM2 0x50
110 #define RANKOFFSET_MASK ((1 << 12) | (1 << 11) | (1 << 10))
111 #define RANKOFFSET(x) ((x & RANKOFFSET_MASK) >> 10)
112 #define DIMM_PRESENT_MASK (1 << 9)
113 #define DIMM_PRESENT(x) (((x) & DIMM_PRESENT_MASK) >> 9)
114 #define MC_DOD_NUMBANK_MASK ((1 << 8) | (1 << 7))
115 #define MC_DOD_NUMBANK(x) (((x) & MC_DOD_NUMBANK_MASK) >> 7)
116 #define MC_DOD_NUMRANK_MASK ((1 << 6) | (1 << 5))
117 #define MC_DOD_NUMRANK(x) (((x) & MC_DOD_NUMRANK_MASK) >> 5)
118 #define MC_DOD_NUMROW_MASK ((1 << 4) | (1 << 3) | (1 << 2))
119 #define MC_DOD_NUMROW(x) (((x) & MC_DOD_NUMROW_MASK) >> 2)
120 #define MC_DOD_NUMCOL_MASK 3
121 #define MC_DOD_NUMCOL(x) ((x) & MC_DOD_NUMCOL_MASK)
123 #define MC_RANK_PRESENT 0x7c
125 #define MC_SAG_CH_0 0x80
126 #define MC_SAG_CH_1 0x84
127 #define MC_SAG_CH_2 0x88
128 #define MC_SAG_CH_3 0x8c
129 #define MC_SAG_CH_4 0x90
130 #define MC_SAG_CH_5 0x94
131 #define MC_SAG_CH_6 0x98
132 #define MC_SAG_CH_7 0x9c
134 #define MC_RIR_LIMIT_CH_0 0x40
135 #define MC_RIR_LIMIT_CH_1 0x44
136 #define MC_RIR_LIMIT_CH_2 0x48
137 #define MC_RIR_LIMIT_CH_3 0x4C
138 #define MC_RIR_LIMIT_CH_4 0x50
139 #define MC_RIR_LIMIT_CH_5 0x54
140 #define MC_RIR_LIMIT_CH_6 0x58
141 #define MC_RIR_LIMIT_CH_7 0x5C
142 #define MC_RIR_LIMIT_MASK ((1 << 10) - 1)
144 #define MC_RIR_WAY_CH 0x80
145 #define MC_RIR_WAY_OFFSET_MASK (((1 << 14) - 1) & ~0x7)
146 #define MC_RIR_WAY_RANK_MASK 0x7
153 #define MAX_DIMMS 3 /* Max DIMMS per channel */
154 #define MAX_MCR_FUNC 4
155 #define MAX_CHAN_FUNC 3
165 struct i7core_inject {
172 /* Error address mask */
173 int channel, dimm, rank, bank, page, col;
176 struct i7core_channel {
181 struct pci_id_descr {
185 struct pci_dev *pdev;
189 struct pci_dev *pci_mcr[MAX_MCR_FUNC + 1];
190 struct pci_dev *pci_ch[NUM_CHANS][MAX_CHAN_FUNC + 1];
191 struct i7core_info info;
192 struct i7core_inject inject;
193 struct i7core_channel channel[NUM_CHANS];
194 int channels; /* Number of active channels */
196 int ce_count_available;
197 unsigned long ce_count[MAX_DIMMS]; /* ECC corrected errors counts per dimm */
198 int last_ce_count[MAX_DIMMS];
201 struct edac_mce edac_mce;
202 struct mce mce_entry[MCE_LOG_LEN];
207 /* Device name and register DID (Device ID) */
208 struct i7core_dev_info {
209 const char *ctl_name; /* name for this device */
210 u16 fsb_mapping_errors; /* DID for the branchmap,control */
213 #define PCI_DESCR(device, function, device_id) \
215 .func = (function), \
216 .dev_id = (device_id)
218 struct pci_id_descr pci_devs[] = {
219 /* Memory controller */
220 { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) },
221 { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) },
222 { 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) },
226 { 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) },
228 { PCI_DESCR(4, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH0_RANK) },
229 { PCI_DESCR(4, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH0_TC) },
232 { PCI_DESCR(5, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH1_CTRL) },
233 { PCI_DESCR(5, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH1_ADDR) },
234 { PCI_DESCR(5, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH1_RANK) },
235 { PCI_DESCR(5, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH1_TC) },
238 { PCI_DESCR(6, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH2_CTRL) },
239 { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR) },
240 { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK) },
241 { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC) },
243 #define N_DEVS ARRAY_SIZE(pci_devs)
246 * pci_device_id table for which devices we are looking for
247 * This should match the first device at pci_devs table
249 static const struct pci_device_id i7core_pci_tbl[] __devinitdata = {
250 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_MCR)},
251 {0,} /* 0 terminated list. */
255 /* Table of devices attributes supported by this driver */
256 static const struct i7core_dev_info i7core_devs[] = {
258 .ctl_name = "i7 Core",
259 .fsb_mapping_errors = PCI_DEVICE_ID_INTEL_I7_MCR,
263 static struct edac_pci_ctl_info *i7core_pci;
265 /****************************************************************************
266 Anciliary status routines
267 ****************************************************************************/
269 /* MC_CONTROL bits */
270 #define CH_ACTIVE(pvt, ch) ((pvt)->info.mc_control & (1 << (8 + ch)))
271 #define ECCx8(pvt) ((pvt)->info.mc_control & (1 << 1))
274 #define ECC_ENABLED(pvt) ((pvt)->info.mc_status & (1 << 3))
275 #define CH_DISABLED(pvt, ch) ((pvt)->info.mc_status & (1 << ch))
277 /* MC_MAX_DOD read functions */
278 static inline int numdimms(u32 dimms)
280 return (dimms & 0x3) + 1;
283 static inline int numrank(u32 rank)
285 static int ranks[4] = { 1, 2, 4, -EINVAL };
287 return ranks[rank & 0x3];
290 static inline int numbank(u32 bank)
292 static int banks[4] = { 4, 8, 16, -EINVAL };
294 return banks[bank & 0x3];
297 static inline int numrow(u32 row)
299 static int rows[8] = {
300 1 << 12, 1 << 13, 1 << 14, 1 << 15,
301 1 << 16, -EINVAL, -EINVAL, -EINVAL,
304 return rows[row & 0x7];
307 static inline int numcol(u32 col)
309 static int cols[8] = {
310 1 << 10, 1 << 11, 1 << 12, -EINVAL,
312 return cols[col & 0x3];
316 /****************************************************************************
317 Memory check routines
318 ****************************************************************************/
319 static struct pci_dev *get_pdev_slot_func(int slot, int func)
323 for (i = 0; i < N_DEVS; i++) {
324 if (!pci_devs[i].pdev)
327 if (PCI_SLOT(pci_devs[i].pdev->devfn) == slot &&
328 PCI_FUNC(pci_devs[i].pdev->devfn) == func) {
329 return pci_devs[i].pdev;
336 static int i7core_get_active_channels(int *channels, int *csrows)
338 struct pci_dev *pdev = NULL;
345 pdev = get_pdev_slot_func(3, 0);
347 i7core_printk(KERN_ERR, "Couldn't find fn 3.0!!!\n");
351 /* Device 3 function 0 reads */
352 pci_read_config_dword(pdev, MC_STATUS, &status);
353 pci_read_config_dword(pdev, MC_CONTROL, &control);
355 for (i = 0; i < NUM_CHANS; i++) {
357 /* Check if the channel is active */
358 if (!(control & (1 << (8 + i))))
361 /* Check if the channel is disabled */
362 if (status & (1 << i))
365 pdev = get_pdev_slot_func(i + 4, 1);
367 i7core_printk(KERN_ERR, "Couldn't find fn %d.%d!!!\n",
371 /* Devices 4-6 function 1 */
372 pci_read_config_dword(pdev,
373 MC_DOD_CH_DIMM0, &dimm_dod[0]);
374 pci_read_config_dword(pdev,
375 MC_DOD_CH_DIMM1, &dimm_dod[1]);
376 pci_read_config_dword(pdev,
377 MC_DOD_CH_DIMM2, &dimm_dod[2]);
381 for (j = 0; j < 3; j++) {
382 if (!DIMM_PRESENT(dimm_dod[j]))
388 debugf0("Number of active channels: %d\n", *channels);
393 static int get_dimm_config(struct mem_ctl_info *mci)
395 struct i7core_pvt *pvt = mci->pvt_info;
396 struct csrow_info *csr;
397 struct pci_dev *pdev;
399 unsigned long last_page = 0;
403 /* Get data from the MC register, function 0 */
404 pdev = pvt->pci_mcr[0];
408 /* Device 3 function 0 reads */
409 pci_read_config_dword(pdev, MC_CONTROL, &pvt->info.mc_control);
410 pci_read_config_dword(pdev, MC_STATUS, &pvt->info.mc_status);
411 pci_read_config_dword(pdev, MC_MAX_DOD, &pvt->info.max_dod);
412 pci_read_config_dword(pdev, MC_CHANNEL_MAPPER, &pvt->info.ch_map);
414 debugf0("MC control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n",
415 pvt->info.mc_control, pvt->info.mc_status,
416 pvt->info.max_dod, pvt->info.ch_map);
418 if (ECC_ENABLED(pvt)) {
419 debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt) ? 8 : 4);
421 mode = EDAC_S8ECD8ED;
423 mode = EDAC_S4ECD4ED;
425 debugf0("ECC disabled\n");
429 /* FIXME: need to handle the error codes */
430 debugf0("DOD Max limits: DIMMS: %d, %d-ranked, %d-banked\n",
431 numdimms(pvt->info.max_dod),
432 numrank(pvt->info.max_dod >> 2),
433 numbank(pvt->info.max_dod >> 4));
434 debugf0("DOD Max rows x colums = 0x%x x 0x%x\n",
435 numrow(pvt->info.max_dod >> 6),
436 numcol(pvt->info.max_dod >> 9));
438 debugf0("Memory channel configuration:\n");
440 for (i = 0; i < NUM_CHANS; i++) {
441 u32 data, dimm_dod[3], value[8];
443 if (!CH_ACTIVE(pvt, i)) {
444 debugf0("Channel %i is not active\n", i);
447 if (CH_DISABLED(pvt, i)) {
448 debugf0("Channel %i is disabled\n", i);
452 /* Devices 4-6 function 0 */
453 pci_read_config_dword(pvt->pci_ch[i][0],
454 MC_CHANNEL_DIMM_INIT_PARAMS, &data);
456 pvt->channel[i].ranks = (data & QUAD_RANK_PRESENT) ? 4 : 2;
458 if (data & REGISTERED_DIMM)
463 if (data & THREE_DIMMS_PRESENT)
464 pvt->channel[i].dimms = 3;
465 else if (data & SINGLE_QUAD_RANK_PRESENT)
466 pvt->channel[i].dimms = 1;
468 pvt->channel[i].dimms = 2;
471 /* Devices 4-6 function 1 */
472 pci_read_config_dword(pvt->pci_ch[i][1],
473 MC_DOD_CH_DIMM0, &dimm_dod[0]);
474 pci_read_config_dword(pvt->pci_ch[i][1],
475 MC_DOD_CH_DIMM1, &dimm_dod[1]);
476 pci_read_config_dword(pvt->pci_ch[i][1],
477 MC_DOD_CH_DIMM2, &dimm_dod[2]);
479 debugf0("Ch%d phy rd%d, wr%d (0x%08x): "
480 "%d ranks, %cDIMMs\n",
482 RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i),
484 pvt->channel[i].ranks,
485 (data & REGISTERED_DIMM) ? 'R' : 'U');
487 for (j = 0; j < 3; j++) {
488 u32 banks, ranks, rows, cols;
491 if (!DIMM_PRESENT(dimm_dod[j]))
494 banks = numbank(MC_DOD_NUMBANK(dimm_dod[j]));
495 ranks = numrank(MC_DOD_NUMRANK(dimm_dod[j]));
496 rows = numrow(MC_DOD_NUMROW(dimm_dod[j]));
497 cols = numcol(MC_DOD_NUMCOL(dimm_dod[j]));
499 /* DDR3 has 8 I/O banks */
500 size = (rows * cols * banks * ranks) >> (20 - 3);
502 pvt->channel[i].dimms++;
504 debugf0("\tdimm %d (0x%08x) %d Mb offset: %x, "
506 "numrank: %d, numrow: %#x, numcol: %#x\n",
507 j, dimm_dod[j], size,
508 RANKOFFSET(dimm_dod[j]),
509 banks, ranks, rows, cols);
512 npages = size >> (PAGE_SHIFT - 20);
514 npages = size << (20 - PAGE_SHIFT);
517 csr = &mci->csrows[csrow];
518 csr->first_page = last_page + 1;
520 csr->last_page = last_page;
521 csr->nr_pages = npages;
525 csr->csrow_idx = csrow;
526 csr->nr_channels = 1;
528 csr->channels[0].chan_idx = i;
529 csr->channels[0].ce_count = 0;
539 csr->dtype = DEV_X16;
542 csr->dtype = DEV_UNKNOWN;
545 csr->edac_mode = mode;
551 pci_read_config_dword(pdev, MC_SAG_CH_0, &value[0]);
552 pci_read_config_dword(pdev, MC_SAG_CH_1, &value[1]);
553 pci_read_config_dword(pdev, MC_SAG_CH_2, &value[2]);
554 pci_read_config_dword(pdev, MC_SAG_CH_3, &value[3]);
555 pci_read_config_dword(pdev, MC_SAG_CH_4, &value[4]);
556 pci_read_config_dword(pdev, MC_SAG_CH_5, &value[5]);
557 pci_read_config_dword(pdev, MC_SAG_CH_6, &value[6]);
558 pci_read_config_dword(pdev, MC_SAG_CH_7, &value[7]);
559 debugf0("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i);
560 for (j = 0; j < 8; j++)
561 debugf0("\t\t%#x\t%#x\t%#x\n",
562 (value[j] >> 27) & 0x1,
563 (value[j] >> 24) & 0x7,
564 (value[j] && ((1 << 24) - 1)));
570 /****************************************************************************
571 Error insertion routines
572 ****************************************************************************/
574 /* The i7core has independent error injection features per channel.
575 However, to have a simpler code, we don't allow enabling error injection
576 on more than one channel.
577 Also, since a change at an inject parameter will be applied only at enable,
578 we're disabling error injection on all write calls to the sysfs nodes that
579 controls the error code injection.
581 static int disable_inject(struct mem_ctl_info *mci)
583 struct i7core_pvt *pvt = mci->pvt_info;
585 pvt->inject.enable = 0;
587 if (!pvt->pci_ch[pvt->inject.channel][0])
590 pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
591 MC_CHANNEL_ERROR_MASK, 0);
597 * i7core inject inject.section
599 * accept and store error injection inject.section value
600 * bit 0 - refers to the lower 32-byte half cacheline
601 * bit 1 - refers to the upper 32-byte half cacheline
603 static ssize_t i7core_inject_section_store(struct mem_ctl_info *mci,
604 const char *data, size_t count)
606 struct i7core_pvt *pvt = mci->pvt_info;
610 if (pvt->inject.enable)
613 rc = strict_strtoul(data, 10, &value);
614 if ((rc < 0) || (value > 3))
617 pvt->inject.section = (u32) value;
621 static ssize_t i7core_inject_section_show(struct mem_ctl_info *mci,
624 struct i7core_pvt *pvt = mci->pvt_info;
625 return sprintf(data, "0x%08x\n", pvt->inject.section);
631 * accept and store error injection inject.section value
632 * bit 0 - repeat enable - Enable error repetition
633 * bit 1 - inject ECC error
634 * bit 2 - inject parity error
636 static ssize_t i7core_inject_type_store(struct mem_ctl_info *mci,
637 const char *data, size_t count)
639 struct i7core_pvt *pvt = mci->pvt_info;
643 if (pvt->inject.enable)
646 rc = strict_strtoul(data, 10, &value);
647 if ((rc < 0) || (value > 7))
650 pvt->inject.type = (u32) value;
654 static ssize_t i7core_inject_type_show(struct mem_ctl_info *mci,
657 struct i7core_pvt *pvt = mci->pvt_info;
658 return sprintf(data, "0x%08x\n", pvt->inject.type);
662 * i7core_inject_inject.eccmask_store
664 * The type of error (UE/CE) will depend on the inject.eccmask value:
665 * Any bits set to a 1 will flip the corresponding ECC bit
666 * Correctable errors can be injected by flipping 1 bit or the bits within
667 * a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or
668 * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an
669 * uncorrectable error to be injected.
671 static ssize_t i7core_inject_eccmask_store(struct mem_ctl_info *mci,
672 const char *data, size_t count)
674 struct i7core_pvt *pvt = mci->pvt_info;
678 if (pvt->inject.enable)
681 rc = strict_strtoul(data, 10, &value);
685 pvt->inject.eccmask = (u32) value;
689 static ssize_t i7core_inject_eccmask_show(struct mem_ctl_info *mci,
692 struct i7core_pvt *pvt = mci->pvt_info;
693 return sprintf(data, "0x%08x\n", pvt->inject.eccmask);
699 * The type of error (UE/CE) will depend on the inject.eccmask value:
700 * Any bits set to a 1 will flip the corresponding ECC bit
701 * Correctable errors can be injected by flipping 1 bit or the bits within
702 * a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or
703 * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an
704 * uncorrectable error to be injected.
706 static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci,
707 const char *data, size_t count)
709 struct i7core_pvt *pvt = mci->pvt_info;
714 if (pvt->inject.enable)
718 cmd = strsep((char **) &data, ":");
721 val = strsep((char **) &data, " \n\t");
725 if (!strcasecmp(val, "any"))
728 rc = strict_strtol(val, 10, &value);
729 if ((rc < 0) || (value < 0))
733 if (!strcasecmp(cmd, "channel")) {
735 pvt->inject.channel = value;
738 } else if (!strcasecmp(cmd, "dimm")) {
740 pvt->inject.dimm = value;
743 } else if (!strcasecmp(cmd, "rank")) {
745 pvt->inject.rank = value;
748 } else if (!strcasecmp(cmd, "bank")) {
750 pvt->inject.bank = value;
753 } else if (!strcasecmp(cmd, "page")) {
755 pvt->inject.page = value;
758 } else if (!strcasecmp(cmd, "col") ||
759 !strcasecmp(cmd, "column")) {
761 pvt->inject.col = value;
770 static ssize_t i7core_inject_addrmatch_show(struct mem_ctl_info *mci,
773 struct i7core_pvt *pvt = mci->pvt_info;
774 char channel[4], dimm[4], bank[4], rank[4], page[7], col[7];
776 if (pvt->inject.channel < 0)
777 sprintf(channel, "any");
779 sprintf(channel, "%d", pvt->inject.channel);
780 if (pvt->inject.dimm < 0)
781 sprintf(dimm, "any");
783 sprintf(dimm, "%d", pvt->inject.dimm);
784 if (pvt->inject.bank < 0)
785 sprintf(bank, "any");
787 sprintf(bank, "%d", pvt->inject.bank);
788 if (pvt->inject.rank < 0)
789 sprintf(rank, "any");
791 sprintf(rank, "%d", pvt->inject.rank);
792 if (pvt->inject.page < 0)
793 sprintf(page, "any");
795 sprintf(page, "0x%04x", pvt->inject.page);
796 if (pvt->inject.col < 0)
799 sprintf(col, "0x%04x", pvt->inject.col);
801 return sprintf(data, "channel: %s\ndimm: %s\nbank: %s\n"
802 "rank: %s\npage: %s\ncolumn: %s\n",
803 channel, dimm, bank, rank, page, col);
807 * This routine prepares the Memory Controller for error injection.
808 * The error will be injected when some process tries to write to the
809 * memory that matches the given criteria.
810 * The criteria can be set in terms of a mask where dimm, rank, bank, page
811 * and col can be specified.
812 * A -1 value for any of the mask items will make the MCU to ignore
813 * that matching criteria for error injection.
815 * It should be noticed that the error will only happen after a write operation
816 * on a memory that matches the condition. if REPEAT_EN is not enabled at
817 * inject mask, then it will produce just one error. Otherwise, it will repeat
818 * until the injectmask would be cleaned.
820 * FIXME: This routine assumes that MAXNUMDIMMS value of MC_MAX_DOD
821 * is reliable enough to check if the MC is using the
822 * three channels. However, this is not clear at the datasheet.
824 static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci,
825 const char *data, size_t count)
827 struct i7core_pvt *pvt = mci->pvt_info;
833 if (!pvt->pci_ch[pvt->inject.channel][0])
836 rc = strict_strtoul(data, 10, &enable);
841 pvt->inject.enable = 1;
847 /* Sets pvt->inject.dimm mask */
848 if (pvt->inject.dimm < 0)
851 if (pvt->channel[pvt->inject.channel].dimms > 2)
852 mask |= (pvt->inject.dimm & 0x3L) << 35;
854 mask |= (pvt->inject.dimm & 0x1L) << 36;
857 /* Sets pvt->inject.rank mask */
858 if (pvt->inject.rank < 0)
861 if (pvt->channel[pvt->inject.channel].dimms > 2)
862 mask |= (pvt->inject.rank & 0x1L) << 34;
864 mask |= (pvt->inject.rank & 0x3L) << 34;
867 /* Sets pvt->inject.bank mask */
868 if (pvt->inject.bank < 0)
871 mask |= (pvt->inject.bank & 0x15L) << 30;
873 /* Sets pvt->inject.page mask */
874 if (pvt->inject.page < 0)
877 mask |= (pvt->inject.page & 0xffffL) << 14;
879 /* Sets pvt->inject.column mask */
880 if (pvt->inject.col < 0)
883 mask |= (pvt->inject.col & 0x3fffL);
886 pci_write_config_qword(pvt->pci_ch[pvt->inject.channel][0],
887 MC_CHANNEL_ADDR_MATCH, mask);
889 pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
890 MC_CHANNEL_ADDR_MATCH, mask);
891 pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
892 MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L);
898 pci_read_config_qword(pvt->pci_ch[pvt->inject.channel][0],
899 MC_CHANNEL_ADDR_MATCH, &rdmask);
900 debugf0("Inject addr match write 0x%016llx, read: 0x%016llx\n",
903 u32 rdmask1, rdmask2;
905 pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0],
906 MC_CHANNEL_ADDR_MATCH, &rdmask1);
907 pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0],
908 MC_CHANNEL_ADDR_MATCH + 4, &rdmask2);
910 debugf0("Inject addr match write 0x%016llx, read: 0x%08x 0x%08x\n",
911 mask, rdmask1, rdmask2);
915 pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
916 MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask);
920 * bits 1-2: MASK_HALF_CACHELINE
922 * bit 4: INJECT_ADDR_PARITY
925 injectmask = (pvt->inject.type & 1) |
926 (pvt->inject.section & 0x3) << 1 |
927 (pvt->inject.type & 0x6) << (3 - 1);
929 pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
930 MC_CHANNEL_ERROR_MASK, injectmask);
932 debugf0("Error inject addr match 0x%016llx, ecc 0x%08x,"
934 mask, pvt->inject.eccmask, injectmask);
941 static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci,
944 struct i7core_pvt *pvt = mci->pvt_info;
947 pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0],
948 MC_CHANNEL_ERROR_MASK, &injectmask);
950 debugf0("Inject error read: 0x%018x\n", injectmask);
952 if (injectmask & 0x0c)
953 pvt->inject.enable = 1;
955 return sprintf(data, "%d\n", pvt->inject.enable);
958 static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data)
960 struct i7core_pvt *pvt = mci->pvt_info;
962 if (!pvt->ce_count_available)
963 return sprintf(data, "unavailable\n");
965 return sprintf(data, "dimm0: %lu\ndimm1: %lu\ndimm2: %lu\n",
974 static struct mcidev_sysfs_attribute i7core_inj_attrs[] = {
978 .name = "inject_section",
979 .mode = (S_IRUGO | S_IWUSR)
981 .show = i7core_inject_section_show,
982 .store = i7core_inject_section_store,
985 .name = "inject_type",
986 .mode = (S_IRUGO | S_IWUSR)
988 .show = i7core_inject_type_show,
989 .store = i7core_inject_type_store,
992 .name = "inject_eccmask",
993 .mode = (S_IRUGO | S_IWUSR)
995 .show = i7core_inject_eccmask_show,
996 .store = i7core_inject_eccmask_store,
999 .name = "inject_addrmatch",
1000 .mode = (S_IRUGO | S_IWUSR)
1002 .show = i7core_inject_addrmatch_show,
1003 .store = i7core_inject_addrmatch_store,
1006 .name = "inject_enable",
1007 .mode = (S_IRUGO | S_IWUSR)
1009 .show = i7core_inject_enable_show,
1010 .store = i7core_inject_enable_store,
1013 .name = "corrected_error_counts",
1014 .mode = (S_IRUGO | S_IWUSR)
1016 .show = i7core_ce_regs_show,
1021 /****************************************************************************
1022 Device initialization routines: put/get, init/exit
1023 ****************************************************************************/
1026 * i7core_put_devices 'put' all the devices that we have
1027 * reserved via 'get'
1029 static void i7core_put_devices(void)
1033 for (i = 0; i < N_DEVS; i++)
1034 pci_dev_put(pci_devs[i].pdev);
1038 * i7core_get_devices Find and perform 'get' operation on the MCH's
1039 * device/functions we want to reference for this driver
1041 * Need to 'get' device 16 func 1 and func 2
1043 static int i7core_get_devices(void)
1046 struct pci_dev *pdev = NULL;
1048 for (i = 0; i < N_DEVS; i++) {
1049 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1050 pci_devs[i].dev_id, NULL);
1052 pci_devs[i].pdev = pdev;
1054 i7core_printk(KERN_ERR,
1055 "Device not found: PCI ID %04x:%04x "
1056 "(dev %d, func %d)\n",
1057 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
1058 pci_devs[i].dev, pci_devs[i].func);
1060 /* Dev 3 function 2 only exists on chips with RDIMMs */
1061 if ((pci_devs[i].dev == 3) && (pci_devs[i].func == 2))
1064 /* End of list, leave */
1070 if (unlikely(PCI_SLOT(pdev->devfn) != pci_devs[i].dev ||
1071 PCI_FUNC(pdev->devfn) != pci_devs[i].func)) {
1072 i7core_printk(KERN_ERR,
1073 "Device PCI ID %04x:%04x "
1074 "has fn %d.%d instead of fn %d.%d\n",
1075 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
1076 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
1077 pci_devs[i].dev, pci_devs[i].func);
1082 /* Be sure that the device is enabled */
1083 rc = pci_enable_device(pdev);
1084 if (unlikely(rc < 0)) {
1085 i7core_printk(KERN_ERR,
1086 "Couldn't enable PCI ID %04x:%04x "
1088 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
1089 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
1093 i7core_printk(KERN_INFO,
1094 "Registered device %0x:%0x fn %d.%d\n",
1095 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
1096 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
1102 i7core_put_devices();
1106 static int mci_bind_devs(struct mem_ctl_info *mci)
1108 struct i7core_pvt *pvt = mci->pvt_info;
1109 struct pci_dev *pdev;
1112 for (i = 0; i < N_DEVS; i++) {
1113 pdev = pci_devs[i].pdev;
1117 func = PCI_FUNC(pdev->devfn);
1118 slot = PCI_SLOT(pdev->devfn);
1120 if (unlikely(func > MAX_MCR_FUNC))
1122 pvt->pci_mcr[func] = pdev;
1123 } else if (likely(slot >= 4 && slot < 4 + NUM_CHANS)) {
1124 if (unlikely(func > MAX_CHAN_FUNC))
1126 pvt->pci_ch[slot - 4][func] = pdev;
1130 debugf0("Associated fn %d.%d, dev = %p\n",
1131 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev);
1136 i7core_printk(KERN_ERR, "Device %d, function %d "
1137 "is out of the expected range\n",
1142 /****************************************************************************
1143 Error check routines
1144 ****************************************************************************/
1146 /* This function is based on the device 3 function 4 registers as described on:
1147 * Intel Xeon Processor 5500 Series Datasheet Volume 2
1148 * http://www.intel.com/Assets/PDF/datasheet/321322.pdf
1149 * also available at:
1150 * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
1152 static void check_mc_test_err(struct mem_ctl_info *mci)
1154 struct i7core_pvt *pvt = mci->pvt_info;
1156 int new0, new1, new2;
1158 if (!pvt->pci_mcr[4]) {
1159 debugf0("%s MCR registers not found\n",__func__);
1163 /* Corrected error reads */
1164 pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV1, &rcv1);
1165 pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV0, &rcv0);
1167 /* Store the new values */
1168 new2 = DIMM2_COR_ERR(rcv1);
1169 new1 = DIMM1_COR_ERR(rcv0);
1170 new0 = DIMM0_COR_ERR(rcv0);
1173 debugf2("%s CE rcv1=0x%08x rcv0=0x%08x, %d %d %d\n",
1174 (pvt->ce_count_available ? "UPDATE" : "READ"),
1175 rcv1, rcv0, new0, new1, new2);
1178 /* Updates CE counters if it is not the first time here */
1179 if (pvt->ce_count_available) {
1180 /* Updates CE counters */
1181 int add0, add1, add2;
1183 add2 = new2 - pvt->last_ce_count[2];
1184 add1 = new1 - pvt->last_ce_count[1];
1185 add0 = new0 - pvt->last_ce_count[0];
1189 pvt->ce_count[2] += add2;
1193 pvt->ce_count[1] += add1;
1197 pvt->ce_count[0] += add0;
1199 pvt->ce_count_available = 1;
1201 /* Store the new values */
1202 pvt->last_ce_count[2] = new2;
1203 pvt->last_ce_count[1] = new1;
1204 pvt->last_ce_count[0] = new0;
1207 static void i7core_mce_output_error(struct mem_ctl_info *mci,
1210 debugf0("CPU %d: Machine Check Exception: %16Lx"
1211 "Bank %d: %016Lx\n",
1212 m->cpu, m->mcgstatus, m->bank, m->status);
1214 debugf0("RIP%s %02x:<%016Lx>\n",
1215 !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "",
1218 printk(KERN_EMERG "TSC %llx ", m->tsc);
1220 printk("ADDR %llx ", m->addr);
1222 printk("MISC %llx ", m->misc);
1225 snprintf(msg, sizeof(msg),
1226 "%s (Branch=%d DRAM-Bank=%d Buffer ID = %d RDWR=%s "
1227 "RAS=%d CAS=%d %s Err=0x%lx (%s))",
1228 type, branch >> 1, bank, buf_id, rdwr_str(rdwr), ras, cas,
1229 type, allErrors, error_name[errnum]);
1231 /* Call the helper to output message */
1232 edac_mc_handle_fbd_ue(mci, rank, channel, channel + 1, msg);
1237 * i7core_check_error Retrieve and process errors reported by the
1238 * hardware. Called by the Core module.
1240 static void i7core_check_error(struct mem_ctl_info *mci)
1242 struct i7core_pvt *pvt = mci->pvt_info;
1245 struct mce *m = NULL;
1246 unsigned long flags;
1248 debugf0(__FILE__ ": %s()\n", __func__);
1250 /* Copy all mce errors into a temporary buffer */
1251 spin_lock_irqsave(&pvt->mce_lock, flags);
1252 if (pvt->mce_count) {
1253 m = kmalloc(sizeof(*m) * pvt->mce_count, GFP_ATOMIC);
1255 count = pvt->mce_count;
1256 memcpy(m, &pvt->mce_entry, sizeof(*m) * count);
1260 spin_unlock_irqrestore(&pvt->mce_lock, flags);
1262 /* proccess mcelog errors */
1263 for (i = 0; i < count; i++)
1264 i7core_mce_output_error(mci, &m[i]);
1268 /* check memory count errors */
1269 check_mc_test_err(mci);
1273 * i7core_mce_check_error Replicates mcelog routine to get errors
1274 * This routine simply queues mcelog errors, and
1275 * return. The error itself should be handled later
1276 * by i7core_check_error.
1278 static int i7core_mce_check_error(void *priv, struct mce *mce)
1280 struct i7core_pvt *pvt = priv;
1281 unsigned long flags;
1283 debugf0(__FILE__ ": %s()\n", __func__);
1285 spin_lock_irqsave(&pvt->mce_lock, flags);
1286 if (pvt->mce_count < MCE_LOG_LEN) {
1287 memcpy(&pvt->mce_entry[pvt->mce_count], mce, sizeof(*mce));
1290 spin_unlock_irqrestore(&pvt->mce_lock, flags);
1292 /* Advice mcelog that the error were handled */
1294 return 0; // Let's duplicate the log
1298 * i7core_probe Probe for ONE instance of device to see if it is
1301 * 0 for FOUND a device
1302 * < 0 for error code
1304 static int __devinit i7core_probe(struct pci_dev *pdev,
1305 const struct pci_device_id *id)
1307 struct mem_ctl_info *mci;
1308 struct i7core_pvt *pvt;
1311 int dev_idx = id->driver_data;
1314 if (unlikely(dev_idx >= ARRAY_SIZE(i7core_devs)))
1317 /* get the pci devices we want to reserve for our use */
1318 rc = i7core_get_devices();
1319 if (unlikely(rc < 0))
1322 /* Check the number of active and not disabled channels */
1323 rc = i7core_get_active_channels(&num_channels, &num_csrows);
1324 if (unlikely(rc < 0))
1327 /* allocate a new MC control structure */
1328 mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0);
1329 if (unlikely(!mci)) {
1334 debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci);
1336 mci->dev = &pdev->dev; /* record ptr to the generic device */
1338 pvt = mci->pvt_info;
1339 memset(pvt, 0, sizeof(*pvt));
1343 * FIXME: how to handle RDDR3 at MCI level? It is possible to have
1344 * Mixed RDDR3/UDDR3 with Nehalem, provided that they are on different
1347 mci->mtype_cap = MEM_FLAG_DDR3;
1348 mci->edac_ctl_cap = EDAC_FLAG_NONE;
1349 mci->edac_cap = EDAC_FLAG_NONE;
1350 mci->mod_name = "i7core_edac.c";
1351 mci->mod_ver = I7CORE_REVISION;
1352 mci->ctl_name = i7core_devs[dev_idx].ctl_name;
1353 mci->dev_name = pci_name(pdev);
1354 mci->ctl_page_to_phys = NULL;
1355 mci->mc_driver_sysfs_attributes = i7core_inj_attrs;
1356 /* Set the function pointer to an actual operation function */
1357 mci->edac_check = i7core_check_error;
1359 /* Store pci devices at mci for faster access */
1360 rc = mci_bind_devs(mci);
1361 if (unlikely(rc < 0))
1364 /* Get dimm basic config */
1365 get_dimm_config(mci);
1367 /* add this new MC control structure to EDAC's list of MCs */
1368 if (unlikely(edac_mc_add_mc(mci))) {
1369 debugf0("MC: " __FILE__
1370 ": %s(): failed edac_mc_add_mc()\n", __func__);
1371 /* FIXME: perhaps some code should go here that disables error
1372 * reporting if we just enabled it
1379 /* allocating generic PCI control info */
1380 i7core_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
1381 if (unlikely(!i7core_pci)) {
1383 "%s(): Unable to create PCI control\n",
1386 "%s(): PCI error report via EDAC not setup\n",
1390 /* Default error mask is any memory */
1391 pvt->inject.channel = 0;
1392 pvt->inject.dimm = -1;
1393 pvt->inject.rank = -1;
1394 pvt->inject.bank = -1;
1395 pvt->inject.page = -1;
1396 pvt->inject.col = -1;
1398 /* Registers on edac_mce in order to receive memory errors */
1399 pvt->edac_mce.priv = pvt;
1400 pvt->edac_mce.check_error = i7core_mce_check_error;
1401 spin_lock_init(&pvt->mce_lock);
1403 rc = edac_mce_register(&pvt->edac_mce);
1404 if (unlikely (rc < 0)) {
1405 debugf0("MC: " __FILE__
1406 ": %s(): failed edac_mce_register()\n", __func__);
1410 i7core_printk(KERN_INFO, "Driver loaded.\n");
1418 i7core_put_devices();
1423 * i7core_remove destructor for one instance of device
1426 static void __devexit i7core_remove(struct pci_dev *pdev)
1428 struct mem_ctl_info *mci;
1429 struct i7core_pvt *pvt;
1431 debugf0(__FILE__ ": %s()\n", __func__);
1434 edac_pci_release_generic_ctl(i7core_pci);
1437 mci = edac_mc_del_mc(&pdev->dev);
1441 /* Unregisters on edac_mce in order to receive memory errors */
1442 pvt = mci->pvt_info;
1443 edac_mce_unregister(&pvt->edac_mce);
1445 /* retrieve references to resources, and free those resources */
1446 i7core_put_devices();
1451 MODULE_DEVICE_TABLE(pci, i7core_pci_tbl);
1454 * i7core_driver pci_driver structure for this module
1457 static struct pci_driver i7core_driver = {
1458 .name = "i7core_edac",
1459 .probe = i7core_probe,
1460 .remove = __devexit_p(i7core_remove),
1461 .id_table = i7core_pci_tbl,
1465 * i7core_init Module entry function
1466 * Try to initialize this module for its devices
1468 static int __init i7core_init(void)
1472 debugf2("MC: " __FILE__ ": %s()\n", __func__);
1474 /* Ensure that the OPSTATE is set correctly for POLL or NMI */
1477 pci_rc = pci_register_driver(&i7core_driver);
1479 return (pci_rc < 0) ? pci_rc : 0;
1483 * i7core_exit() Module exit function
1484 * Unregister the driver
1486 static void __exit i7core_exit(void)
1488 debugf2("MC: " __FILE__ ": %s()\n", __func__);
1489 pci_unregister_driver(&i7core_driver);
1492 module_init(i7core_init);
1493 module_exit(i7core_exit);
1495 MODULE_LICENSE("GPL");
1496 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
1497 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
1498 MODULE_DESCRIPTION("MC Driver for Intel i7 Core memory controllers - "
1501 module_param(edac_op_state, int, 0444);
1502 MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");