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 0 Function 0 */
63 #define MC_CFG_CONTROL 0x90
65 /* OFFSETS for Device 3 Function 0 */
67 #define MC_CONTROL 0x48
68 #define MC_STATUS 0x4c
69 #define MC_MAX_DOD 0x64
72 * OFFSETS for Device 3 Function 4, as inicated on Xeon 5500 datasheet:
73 * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
76 #define MC_TEST_ERR_RCV1 0x60
77 #define DIMM2_COR_ERR(r) ((r) & 0x7fff)
79 #define MC_TEST_ERR_RCV0 0x64
80 #define DIMM1_COR_ERR(r) (((r) >> 16) & 0x7fff)
81 #define DIMM0_COR_ERR(r) ((r) & 0x7fff)
83 /* OFFSETS for Devices 4,5 and 6 Function 0 */
85 #define MC_CHANNEL_DIMM_INIT_PARAMS 0x58
86 #define THREE_DIMMS_PRESENT (1 << 24)
87 #define SINGLE_QUAD_RANK_PRESENT (1 << 23)
88 #define QUAD_RANK_PRESENT (1 << 22)
89 #define REGISTERED_DIMM (1 << 15)
91 #define MC_CHANNEL_MAPPER 0x60
92 #define RDLCH(r, ch) ((((r) >> (3 + (ch * 6))) & 0x07) - 1)
93 #define WRLCH(r, ch) ((((r) >> (ch * 6)) & 0x07) - 1)
95 #define MC_CHANNEL_RANK_PRESENT 0x7c
96 #define RANK_PRESENT_MASK 0xffff
98 #define MC_CHANNEL_ADDR_MATCH 0xf0
99 #define MC_CHANNEL_ERROR_MASK 0xf8
100 #define MC_CHANNEL_ERROR_INJECT 0xfc
101 #define INJECT_ADDR_PARITY 0x10
102 #define INJECT_ECC 0x08
103 #define MASK_CACHELINE 0x06
104 #define MASK_FULL_CACHELINE 0x06
105 #define MASK_MSB32_CACHELINE 0x04
106 #define MASK_LSB32_CACHELINE 0x02
107 #define NO_MASK_CACHELINE 0x00
108 #define REPEAT_EN 0x01
110 /* OFFSETS for Devices 4,5 and 6 Function 1 */
111 #define MC_DOD_CH_DIMM0 0x48
112 #define MC_DOD_CH_DIMM1 0x4c
113 #define MC_DOD_CH_DIMM2 0x50
114 #define RANKOFFSET_MASK ((1 << 12) | (1 << 11) | (1 << 10))
115 #define RANKOFFSET(x) ((x & RANKOFFSET_MASK) >> 10)
116 #define DIMM_PRESENT_MASK (1 << 9)
117 #define DIMM_PRESENT(x) (((x) & DIMM_PRESENT_MASK) >> 9)
118 #define MC_DOD_NUMBANK_MASK ((1 << 8) | (1 << 7))
119 #define MC_DOD_NUMBANK(x) (((x) & MC_DOD_NUMBANK_MASK) >> 7)
120 #define MC_DOD_NUMRANK_MASK ((1 << 6) | (1 << 5))
121 #define MC_DOD_NUMRANK(x) (((x) & MC_DOD_NUMRANK_MASK) >> 5)
122 #define MC_DOD_NUMROW_MASK ((1 << 4) | (1 << 3) | (1 << 2))
123 #define MC_DOD_NUMROW(x) (((x) & MC_DOD_NUMROW_MASK) >> 2)
124 #define MC_DOD_NUMCOL_MASK 3
125 #define MC_DOD_NUMCOL(x) ((x) & MC_DOD_NUMCOL_MASK)
127 #define MC_RANK_PRESENT 0x7c
129 #define MC_SAG_CH_0 0x80
130 #define MC_SAG_CH_1 0x84
131 #define MC_SAG_CH_2 0x88
132 #define MC_SAG_CH_3 0x8c
133 #define MC_SAG_CH_4 0x90
134 #define MC_SAG_CH_5 0x94
135 #define MC_SAG_CH_6 0x98
136 #define MC_SAG_CH_7 0x9c
138 #define MC_RIR_LIMIT_CH_0 0x40
139 #define MC_RIR_LIMIT_CH_1 0x44
140 #define MC_RIR_LIMIT_CH_2 0x48
141 #define MC_RIR_LIMIT_CH_3 0x4C
142 #define MC_RIR_LIMIT_CH_4 0x50
143 #define MC_RIR_LIMIT_CH_5 0x54
144 #define MC_RIR_LIMIT_CH_6 0x58
145 #define MC_RIR_LIMIT_CH_7 0x5C
146 #define MC_RIR_LIMIT_MASK ((1 << 10) - 1)
148 #define MC_RIR_WAY_CH 0x80
149 #define MC_RIR_WAY_OFFSET_MASK (((1 << 14) - 1) & ~0x7)
150 #define MC_RIR_WAY_RANK_MASK 0x7
157 #define MAX_DIMMS 3 /* Max DIMMS per channel */
158 #define NUM_SOCKETS 2 /* Max number of MC sockets */
159 #define MAX_MCR_FUNC 4
160 #define MAX_CHAN_FUNC 3
170 struct i7core_inject {
178 /* Error address mask */
179 int channel, dimm, rank, bank, page, col;
182 struct i7core_channel {
187 struct pci_id_descr {
191 struct pci_dev *pdev[NUM_SOCKETS];
195 struct pci_dev *pci_noncore[NUM_SOCKETS];
196 struct pci_dev *pci_mcr[NUM_SOCKETS][MAX_MCR_FUNC + 1];
197 struct pci_dev *pci_ch[NUM_SOCKETS][NUM_CHANS][MAX_CHAN_FUNC + 1];
199 struct i7core_info info;
200 struct i7core_inject inject;
201 struct i7core_channel channel[NUM_SOCKETS][NUM_CHANS];
203 int sockets; /* Number of sockets */
204 int channels; /* Number of active channels */
206 int ce_count_available[NUM_SOCKETS];
207 /* ECC corrected errors counts per dimm */
208 unsigned long ce_count[NUM_SOCKETS][MAX_DIMMS];
209 int last_ce_count[NUM_SOCKETS][MAX_DIMMS];
212 struct edac_mce edac_mce;
213 struct mce mce_entry[MCE_LOG_LEN];
218 /* Device name and register DID (Device ID) */
219 struct i7core_dev_info {
220 const char *ctl_name; /* name for this device */
221 u16 fsb_mapping_errors; /* DID for the branchmap,control */
224 #define PCI_DESCR(device, function, device_id) \
226 .func = (function), \
227 .dev_id = (device_id)
229 struct pci_id_descr pci_devs[] = {
230 /* Memory controller */
231 { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) },
232 { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) },
233 { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS) }, /* if RDIMM is supported */
234 { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) },
237 { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL) },
238 { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH0_ADDR) },
239 { PCI_DESCR(4, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH0_RANK) },
240 { PCI_DESCR(4, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH0_TC) },
243 { PCI_DESCR(5, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH1_CTRL) },
244 { PCI_DESCR(5, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH1_ADDR) },
245 { PCI_DESCR(5, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH1_RANK) },
246 { PCI_DESCR(5, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH1_TC) },
249 { PCI_DESCR(6, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH2_CTRL) },
250 { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR) },
251 { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK) },
252 { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC) },
254 /* Generic Non-core registers */
256 * This is the PCI device on i7core and on Xeon 35xx (8086:2c41)
257 * On Xeon 55xx, however, it has a different id (8086:2c40). So,
258 * the probing code needs to test for the other address in case of
259 * failure of this one
261 { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NOCORE) },
264 #define N_DEVS ARRAY_SIZE(pci_devs)
267 * pci_device_id table for which devices we are looking for
268 * This should match the first device at pci_devs table
270 static const struct pci_device_id i7core_pci_tbl[] __devinitdata = {
271 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_X58_HUB_MGMT)},
272 {0,} /* 0 terminated list. */
276 /* Table of devices attributes supported by this driver */
277 static const struct i7core_dev_info i7core_devs[] = {
279 .ctl_name = "i7 Core",
280 .fsb_mapping_errors = PCI_DEVICE_ID_INTEL_I7_MCR,
284 static struct edac_pci_ctl_info *i7core_pci;
286 /****************************************************************************
287 Anciliary status routines
288 ****************************************************************************/
290 /* MC_CONTROL bits */
291 #define CH_ACTIVE(pvt, ch) ((pvt)->info.mc_control & (1 << (8 + ch)))
292 #define ECCx8(pvt) ((pvt)->info.mc_control & (1 << 1))
295 #define ECC_ENABLED(pvt) ((pvt)->info.mc_status & (1 << 3))
296 #define CH_DISABLED(pvt, ch) ((pvt)->info.mc_status & (1 << ch))
298 /* MC_MAX_DOD read functions */
299 static inline int numdimms(u32 dimms)
301 return (dimms & 0x3) + 1;
304 static inline int numrank(u32 rank)
306 static int ranks[4] = { 1, 2, 4, -EINVAL };
308 return ranks[rank & 0x3];
311 static inline int numbank(u32 bank)
313 static int banks[4] = { 4, 8, 16, -EINVAL };
315 return banks[bank & 0x3];
318 static inline int numrow(u32 row)
320 static int rows[8] = {
321 1 << 12, 1 << 13, 1 << 14, 1 << 15,
322 1 << 16, -EINVAL, -EINVAL, -EINVAL,
325 return rows[row & 0x7];
328 static inline int numcol(u32 col)
330 static int cols[8] = {
331 1 << 10, 1 << 11, 1 << 12, -EINVAL,
333 return cols[col & 0x3];
336 /****************************************************************************
337 Memory check routines
338 ****************************************************************************/
339 static struct pci_dev *get_pdev_slot_func(u8 socket, unsigned slot,
344 for (i = 0; i < N_DEVS; i++) {
345 if (!pci_devs[i].pdev[socket])
348 if (PCI_SLOT(pci_devs[i].pdev[socket]->devfn) == slot &&
349 PCI_FUNC(pci_devs[i].pdev[socket]->devfn) == func) {
350 return pci_devs[i].pdev[socket];
358 * i7core_get_active_channels() - gets the number of channels and csrows
359 * @socket: Quick Path Interconnect socket
360 * @channels: Number of channels that will be returned
361 * @csrows: Number of csrows found
363 * Since EDAC core needs to know in advance the number of available channels
364 * and csrows, in order to allocate memory for csrows/channels, it is needed
365 * to run two similar steps. At the first step, implemented on this function,
366 * it checks the number of csrows/channels present at one socket.
367 * this is used in order to properly allocate the size of mci components.
369 * It should be noticed that none of the current available datasheets explain
370 * or even mention how csrows are seen by the memory controller. So, we need
371 * to add a fake description for csrows.
372 * So, this driver is attributing one DIMM memory for one csrow.
374 static int i7core_get_active_channels(u8 socket, unsigned *channels,
377 struct pci_dev *pdev = NULL;
384 pdev = get_pdev_slot_func(socket, 3, 0);
386 i7core_printk(KERN_ERR, "Couldn't find socket %d fn 3.0!!!\n",
391 /* Device 3 function 0 reads */
392 pci_read_config_dword(pdev, MC_STATUS, &status);
393 pci_read_config_dword(pdev, MC_CONTROL, &control);
395 for (i = 0; i < NUM_CHANS; i++) {
397 /* Check if the channel is active */
398 if (!(control & (1 << (8 + i))))
401 /* Check if the channel is disabled */
402 if (status & (1 << i))
405 pdev = get_pdev_slot_func(socket, i + 4, 1);
407 i7core_printk(KERN_ERR, "Couldn't find socket %d "
412 /* Devices 4-6 function 1 */
413 pci_read_config_dword(pdev,
414 MC_DOD_CH_DIMM0, &dimm_dod[0]);
415 pci_read_config_dword(pdev,
416 MC_DOD_CH_DIMM1, &dimm_dod[1]);
417 pci_read_config_dword(pdev,
418 MC_DOD_CH_DIMM2, &dimm_dod[2]);
422 for (j = 0; j < 3; j++) {
423 if (!DIMM_PRESENT(dimm_dod[j]))
429 debugf0("Number of active channels on socket %d: %d\n",
435 static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket)
437 struct i7core_pvt *pvt = mci->pvt_info;
438 struct csrow_info *csr;
439 struct pci_dev *pdev;
441 unsigned long last_page = 0;
445 /* Get data from the MC register, function 0 */
446 pdev = pvt->pci_mcr[socket][0];
450 /* Device 3 function 0 reads */
451 pci_read_config_dword(pdev, MC_CONTROL, &pvt->info.mc_control);
452 pci_read_config_dword(pdev, MC_STATUS, &pvt->info.mc_status);
453 pci_read_config_dword(pdev, MC_MAX_DOD, &pvt->info.max_dod);
454 pci_read_config_dword(pdev, MC_CHANNEL_MAPPER, &pvt->info.ch_map);
456 debugf0("QPI %d control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n",
457 socket, pvt->info.mc_control, pvt->info.mc_status,
458 pvt->info.max_dod, pvt->info.ch_map);
460 if (ECC_ENABLED(pvt)) {
461 debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt) ? 8 : 4);
463 mode = EDAC_S8ECD8ED;
465 mode = EDAC_S4ECD4ED;
467 debugf0("ECC disabled\n");
471 /* FIXME: need to handle the error codes */
472 debugf0("DOD Max limits: DIMMS: %d, %d-ranked, %d-banked "
474 numdimms(pvt->info.max_dod),
475 numrank(pvt->info.max_dod >> 2),
476 numbank(pvt->info.max_dod >> 4));
477 numrow(pvt->info.max_dod >> 6),
478 numcol(pvt->info.max_dod >> 9));
480 for (i = 0; i < NUM_CHANS; i++) {
481 u32 data, dimm_dod[3], value[8];
483 if (!CH_ACTIVE(pvt, i)) {
484 debugf0("Channel %i is not active\n", i);
487 if (CH_DISABLED(pvt, i)) {
488 debugf0("Channel %i is disabled\n", i);
492 /* Devices 4-6 function 0 */
493 pci_read_config_dword(pvt->pci_ch[socket][i][0],
494 MC_CHANNEL_DIMM_INIT_PARAMS, &data);
496 pvt->channel[socket][i].ranks = (data & QUAD_RANK_PRESENT) ?
499 if (data & REGISTERED_DIMM)
504 if (data & THREE_DIMMS_PRESENT)
505 pvt->channel[i].dimms = 3;
506 else if (data & SINGLE_QUAD_RANK_PRESENT)
507 pvt->channel[i].dimms = 1;
509 pvt->channel[i].dimms = 2;
512 /* Devices 4-6 function 1 */
513 pci_read_config_dword(pvt->pci_ch[socket][i][1],
514 MC_DOD_CH_DIMM0, &dimm_dod[0]);
515 pci_read_config_dword(pvt->pci_ch[socket][i][1],
516 MC_DOD_CH_DIMM1, &dimm_dod[1]);
517 pci_read_config_dword(pvt->pci_ch[socket][i][1],
518 MC_DOD_CH_DIMM2, &dimm_dod[2]);
520 debugf0("Ch%d phy rd%d, wr%d (0x%08x): "
521 "%d ranks, %cDIMMs\n",
523 RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i),
525 pvt->channel[socket][i].ranks,
526 (data & REGISTERED_DIMM) ? 'R' : 'U');
528 for (j = 0; j < 3; j++) {
529 u32 banks, ranks, rows, cols;
532 if (!DIMM_PRESENT(dimm_dod[j]))
535 banks = numbank(MC_DOD_NUMBANK(dimm_dod[j]));
536 ranks = numrank(MC_DOD_NUMRANK(dimm_dod[j]));
537 rows = numrow(MC_DOD_NUMROW(dimm_dod[j]));
538 cols = numcol(MC_DOD_NUMCOL(dimm_dod[j]));
540 /* DDR3 has 8 I/O banks */
541 size = (rows * cols * banks * ranks) >> (20 - 3);
543 pvt->channel[socket][i].dimms++;
545 debugf0("\tdimm %d %d Mb offset: %x, "
546 "bank: %d, rank: %d, row: %#x, col: %#x\n",
548 RANKOFFSET(dimm_dod[j]),
549 banks, ranks, rows, cols);
552 npages = size >> (PAGE_SHIFT - 20);
554 npages = size << (20 - PAGE_SHIFT);
557 csr = &mci->csrows[*csrow];
558 csr->first_page = last_page + 1;
560 csr->last_page = last_page;
561 csr->nr_pages = npages;
565 csr->csrow_idx = *csrow;
566 csr->nr_channels = 1;
568 csr->channels[0].chan_idx = i;
569 csr->channels[0].ce_count = 0;
579 csr->dtype = DEV_X16;
582 csr->dtype = DEV_UNKNOWN;
585 csr->edac_mode = mode;
591 pci_read_config_dword(pdev, MC_SAG_CH_0, &value[0]);
592 pci_read_config_dword(pdev, MC_SAG_CH_1, &value[1]);
593 pci_read_config_dword(pdev, MC_SAG_CH_2, &value[2]);
594 pci_read_config_dword(pdev, MC_SAG_CH_3, &value[3]);
595 pci_read_config_dword(pdev, MC_SAG_CH_4, &value[4]);
596 pci_read_config_dword(pdev, MC_SAG_CH_5, &value[5]);
597 pci_read_config_dword(pdev, MC_SAG_CH_6, &value[6]);
598 pci_read_config_dword(pdev, MC_SAG_CH_7, &value[7]);
599 debugf1("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i);
600 for (j = 0; j < 8; j++)
601 debugf1("\t\t%#x\t%#x\t%#x\n",
602 (value[j] >> 27) & 0x1,
603 (value[j] >> 24) & 0x7,
604 (value[j] && ((1 << 24) - 1)));
610 /****************************************************************************
611 Error insertion routines
612 ****************************************************************************/
614 /* The i7core has independent error injection features per channel.
615 However, to have a simpler code, we don't allow enabling error injection
616 on more than one channel.
617 Also, since a change at an inject parameter will be applied only at enable,
618 we're disabling error injection on all write calls to the sysfs nodes that
619 controls the error code injection.
621 static int disable_inject(struct mem_ctl_info *mci)
623 struct i7core_pvt *pvt = mci->pvt_info;
625 pvt->inject.enable = 0;
627 if (!pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0])
630 pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
631 MC_CHANNEL_ERROR_MASK, 0);
637 * i7core inject inject.socket
639 * accept and store error injection inject.socket value
641 static ssize_t i7core_inject_socket_store(struct mem_ctl_info *mci,
642 const char *data, size_t count)
644 struct i7core_pvt *pvt = mci->pvt_info;
648 rc = strict_strtoul(data, 10, &value);
649 if ((rc < 0) || (value > pvt->sockets))
652 pvt->inject.section = (u32) value;
656 static ssize_t i7core_inject_socket_show(struct mem_ctl_info *mci,
659 struct i7core_pvt *pvt = mci->pvt_info;
660 return sprintf(data, "%d\n", pvt->inject.socket);
664 * i7core inject inject.section
666 * accept and store error injection inject.section value
667 * bit 0 - refers to the lower 32-byte half cacheline
668 * bit 1 - refers to the upper 32-byte half cacheline
670 static ssize_t i7core_inject_section_store(struct mem_ctl_info *mci,
671 const char *data, size_t count)
673 struct i7core_pvt *pvt = mci->pvt_info;
677 if (pvt->inject.enable)
680 rc = strict_strtoul(data, 10, &value);
681 if ((rc < 0) || (value > 3))
684 pvt->inject.section = (u32) value;
688 static ssize_t i7core_inject_section_show(struct mem_ctl_info *mci,
691 struct i7core_pvt *pvt = mci->pvt_info;
692 return sprintf(data, "0x%08x\n", pvt->inject.section);
698 * accept and store error injection inject.section value
699 * bit 0 - repeat enable - Enable error repetition
700 * bit 1 - inject ECC error
701 * bit 2 - inject parity error
703 static ssize_t i7core_inject_type_store(struct mem_ctl_info *mci,
704 const char *data, size_t count)
706 struct i7core_pvt *pvt = mci->pvt_info;
710 if (pvt->inject.enable)
713 rc = strict_strtoul(data, 10, &value);
714 if ((rc < 0) || (value > 7))
717 pvt->inject.type = (u32) value;
721 static ssize_t i7core_inject_type_show(struct mem_ctl_info *mci,
724 struct i7core_pvt *pvt = mci->pvt_info;
725 return sprintf(data, "0x%08x\n", pvt->inject.type);
729 * i7core_inject_inject.eccmask_store
731 * The type of error (UE/CE) will depend on the inject.eccmask value:
732 * Any bits set to a 1 will flip the corresponding ECC bit
733 * Correctable errors can be injected by flipping 1 bit or the bits within
734 * a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or
735 * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an
736 * uncorrectable error to be injected.
738 static ssize_t i7core_inject_eccmask_store(struct mem_ctl_info *mci,
739 const char *data, size_t count)
741 struct i7core_pvt *pvt = mci->pvt_info;
745 if (pvt->inject.enable)
748 rc = strict_strtoul(data, 10, &value);
752 pvt->inject.eccmask = (u32) value;
756 static ssize_t i7core_inject_eccmask_show(struct mem_ctl_info *mci,
759 struct i7core_pvt *pvt = mci->pvt_info;
760 return sprintf(data, "0x%08x\n", pvt->inject.eccmask);
766 * The type of error (UE/CE) will depend on the inject.eccmask value:
767 * Any bits set to a 1 will flip the corresponding ECC bit
768 * Correctable errors can be injected by flipping 1 bit or the bits within
769 * a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or
770 * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an
771 * uncorrectable error to be injected.
773 static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci,
774 const char *data, size_t count)
776 struct i7core_pvt *pvt = mci->pvt_info;
781 if (pvt->inject.enable)
785 cmd = strsep((char **) &data, ":");
788 val = strsep((char **) &data, " \n\t");
792 if (!strcasecmp(val, "any"))
795 rc = strict_strtol(val, 10, &value);
796 if ((rc < 0) || (value < 0))
800 if (!strcasecmp(cmd, "channel")) {
802 pvt->inject.channel = value;
805 } else if (!strcasecmp(cmd, "dimm")) {
807 pvt->inject.dimm = value;
810 } else if (!strcasecmp(cmd, "rank")) {
812 pvt->inject.rank = value;
815 } else if (!strcasecmp(cmd, "bank")) {
817 pvt->inject.bank = value;
820 } else if (!strcasecmp(cmd, "page")) {
822 pvt->inject.page = value;
825 } else if (!strcasecmp(cmd, "col") ||
826 !strcasecmp(cmd, "column")) {
828 pvt->inject.col = value;
837 static ssize_t i7core_inject_addrmatch_show(struct mem_ctl_info *mci,
840 struct i7core_pvt *pvt = mci->pvt_info;
841 char channel[4], dimm[4], bank[4], rank[4], page[7], col[7];
843 if (pvt->inject.channel < 0)
844 sprintf(channel, "any");
846 sprintf(channel, "%d", pvt->inject.channel);
847 if (pvt->inject.dimm < 0)
848 sprintf(dimm, "any");
850 sprintf(dimm, "%d", pvt->inject.dimm);
851 if (pvt->inject.bank < 0)
852 sprintf(bank, "any");
854 sprintf(bank, "%d", pvt->inject.bank);
855 if (pvt->inject.rank < 0)
856 sprintf(rank, "any");
858 sprintf(rank, "%d", pvt->inject.rank);
859 if (pvt->inject.page < 0)
860 sprintf(page, "any");
862 sprintf(page, "0x%04x", pvt->inject.page);
863 if (pvt->inject.col < 0)
866 sprintf(col, "0x%04x", pvt->inject.col);
868 return sprintf(data, "channel: %s\ndimm: %s\nbank: %s\n"
869 "rank: %s\npage: %s\ncolumn: %s\n",
870 channel, dimm, bank, rank, page, col);
874 * This routine prepares the Memory Controller for error injection.
875 * The error will be injected when some process tries to write to the
876 * memory that matches the given criteria.
877 * The criteria can be set in terms of a mask where dimm, rank, bank, page
878 * and col can be specified.
879 * A -1 value for any of the mask items will make the MCU to ignore
880 * that matching criteria for error injection.
882 * It should be noticed that the error will only happen after a write operation
883 * on a memory that matches the condition. if REPEAT_EN is not enabled at
884 * inject mask, then it will produce just one error. Otherwise, it will repeat
885 * until the injectmask would be cleaned.
887 * FIXME: This routine assumes that MAXNUMDIMMS value of MC_MAX_DOD
888 * is reliable enough to check if the MC is using the
889 * three channels. However, this is not clear at the datasheet.
891 static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci,
892 const char *data, size_t count)
894 struct i7core_pvt *pvt = mci->pvt_info;
900 if (!pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0])
903 rc = strict_strtoul(data, 10, &enable);
908 pvt->inject.enable = 1;
914 /* Sets pvt->inject.dimm mask */
915 if (pvt->inject.dimm < 0)
918 if (pvt->channel[pvt->inject.socket][pvt->inject.channel].dimms > 2)
919 mask |= (pvt->inject.dimm & 0x3L) << 35;
921 mask |= (pvt->inject.dimm & 0x1L) << 36;
924 /* Sets pvt->inject.rank mask */
925 if (pvt->inject.rank < 0)
928 if (pvt->channel[pvt->inject.socket][pvt->inject.channel].dimms > 2)
929 mask |= (pvt->inject.rank & 0x1L) << 34;
931 mask |= (pvt->inject.rank & 0x3L) << 34;
934 /* Sets pvt->inject.bank mask */
935 if (pvt->inject.bank < 0)
938 mask |= (pvt->inject.bank & 0x15L) << 30;
940 /* Sets pvt->inject.page mask */
941 if (pvt->inject.page < 0)
944 mask |= (pvt->inject.page & 0xffffL) << 14;
946 /* Sets pvt->inject.column mask */
947 if (pvt->inject.col < 0)
950 mask |= (pvt->inject.col & 0x3fffL);
952 /* Unlock writes to registers */
953 pci_write_config_dword(pvt->pci_noncore[pvt->inject.socket],
954 MC_CFG_CONTROL, 0x2);
957 /* Zeroes error count registers */
958 pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4],
959 MC_TEST_ERR_RCV1, 0);
960 pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4],
961 MC_TEST_ERR_RCV0, 0);
962 pvt->ce_count_available[pvt->inject.socket] = 0;
966 pci_write_config_qword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
967 MC_CHANNEL_ADDR_MATCH, mask);
969 pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
970 MC_CHANNEL_ADDR_MATCH, mask);
971 pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
972 MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L);
978 pci_read_config_qword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
979 MC_CHANNEL_ADDR_MATCH, &rdmask);
980 debugf0("Inject addr match write 0x%016llx, read: 0x%016llx\n",
983 u32 rdmask1, rdmask2;
985 pci_read_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
986 MC_CHANNEL_ADDR_MATCH, &rdmask1);
987 pci_read_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
988 MC_CHANNEL_ADDR_MATCH + 4, &rdmask2);
990 debugf0("Inject addr match write 0x%016llx, read: 0x%08x 0x%08x\n",
991 mask, rdmask1, rdmask2);
995 pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
996 MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask);
1000 * bits 1-2: MASK_HALF_CACHELINE
1002 * bit 4: INJECT_ADDR_PARITY
1005 injectmask = (pvt->inject.type & 1) |
1006 (pvt->inject.section & 0x3) << 1 |
1007 (pvt->inject.type & 0x6) << (3 - 1);
1009 pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
1010 MC_CHANNEL_ERROR_MASK, injectmask);
1013 /* lock writes to registers */
1014 pci_write_config_dword(pvt->pci_noncore, MC_CFG_CONTROL, 0);
1016 debugf0("Error inject addr match 0x%016llx, ecc 0x%08x,"
1018 mask, pvt->inject.eccmask, injectmask);
1024 static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci,
1027 struct i7core_pvt *pvt = mci->pvt_info;
1030 pci_read_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
1031 MC_CHANNEL_ERROR_MASK, &injectmask);
1033 debugf0("Inject error read: 0x%018x\n", injectmask);
1035 if (injectmask & 0x0c)
1036 pvt->inject.enable = 1;
1038 return sprintf(data, "%d\n", pvt->inject.enable);
1041 static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data)
1043 unsigned i, count, total = 0;
1044 struct i7core_pvt *pvt = mci->pvt_info;
1046 for (i = 0; i < pvt->sockets; i++) {
1047 if (!pvt->ce_count_available[i])
1048 count = sprintf(data, "socket 0 data unavailable\n");
1050 count = sprintf(data, "socket %d, dimm0: %lu\n"
1051 "dimm1: %lu\ndimm2: %lu\n",
1053 pvt->ce_count[i][0],
1054 pvt->ce_count[i][1],
1055 pvt->ce_count[i][2]);
1066 static struct mcidev_sysfs_attribute i7core_inj_attrs[] = {
1069 .name = "inject_socket",
1070 .mode = (S_IRUGO | S_IWUSR)
1072 .show = i7core_inject_socket_show,
1073 .store = i7core_inject_socket_store,
1076 .name = "inject_section",
1077 .mode = (S_IRUGO | S_IWUSR)
1079 .show = i7core_inject_section_show,
1080 .store = i7core_inject_section_store,
1083 .name = "inject_type",
1084 .mode = (S_IRUGO | S_IWUSR)
1086 .show = i7core_inject_type_show,
1087 .store = i7core_inject_type_store,
1090 .name = "inject_eccmask",
1091 .mode = (S_IRUGO | S_IWUSR)
1093 .show = i7core_inject_eccmask_show,
1094 .store = i7core_inject_eccmask_store,
1097 .name = "inject_addrmatch",
1098 .mode = (S_IRUGO | S_IWUSR)
1100 .show = i7core_inject_addrmatch_show,
1101 .store = i7core_inject_addrmatch_store,
1104 .name = "inject_enable",
1105 .mode = (S_IRUGO | S_IWUSR)
1107 .show = i7core_inject_enable_show,
1108 .store = i7core_inject_enable_store,
1111 .name = "corrected_error_counts",
1112 .mode = (S_IRUGO | S_IWUSR)
1114 .show = i7core_ce_regs_show,
1119 /****************************************************************************
1120 Device initialization routines: put/get, init/exit
1121 ****************************************************************************/
1124 * i7core_put_devices 'put' all the devices that we have
1125 * reserved via 'get'
1127 static void i7core_put_devices(void)
1131 for (i = 0; i < NUM_SOCKETS; i++)
1132 for (j = 0; j < N_DEVS; j++)
1133 pci_dev_put(pci_devs[j].pdev[i]);
1137 * i7core_get_devices Find and perform 'get' operation on the MCH's
1138 * device/functions we want to reference for this driver
1140 * Need to 'get' device 16 func 1 and func 2
1142 int i7core_get_onedevice(struct pci_dev **prev, int devno)
1144 struct pci_dev *pdev = NULL;
1148 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1149 pci_devs[devno].dev_id, *prev);
1152 * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core pci buses
1153 * aren't announced by acpi. So, we need to use a legacy scan probing
1156 if (unlikely(!pdev && !devno && !prev)) {
1157 pcibios_scan_specific_bus(254);
1158 pcibios_scan_specific_bus(255);
1160 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1161 pci_devs[devno].dev_id, *prev);
1165 * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs
1166 * is at addr 8086:2c40, instead of 8086:2c41. So, we need
1167 * to probe for the alternate address in case of failure
1169 if (pci_devs[devno].dev_id == PCI_DEVICE_ID_INTEL_I7_NOCORE && !pdev)
1170 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1171 PCI_DEVICE_ID_INTEL_I7_NOCORE_ALT, *prev);
1180 * Dev 3 function 2 only exists on chips with RDIMMs
1181 * so, it is ok to not found it
1183 if ((pci_devs[devno].dev == 3) && (pci_devs[devno].func == 2)) {
1188 i7core_printk(KERN_ERR,
1189 "Device not found: dev %02x.%d PCI ID %04x:%04x\n",
1190 pci_devs[devno].dev, pci_devs[devno].func,
1191 PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id);
1193 /* End of list, leave */
1196 bus = pdev->bus->number;
1203 if (socket >= NUM_SOCKETS) {
1204 i7core_printk(KERN_ERR,
1205 "Unexpected socket for "
1206 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1207 bus, pci_devs[devno].dev, pci_devs[devno].func,
1208 PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id);
1213 if (pci_devs[devno].pdev[socket]) {
1214 i7core_printk(KERN_ERR,
1215 "Duplicated device for "
1216 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1217 bus, pci_devs[devno].dev, pci_devs[devno].func,
1218 PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id);
1223 pci_devs[devno].pdev[socket] = pdev;
1226 if (unlikely(PCI_SLOT(pdev->devfn) != pci_devs[devno].dev ||
1227 PCI_FUNC(pdev->devfn) != pci_devs[devno].func)) {
1228 i7core_printk(KERN_ERR,
1229 "Device PCI ID %04x:%04x "
1230 "has dev %02x:%02x.%d instead of dev %02x:%02x.%d\n",
1231 PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id,
1232 bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
1233 bus, pci_devs[devno].dev, pci_devs[devno].func);
1237 /* Be sure that the device is enabled */
1238 if (unlikely(pci_enable_device(pdev) < 0)) {
1239 i7core_printk(KERN_ERR,
1241 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1242 bus, pci_devs[devno].dev, pci_devs[devno].func,
1243 PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id);
1247 i7core_printk(KERN_INFO,
1248 "Registered socket %d "
1249 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1250 socket, bus, pci_devs[devno].dev, pci_devs[devno].func,
1251 PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id);
1258 static int i7core_get_devices(void)
1261 struct pci_dev *pdev = NULL;
1263 for (i = 0; i < N_DEVS; i++) {
1266 if (i7core_get_onedevice(&pdev, i) < 0) {
1267 i7core_put_devices();
1275 static int mci_bind_devs(struct mem_ctl_info *mci)
1277 struct i7core_pvt *pvt = mci->pvt_info;
1278 struct pci_dev *pdev;
1279 int i, j, func, slot;
1281 for (i = 0; i < pvt->sockets; i++) {
1282 for (j = 0; j < N_DEVS; j++) {
1283 pdev = pci_devs[j].pdev[i];
1287 func = PCI_FUNC(pdev->devfn);
1288 slot = PCI_SLOT(pdev->devfn);
1290 if (unlikely(func > MAX_MCR_FUNC))
1292 pvt->pci_mcr[i][func] = pdev;
1293 } else if (likely(slot >= 4 && slot < 4 + NUM_CHANS)) {
1294 if (unlikely(func > MAX_CHAN_FUNC))
1296 pvt->pci_ch[i][slot - 4][func] = pdev;
1297 } else if (!slot && !func)
1298 pvt->pci_noncore[i] = pdev;
1302 debugf0("Associated fn %d.%d, dev = %p, socket %d\n",
1303 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
1311 i7core_printk(KERN_ERR, "Device %d, function %d "
1312 "is out of the expected range\n",
1317 /****************************************************************************
1318 Error check routines
1319 ****************************************************************************/
1321 /* This function is based on the device 3 function 4 registers as described on:
1322 * Intel Xeon Processor 5500 Series Datasheet Volume 2
1323 * http://www.intel.com/Assets/PDF/datasheet/321322.pdf
1324 * also available at:
1325 * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
1327 static void check_mc_test_err(struct mem_ctl_info *mci, u8 socket)
1329 struct i7core_pvt *pvt = mci->pvt_info;
1331 int new0, new1, new2;
1333 if (!pvt->pci_mcr[socket][4]) {
1334 debugf0("%s MCR registers not found\n",__func__);
1338 /* Corrected error reads */
1339 pci_read_config_dword(pvt->pci_mcr[socket][4], MC_TEST_ERR_RCV1, &rcv1);
1340 pci_read_config_dword(pvt->pci_mcr[socket][4], MC_TEST_ERR_RCV0, &rcv0);
1342 /* Store the new values */
1343 new2 = DIMM2_COR_ERR(rcv1);
1344 new1 = DIMM1_COR_ERR(rcv0);
1345 new0 = DIMM0_COR_ERR(rcv0);
1348 debugf2("%s CE rcv1=0x%08x rcv0=0x%08x, %d %d %d\n",
1349 (pvt->ce_count_available ? "UPDATE" : "READ"),
1350 rcv1, rcv0, new0, new1, new2);
1353 /* Updates CE counters if it is not the first time here */
1354 if (pvt->ce_count_available[socket]) {
1355 /* Updates CE counters */
1356 int add0, add1, add2;
1358 add2 = new2 - pvt->last_ce_count[socket][2];
1359 add1 = new1 - pvt->last_ce_count[socket][1];
1360 add0 = new0 - pvt->last_ce_count[socket][0];
1364 pvt->ce_count[socket][2] += add2;
1368 pvt->ce_count[socket][1] += add1;
1372 pvt->ce_count[socket][0] += add0;
1374 pvt->ce_count_available[socket] = 1;
1376 /* Store the new values */
1377 pvt->last_ce_count[socket][2] = new2;
1378 pvt->last_ce_count[socket][1] = new1;
1379 pvt->last_ce_count[socket][0] = new0;
1383 * According with tables E-11 and E-12 of chapter E.3.3 of Intel 64 and IA-32
1384 * Architectures Software Developer’s Manual Volume 3B.
1385 * Nehalem are defined as family 0x06, model 0x1a
1387 * The MCA registers used here are the following ones:
1388 * struct mce field MCA Register
1389 * m->status MSR_IA32_MC8_STATUS
1390 * m->addr MSR_IA32_MC8_ADDR
1391 * m->misc MSR_IA32_MC8_MISC
1392 * In the case of Nehalem, the error information is masked at .status and .misc
1395 static void i7core_mce_output_error(struct mem_ctl_info *mci,
1398 char *type, *optype, *err, *msg;
1399 unsigned long error = m->status & 0x1ff0000l;
1400 u32 optypenum = (m->status >> 4) & 0x07;
1401 u32 core_err_cnt = (m->status >> 38) && 0x7fff;
1402 u32 dimm = (m->misc >> 16) & 0x3;
1403 u32 channel = (m->misc >> 18) & 0x3;
1404 u32 syndrome = m->misc >> 32;
1405 u32 errnum = find_first_bit(&error, 32);
1407 if (m->mcgstatus & 1)
1412 switch (optypenum) {
1414 optype = "generic undef request";
1417 optype = "read error";
1420 optype = "write error";
1423 optype = "addr/cmd error";
1426 optype = "scrubbing error";
1429 optype = "reserved";
1435 err = "read ECC error";
1438 err = "RAS ECC error";
1441 err = "write parity error";
1444 err = "redundacy loss";
1450 err = "memory range error";
1453 err = "RTID out of range";
1456 err = "address parity error";
1459 err = "byte enable parity error";
1465 /* FIXME: should convert addr into bank and rank information */
1466 msg = kasprintf(GFP_ATOMIC,
1467 "%s (addr = 0x%08llx, socket=%d, Dimm=%d, Channel=%d, "
1468 "syndrome=0x%08x, count=%d, Err=%08llx:%08llx (%s: %s))\n",
1469 type, (long long) m->addr, m->cpu, dimm, channel,
1470 syndrome, core_err_cnt, (long long)m->status,
1471 (long long)m->misc, optype, err);
1475 /* Call the helper to output message */
1476 edac_mc_handle_fbd_ue(mci, 0 /* FIXME: should be rank here */,
1477 0, 0 /* FIXME: should be channel here */, msg);
1483 * i7core_check_error Retrieve and process errors reported by the
1484 * hardware. Called by the Core module.
1486 static void i7core_check_error(struct mem_ctl_info *mci)
1488 struct i7core_pvt *pvt = mci->pvt_info;
1491 struct mce *m = NULL;
1492 unsigned long flags;
1494 /* Copy all mce errors into a temporary buffer */
1495 spin_lock_irqsave(&pvt->mce_lock, flags);
1496 if (pvt->mce_count) {
1497 m = kmalloc(sizeof(*m) * pvt->mce_count, GFP_ATOMIC);
1499 count = pvt->mce_count;
1500 memcpy(m, &pvt->mce_entry, sizeof(*m) * count);
1504 spin_unlock_irqrestore(&pvt->mce_lock, flags);
1506 /* proccess mcelog errors */
1507 for (i = 0; i < count; i++)
1508 i7core_mce_output_error(mci, &m[i]);
1512 /* check memory count errors */
1513 for (i = 0; i < pvt->sockets; i++)
1514 check_mc_test_err(mci, i);
1518 * i7core_mce_check_error Replicates mcelog routine to get errors
1519 * This routine simply queues mcelog errors, and
1520 * return. The error itself should be handled later
1521 * by i7core_check_error.
1523 static int i7core_mce_check_error(void *priv, struct mce *mce)
1525 struct mem_ctl_info *mci = priv;
1526 struct i7core_pvt *pvt = mci->pvt_info;
1527 unsigned long flags;
1530 * Just let mcelog handle it if the error is
1531 * outside the memory controller
1533 if (((mce->status & 0xffff) >> 7) != 1)
1536 /* Bank 8 registers are the only ones that we know how to handle */
1540 spin_lock_irqsave(&pvt->mce_lock, flags);
1541 if (pvt->mce_count < MCE_LOG_LEN) {
1542 memcpy(&pvt->mce_entry[pvt->mce_count], mce, sizeof(*mce));
1545 spin_unlock_irqrestore(&pvt->mce_lock, flags);
1547 /* Handle fatal errors immediately */
1548 if (mce->mcgstatus & 1)
1549 i7core_check_error(mci);
1551 /* Advice mcelog that the error were handled */
1556 * i7core_probe Probe for ONE instance of device to see if it is
1559 * 0 for FOUND a device
1560 * < 0 for error code
1562 static int __devinit i7core_probe(struct pci_dev *pdev,
1563 const struct pci_device_id *id)
1565 struct mem_ctl_info *mci;
1566 struct i7core_pvt *pvt;
1567 int num_channels = 0;
1570 int dev_idx = id->driver_data;
1574 if (unlikely(dev_idx >= ARRAY_SIZE(i7core_devs)))
1577 /* get the pci devices we want to reserve for our use */
1578 rc = i7core_get_devices();
1579 if (unlikely(rc < 0))
1583 for (i = NUM_SOCKETS - 1; i > 0; i--)
1584 if (pci_devs[0].pdev[i]) {
1589 for (i = 0; i < sockets; i++) {
1593 /* Check the number of active and not disabled channels */
1594 rc = i7core_get_active_channels(i, &channels, &csrows);
1595 if (unlikely(rc < 0))
1598 num_channels += channels;
1599 num_csrows += csrows;
1602 /* allocate a new MC control structure */
1603 mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0);
1604 if (unlikely(!mci)) {
1609 debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci);
1611 mci->dev = &pdev->dev; /* record ptr to the generic device */
1612 pvt = mci->pvt_info;
1613 memset(pvt, 0, sizeof(*pvt));
1614 pvt->sockets = sockets;
1618 * FIXME: how to handle RDDR3 at MCI level? It is possible to have
1619 * Mixed RDDR3/UDDR3 with Nehalem, provided that they are on different
1622 mci->mtype_cap = MEM_FLAG_DDR3;
1623 mci->edac_ctl_cap = EDAC_FLAG_NONE;
1624 mci->edac_cap = EDAC_FLAG_NONE;
1625 mci->mod_name = "i7core_edac.c";
1626 mci->mod_ver = I7CORE_REVISION;
1627 mci->ctl_name = i7core_devs[dev_idx].ctl_name;
1628 mci->dev_name = pci_name(pdev);
1629 mci->ctl_page_to_phys = NULL;
1630 mci->mc_driver_sysfs_attributes = i7core_inj_attrs;
1631 /* Set the function pointer to an actual operation function */
1632 mci->edac_check = i7core_check_error;
1634 /* Store pci devices at mci for faster access */
1635 rc = mci_bind_devs(mci);
1636 if (unlikely(rc < 0))
1639 /* Get dimm basic config */
1640 for (i = 0; i < sockets; i++)
1641 get_dimm_config(mci, &csrow, i);
1643 /* add this new MC control structure to EDAC's list of MCs */
1644 if (unlikely(edac_mc_add_mc(mci))) {
1645 debugf0("MC: " __FILE__
1646 ": %s(): failed edac_mc_add_mc()\n", __func__);
1647 /* FIXME: perhaps some code should go here that disables error
1648 * reporting if we just enabled it
1655 /* allocating generic PCI control info */
1656 i7core_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
1657 if (unlikely(!i7core_pci)) {
1659 "%s(): Unable to create PCI control\n",
1662 "%s(): PCI error report via EDAC not setup\n",
1666 /* Default error mask is any memory */
1667 pvt->inject.channel = 0;
1668 pvt->inject.dimm = -1;
1669 pvt->inject.rank = -1;
1670 pvt->inject.bank = -1;
1671 pvt->inject.page = -1;
1672 pvt->inject.col = -1;
1674 /* Registers on edac_mce in order to receive memory errors */
1675 pvt->edac_mce.priv = mci;
1676 pvt->edac_mce.check_error = i7core_mce_check_error;
1677 spin_lock_init(&pvt->mce_lock);
1679 rc = edac_mce_register(&pvt->edac_mce);
1680 if (unlikely (rc < 0)) {
1681 debugf0("MC: " __FILE__
1682 ": %s(): failed edac_mce_register()\n", __func__);
1686 i7core_printk(KERN_INFO, "Driver loaded.\n");
1694 i7core_put_devices();
1699 * i7core_remove destructor for one instance of device
1702 static void __devexit i7core_remove(struct pci_dev *pdev)
1704 struct mem_ctl_info *mci;
1705 struct i7core_pvt *pvt;
1707 debugf0(__FILE__ ": %s()\n", __func__);
1710 edac_pci_release_generic_ctl(i7core_pci);
1713 mci = edac_mc_del_mc(&pdev->dev);
1717 /* Unregisters on edac_mce in order to receive memory errors */
1718 pvt = mci->pvt_info;
1719 edac_mce_unregister(&pvt->edac_mce);
1721 /* retrieve references to resources, and free those resources */
1722 i7core_put_devices();
1727 MODULE_DEVICE_TABLE(pci, i7core_pci_tbl);
1730 * i7core_driver pci_driver structure for this module
1733 static struct pci_driver i7core_driver = {
1734 .name = "i7core_edac",
1735 .probe = i7core_probe,
1736 .remove = __devexit_p(i7core_remove),
1737 .id_table = i7core_pci_tbl,
1741 * i7core_init Module entry function
1742 * Try to initialize this module for its devices
1744 static int __init i7core_init(void)
1748 debugf2("MC: " __FILE__ ": %s()\n", __func__);
1750 /* Ensure that the OPSTATE is set correctly for POLL or NMI */
1753 pci_rc = pci_register_driver(&i7core_driver);
1755 return (pci_rc < 0) ? pci_rc : 0;
1759 * i7core_exit() Module exit function
1760 * Unregister the driver
1762 static void __exit i7core_exit(void)
1764 debugf2("MC: " __FILE__ ": %s()\n", __func__);
1765 pci_unregister_driver(&i7core_driver);
1768 module_init(i7core_init);
1769 module_exit(i7core_exit);
1771 MODULE_LICENSE("GPL");
1772 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
1773 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
1774 MODULE_DESCRIPTION("MC Driver for Intel i7 Core memory controllers - "
1777 module_param(edac_op_state, int, 0444);
1778 MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");