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"
36 * Alter this version for the module when modifications are made
38 #define I7CORE_REVISION " Ver: 1.0.0 " __DATE__
39 #define EDAC_MOD_STR "i7core_edac"
44 #define i7core_printk(level, fmt, arg...) \
45 edac_printk(level, "i7core", fmt, ##arg)
47 #define i7core_mc_printk(mci, level, fmt, arg...) \
48 edac_mc_chipset_printk(mci, level, "i7core", fmt, ##arg)
51 * i7core Memory Controller Registers
54 /* OFFSETS for Device 0 Function 0 */
56 #define MC_CFG_CONTROL 0x90
58 /* OFFSETS for Device 3 Function 0 */
60 #define MC_CONTROL 0x48
61 #define MC_STATUS 0x4c
62 #define MC_MAX_DOD 0x64
65 * OFFSETS for Device 3 Function 4, as inicated on Xeon 5500 datasheet:
66 * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
69 #define MC_TEST_ERR_RCV1 0x60
70 #define DIMM2_COR_ERR(r) ((r) & 0x7fff)
72 #define MC_TEST_ERR_RCV0 0x64
73 #define DIMM1_COR_ERR(r) (((r) >> 16) & 0x7fff)
74 #define DIMM0_COR_ERR(r) ((r) & 0x7fff)
76 /* OFFSETS for Device 3 Function 2, as inicated on Xeon 5500 datasheet */
77 #define MC_COR_ECC_CNT_0 0x80
78 #define MC_COR_ECC_CNT_1 0x84
79 #define MC_COR_ECC_CNT_2 0x88
80 #define MC_COR_ECC_CNT_3 0x8c
81 #define MC_COR_ECC_CNT_4 0x90
82 #define MC_COR_ECC_CNT_5 0x94
84 #define DIMM_TOP_COR_ERR(r) (((r) >> 16) & 0x7fff)
85 #define DIMM_BOT_COR_ERR(r) ((r) & 0x7fff)
88 /* OFFSETS for Devices 4,5 and 6 Function 0 */
90 #define MC_CHANNEL_DIMM_INIT_PARAMS 0x58
91 #define THREE_DIMMS_PRESENT (1 << 24)
92 #define SINGLE_QUAD_RANK_PRESENT (1 << 23)
93 #define QUAD_RANK_PRESENT (1 << 22)
94 #define REGISTERED_DIMM (1 << 15)
96 #define MC_CHANNEL_MAPPER 0x60
97 #define RDLCH(r, ch) ((((r) >> (3 + (ch * 6))) & 0x07) - 1)
98 #define WRLCH(r, ch) ((((r) >> (ch * 6)) & 0x07) - 1)
100 #define MC_CHANNEL_RANK_PRESENT 0x7c
101 #define RANK_PRESENT_MASK 0xffff
103 #define MC_CHANNEL_ADDR_MATCH 0xf0
104 #define MC_CHANNEL_ERROR_MASK 0xf8
105 #define MC_CHANNEL_ERROR_INJECT 0xfc
106 #define INJECT_ADDR_PARITY 0x10
107 #define INJECT_ECC 0x08
108 #define MASK_CACHELINE 0x06
109 #define MASK_FULL_CACHELINE 0x06
110 #define MASK_MSB32_CACHELINE 0x04
111 #define MASK_LSB32_CACHELINE 0x02
112 #define NO_MASK_CACHELINE 0x00
113 #define REPEAT_EN 0x01
115 /* OFFSETS for Devices 4,5 and 6 Function 1 */
117 #define MC_DOD_CH_DIMM0 0x48
118 #define MC_DOD_CH_DIMM1 0x4c
119 #define MC_DOD_CH_DIMM2 0x50
120 #define RANKOFFSET_MASK ((1 << 12) | (1 << 11) | (1 << 10))
121 #define RANKOFFSET(x) ((x & RANKOFFSET_MASK) >> 10)
122 #define DIMM_PRESENT_MASK (1 << 9)
123 #define DIMM_PRESENT(x) (((x) & DIMM_PRESENT_MASK) >> 9)
124 #define MC_DOD_NUMBANK_MASK ((1 << 8) | (1 << 7))
125 #define MC_DOD_NUMBANK(x) (((x) & MC_DOD_NUMBANK_MASK) >> 7)
126 #define MC_DOD_NUMRANK_MASK ((1 << 6) | (1 << 5))
127 #define MC_DOD_NUMRANK(x) (((x) & MC_DOD_NUMRANK_MASK) >> 5)
128 #define MC_DOD_NUMROW_MASK ((1 << 4) | (1 << 3) | (1 << 2))
129 #define MC_DOD_NUMROW(x) (((x) & MC_DOD_NUMROW_MASK) >> 2)
130 #define MC_DOD_NUMCOL_MASK 3
131 #define MC_DOD_NUMCOL(x) ((x) & MC_DOD_NUMCOL_MASK)
133 #define MC_RANK_PRESENT 0x7c
135 #define MC_SAG_CH_0 0x80
136 #define MC_SAG_CH_1 0x84
137 #define MC_SAG_CH_2 0x88
138 #define MC_SAG_CH_3 0x8c
139 #define MC_SAG_CH_4 0x90
140 #define MC_SAG_CH_5 0x94
141 #define MC_SAG_CH_6 0x98
142 #define MC_SAG_CH_7 0x9c
144 #define MC_RIR_LIMIT_CH_0 0x40
145 #define MC_RIR_LIMIT_CH_1 0x44
146 #define MC_RIR_LIMIT_CH_2 0x48
147 #define MC_RIR_LIMIT_CH_3 0x4C
148 #define MC_RIR_LIMIT_CH_4 0x50
149 #define MC_RIR_LIMIT_CH_5 0x54
150 #define MC_RIR_LIMIT_CH_6 0x58
151 #define MC_RIR_LIMIT_CH_7 0x5C
152 #define MC_RIR_LIMIT_MASK ((1 << 10) - 1)
154 #define MC_RIR_WAY_CH 0x80
155 #define MC_RIR_WAY_OFFSET_MASK (((1 << 14) - 1) & ~0x7)
156 #define MC_RIR_WAY_RANK_MASK 0x7
163 #define MAX_DIMMS 3 /* Max DIMMS per channel */
164 #define NUM_SOCKETS 2 /* Max number of MC sockets */
165 #define MAX_MCR_FUNC 4
166 #define MAX_CHAN_FUNC 3
176 struct i7core_inject
{
184 /* Error address mask */
185 int channel
, dimm
, rank
, bank
, page
, col
;
188 struct i7core_channel
{
193 struct pci_id_descr
{
197 struct pci_dev
*pdev
[NUM_SOCKETS
];
201 struct pci_dev
*pci_noncore
[NUM_SOCKETS
];
202 struct pci_dev
*pci_mcr
[NUM_SOCKETS
][MAX_MCR_FUNC
+ 1];
203 struct pci_dev
*pci_ch
[NUM_SOCKETS
][NUM_CHANS
][MAX_CHAN_FUNC
+ 1];
205 struct i7core_info info
;
206 struct i7core_inject inject
;
207 struct i7core_channel channel
[NUM_SOCKETS
][NUM_CHANS
];
209 unsigned int is_registered
:1; /* true if all memories are RDIMMs */
211 int sockets
; /* Number of sockets */
212 int channels
; /* Number of active channels */
214 int ce_count_available
[NUM_SOCKETS
];
215 int csrow_map
[NUM_SOCKETS
][NUM_CHANS
][MAX_DIMMS
];
217 /* ECC corrected errors counts per udimm */
218 unsigned long udimm_ce_count
[NUM_SOCKETS
][MAX_DIMMS
];
219 int udimm_last_ce_count
[NUM_SOCKETS
][MAX_DIMMS
];
220 /* ECC corrected errors counts per rdimm */
221 unsigned long rdimm_ce_count
[NUM_SOCKETS
][NUM_CHANS
][MAX_DIMMS
];
222 int rdimm_last_ce_count
[NUM_SOCKETS
][NUM_CHANS
][MAX_DIMMS
];
225 struct edac_mce edac_mce
;
226 struct mce mce_entry
[MCE_LOG_LEN
];
231 /* Device name and register DID (Device ID) */
232 struct i7core_dev_info
{
233 const char *ctl_name
; /* name for this device */
234 u16 fsb_mapping_errors
; /* DID for the branchmap,control */
237 #define PCI_DESCR(device, function, device_id) \
239 .func = (function), \
240 .dev_id = (device_id)
242 struct pci_id_descr pci_devs
[] = {
243 /* Memory controller */
244 { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR
) },
245 { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD
) },
246 { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS
) }, /* if RDIMM */
247 { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST
) },
250 { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL
) },
251 { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH0_ADDR
) },
252 { PCI_DESCR(4, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH0_RANK
) },
253 { PCI_DESCR(4, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH0_TC
) },
256 { PCI_DESCR(5, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH1_CTRL
) },
257 { PCI_DESCR(5, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH1_ADDR
) },
258 { PCI_DESCR(5, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH1_RANK
) },
259 { PCI_DESCR(5, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH1_TC
) },
262 { PCI_DESCR(6, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH2_CTRL
) },
263 { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR
) },
264 { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK
) },
265 { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC
) },
267 /* Generic Non-core registers */
269 * This is the PCI device on i7core and on Xeon 35xx (8086:2c41)
270 * On Xeon 55xx, however, it has a different id (8086:2c40). So,
271 * the probing code needs to test for the other address in case of
272 * failure of this one
274 { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NOCORE
) },
277 #define N_DEVS ARRAY_SIZE(pci_devs)
280 * pci_device_id table for which devices we are looking for
281 * This should match the first device at pci_devs table
283 static const struct pci_device_id i7core_pci_tbl
[] __devinitdata
= {
284 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_INTEL_X58_HUB_MGMT
)},
285 {0,} /* 0 terminated list. */
289 /* Table of devices attributes supported by this driver */
290 static const struct i7core_dev_info i7core_devs
[] = {
292 .ctl_name
= "i7 Core",
293 .fsb_mapping_errors
= PCI_DEVICE_ID_INTEL_I7_MCR
,
297 static struct edac_pci_ctl_info
*i7core_pci
;
299 /****************************************************************************
300 Anciliary status routines
301 ****************************************************************************/
303 /* MC_CONTROL bits */
304 #define CH_ACTIVE(pvt, ch) ((pvt)->info.mc_control & (1 << (8 + ch)))
305 #define ECCx8(pvt) ((pvt)->info.mc_control & (1 << 1))
308 #define ECC_ENABLED(pvt) ((pvt)->info.mc_status & (1 << 4))
309 #define CH_DISABLED(pvt, ch) ((pvt)->info.mc_status & (1 << ch))
311 /* MC_MAX_DOD read functions */
312 static inline int numdimms(u32 dimms
)
314 return (dimms
& 0x3) + 1;
317 static inline int numrank(u32 rank
)
319 static int ranks
[4] = { 1, 2, 4, -EINVAL
};
321 return ranks
[rank
& 0x3];
324 static inline int numbank(u32 bank
)
326 static int banks
[4] = { 4, 8, 16, -EINVAL
};
328 return banks
[bank
& 0x3];
331 static inline int numrow(u32 row
)
333 static int rows
[8] = {
334 1 << 12, 1 << 13, 1 << 14, 1 << 15,
335 1 << 16, -EINVAL
, -EINVAL
, -EINVAL
,
338 return rows
[row
& 0x7];
341 static inline int numcol(u32 col
)
343 static int cols
[8] = {
344 1 << 10, 1 << 11, 1 << 12, -EINVAL
,
346 return cols
[col
& 0x3];
349 /****************************************************************************
350 Memory check routines
351 ****************************************************************************/
352 static struct pci_dev
*get_pdev_slot_func(u8 socket
, unsigned slot
,
357 for (i
= 0; i
< N_DEVS
; i
++) {
358 if (!pci_devs
[i
].pdev
[socket
])
361 if (PCI_SLOT(pci_devs
[i
].pdev
[socket
]->devfn
) == slot
&&
362 PCI_FUNC(pci_devs
[i
].pdev
[socket
]->devfn
) == func
) {
363 return pci_devs
[i
].pdev
[socket
];
371 * i7core_get_active_channels() - gets the number of channels and csrows
372 * @socket: Quick Path Interconnect socket
373 * @channels: Number of channels that will be returned
374 * @csrows: Number of csrows found
376 * Since EDAC core needs to know in advance the number of available channels
377 * and csrows, in order to allocate memory for csrows/channels, it is needed
378 * to run two similar steps. At the first step, implemented on this function,
379 * it checks the number of csrows/channels present at one socket.
380 * this is used in order to properly allocate the size of mci components.
382 * It should be noticed that none of the current available datasheets explain
383 * or even mention how csrows are seen by the memory controller. So, we need
384 * to add a fake description for csrows.
385 * So, this driver is attributing one DIMM memory for one csrow.
387 static int i7core_get_active_channels(u8 socket
, unsigned *channels
,
390 struct pci_dev
*pdev
= NULL
;
397 pdev
= get_pdev_slot_func(socket
, 3, 0);
399 i7core_printk(KERN_ERR
, "Couldn't find socket %d fn 3.0!!!\n",
404 /* Device 3 function 0 reads */
405 pci_read_config_dword(pdev
, MC_STATUS
, &status
);
406 pci_read_config_dword(pdev
, MC_CONTROL
, &control
);
408 for (i
= 0; i
< NUM_CHANS
; i
++) {
410 /* Check if the channel is active */
411 if (!(control
& (1 << (8 + i
))))
414 /* Check if the channel is disabled */
415 if (status
& (1 << i
))
418 pdev
= get_pdev_slot_func(socket
, i
+ 4, 1);
420 i7core_printk(KERN_ERR
, "Couldn't find socket %d "
425 /* Devices 4-6 function 1 */
426 pci_read_config_dword(pdev
,
427 MC_DOD_CH_DIMM0
, &dimm_dod
[0]);
428 pci_read_config_dword(pdev
,
429 MC_DOD_CH_DIMM1
, &dimm_dod
[1]);
430 pci_read_config_dword(pdev
,
431 MC_DOD_CH_DIMM2
, &dimm_dod
[2]);
435 for (j
= 0; j
< 3; j
++) {
436 if (!DIMM_PRESENT(dimm_dod
[j
]))
442 debugf0("Number of active channels on socket %d: %d\n",
448 static int get_dimm_config(struct mem_ctl_info
*mci
, int *csrow
, u8 socket
)
450 struct i7core_pvt
*pvt
= mci
->pvt_info
;
451 struct csrow_info
*csr
;
452 struct pci_dev
*pdev
;
454 unsigned long last_page
= 0;
458 /* Get data from the MC register, function 0 */
459 pdev
= pvt
->pci_mcr
[socket
][0];
463 /* Device 3 function 0 reads */
464 pci_read_config_dword(pdev
, MC_CONTROL
, &pvt
->info
.mc_control
);
465 pci_read_config_dword(pdev
, MC_STATUS
, &pvt
->info
.mc_status
);
466 pci_read_config_dword(pdev
, MC_MAX_DOD
, &pvt
->info
.max_dod
);
467 pci_read_config_dword(pdev
, MC_CHANNEL_MAPPER
, &pvt
->info
.ch_map
);
469 debugf0("QPI %d control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n",
470 socket
, pvt
->info
.mc_control
, pvt
->info
.mc_status
,
471 pvt
->info
.max_dod
, pvt
->info
.ch_map
);
473 if (ECC_ENABLED(pvt
)) {
474 debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt
) ? 8 : 4);
476 mode
= EDAC_S8ECD8ED
;
478 mode
= EDAC_S4ECD4ED
;
480 debugf0("ECC disabled\n");
484 /* FIXME: need to handle the error codes */
485 debugf0("DOD Max limits: DIMMS: %d, %d-ranked, %d-banked "
487 numdimms(pvt
->info
.max_dod
),
488 numrank(pvt
->info
.max_dod
>> 2),
489 numbank(pvt
->info
.max_dod
>> 4),
490 numrow(pvt
->info
.max_dod
>> 6),
491 numcol(pvt
->info
.max_dod
>> 9));
493 pvt
->is_registered
= 1;
495 for (i
= 0; i
< NUM_CHANS
; i
++) {
496 u32 data
, dimm_dod
[3], value
[8];
498 if (!CH_ACTIVE(pvt
, i
)) {
499 debugf0("Channel %i is not active\n", i
);
502 if (CH_DISABLED(pvt
, i
)) {
503 debugf0("Channel %i is disabled\n", i
);
507 /* Devices 4-6 function 0 */
508 pci_read_config_dword(pvt
->pci_ch
[socket
][i
][0],
509 MC_CHANNEL_DIMM_INIT_PARAMS
, &data
);
511 pvt
->channel
[socket
][i
].ranks
= (data
& QUAD_RANK_PRESENT
) ?
514 if (data
& REGISTERED_DIMM
)
519 * FIXME: Currently, the driver will use dev 3:2
520 * counter registers only if all memories are registered
522 pvt
->is_registered
= 0;
525 if (data
& THREE_DIMMS_PRESENT
)
526 pvt
->channel
[i
].dimms
= 3;
527 else if (data
& SINGLE_QUAD_RANK_PRESENT
)
528 pvt
->channel
[i
].dimms
= 1;
530 pvt
->channel
[i
].dimms
= 2;
533 /* Devices 4-6 function 1 */
534 pci_read_config_dword(pvt
->pci_ch
[socket
][i
][1],
535 MC_DOD_CH_DIMM0
, &dimm_dod
[0]);
536 pci_read_config_dword(pvt
->pci_ch
[socket
][i
][1],
537 MC_DOD_CH_DIMM1
, &dimm_dod
[1]);
538 pci_read_config_dword(pvt
->pci_ch
[socket
][i
][1],
539 MC_DOD_CH_DIMM2
, &dimm_dod
[2]);
541 debugf0("Ch%d phy rd%d, wr%d (0x%08x): "
542 "%d ranks, %cDIMMs\n",
544 RDLCH(pvt
->info
.ch_map
, i
), WRLCH(pvt
->info
.ch_map
, i
),
546 pvt
->channel
[socket
][i
].ranks
,
547 (data
& REGISTERED_DIMM
) ? 'R' : 'U');
549 for (j
= 0; j
< 3; j
++) {
550 u32 banks
, ranks
, rows
, cols
;
553 if (!DIMM_PRESENT(dimm_dod
[j
]))
556 banks
= numbank(MC_DOD_NUMBANK(dimm_dod
[j
]));
557 ranks
= numrank(MC_DOD_NUMRANK(dimm_dod
[j
]));
558 rows
= numrow(MC_DOD_NUMROW(dimm_dod
[j
]));
559 cols
= numcol(MC_DOD_NUMCOL(dimm_dod
[j
]));
561 /* DDR3 has 8 I/O banks */
562 size
= (rows
* cols
* banks
* ranks
) >> (20 - 3);
564 pvt
->channel
[socket
][i
].dimms
++;
566 debugf0("\tdimm %d %d Mb offset: %x, "
567 "bank: %d, rank: %d, row: %#x, col: %#x\n",
569 RANKOFFSET(dimm_dod
[j
]),
570 banks
, ranks
, rows
, cols
);
573 npages
= size
>> (PAGE_SHIFT
- 20);
575 npages
= size
<< (20 - PAGE_SHIFT
);
578 csr
= &mci
->csrows
[*csrow
];
579 csr
->first_page
= last_page
+ 1;
581 csr
->last_page
= last_page
;
582 csr
->nr_pages
= npages
;
586 csr
->csrow_idx
= *csrow
;
587 csr
->nr_channels
= 1;
589 csr
->channels
[0].chan_idx
= i
;
590 csr
->channels
[0].ce_count
= 0;
592 pvt
->csrow_map
[socket
][i
][j
] = *csrow
;
602 csr
->dtype
= DEV_X16
;
605 csr
->dtype
= DEV_UNKNOWN
;
608 csr
->edac_mode
= mode
;
614 pci_read_config_dword(pdev
, MC_SAG_CH_0
, &value
[0]);
615 pci_read_config_dword(pdev
, MC_SAG_CH_1
, &value
[1]);
616 pci_read_config_dword(pdev
, MC_SAG_CH_2
, &value
[2]);
617 pci_read_config_dword(pdev
, MC_SAG_CH_3
, &value
[3]);
618 pci_read_config_dword(pdev
, MC_SAG_CH_4
, &value
[4]);
619 pci_read_config_dword(pdev
, MC_SAG_CH_5
, &value
[5]);
620 pci_read_config_dword(pdev
, MC_SAG_CH_6
, &value
[6]);
621 pci_read_config_dword(pdev
, MC_SAG_CH_7
, &value
[7]);
622 debugf1("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i
);
623 for (j
= 0; j
< 8; j
++)
624 debugf1("\t\t%#x\t%#x\t%#x\n",
625 (value
[j
] >> 27) & 0x1,
626 (value
[j
] >> 24) & 0x7,
627 (value
[j
] && ((1 << 24) - 1)));
633 /****************************************************************************
634 Error insertion routines
635 ****************************************************************************/
637 /* The i7core has independent error injection features per channel.
638 However, to have a simpler code, we don't allow enabling error injection
639 on more than one channel.
640 Also, since a change at an inject parameter will be applied only at enable,
641 we're disabling error injection on all write calls to the sysfs nodes that
642 controls the error code injection.
644 static int disable_inject(struct mem_ctl_info
*mci
)
646 struct i7core_pvt
*pvt
= mci
->pvt_info
;
648 pvt
->inject
.enable
= 0;
650 if (!pvt
->pci_ch
[pvt
->inject
.socket
][pvt
->inject
.channel
][0])
653 pci_write_config_dword(pvt
->pci_ch
[pvt
->inject
.socket
][pvt
->inject
.channel
][0],
654 MC_CHANNEL_ERROR_INJECT
, 0);
660 * i7core inject inject.socket
662 * accept and store error injection inject.socket value
664 static ssize_t
i7core_inject_socket_store(struct mem_ctl_info
*mci
,
665 const char *data
, size_t count
)
667 struct i7core_pvt
*pvt
= mci
->pvt_info
;
671 rc
= strict_strtoul(data
, 10, &value
);
672 if ((rc
< 0) || (value
>= pvt
->sockets
))
675 pvt
->inject
.socket
= (u32
) value
;
679 static ssize_t
i7core_inject_socket_show(struct mem_ctl_info
*mci
,
682 struct i7core_pvt
*pvt
= mci
->pvt_info
;
683 return sprintf(data
, "%d\n", pvt
->inject
.socket
);
687 * i7core inject inject.section
689 * accept and store error injection inject.section value
690 * bit 0 - refers to the lower 32-byte half cacheline
691 * bit 1 - refers to the upper 32-byte half cacheline
693 static ssize_t
i7core_inject_section_store(struct mem_ctl_info
*mci
,
694 const char *data
, size_t count
)
696 struct i7core_pvt
*pvt
= mci
->pvt_info
;
700 if (pvt
->inject
.enable
)
703 rc
= strict_strtoul(data
, 10, &value
);
704 if ((rc
< 0) || (value
> 3))
707 pvt
->inject
.section
= (u32
) value
;
711 static ssize_t
i7core_inject_section_show(struct mem_ctl_info
*mci
,
714 struct i7core_pvt
*pvt
= mci
->pvt_info
;
715 return sprintf(data
, "0x%08x\n", pvt
->inject
.section
);
721 * accept and store error injection inject.section value
722 * bit 0 - repeat enable - Enable error repetition
723 * bit 1 - inject ECC error
724 * bit 2 - inject parity error
726 static ssize_t
i7core_inject_type_store(struct mem_ctl_info
*mci
,
727 const char *data
, size_t count
)
729 struct i7core_pvt
*pvt
= mci
->pvt_info
;
733 if (pvt
->inject
.enable
)
736 rc
= strict_strtoul(data
, 10, &value
);
737 if ((rc
< 0) || (value
> 7))
740 pvt
->inject
.type
= (u32
) value
;
744 static ssize_t
i7core_inject_type_show(struct mem_ctl_info
*mci
,
747 struct i7core_pvt
*pvt
= mci
->pvt_info
;
748 return sprintf(data
, "0x%08x\n", pvt
->inject
.type
);
752 * i7core_inject_inject.eccmask_store
754 * The type of error (UE/CE) will depend on the inject.eccmask value:
755 * Any bits set to a 1 will flip the corresponding ECC bit
756 * Correctable errors can be injected by flipping 1 bit or the bits within
757 * a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or
758 * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an
759 * uncorrectable error to be injected.
761 static ssize_t
i7core_inject_eccmask_store(struct mem_ctl_info
*mci
,
762 const char *data
, size_t count
)
764 struct i7core_pvt
*pvt
= mci
->pvt_info
;
768 if (pvt
->inject
.enable
)
771 rc
= strict_strtoul(data
, 10, &value
);
775 pvt
->inject
.eccmask
= (u32
) value
;
779 static ssize_t
i7core_inject_eccmask_show(struct mem_ctl_info
*mci
,
782 struct i7core_pvt
*pvt
= mci
->pvt_info
;
783 return sprintf(data
, "0x%08x\n", pvt
->inject
.eccmask
);
789 * The type of error (UE/CE) will depend on the inject.eccmask value:
790 * Any bits set to a 1 will flip the corresponding ECC bit
791 * Correctable errors can be injected by flipping 1 bit or the bits within
792 * a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or
793 * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an
794 * uncorrectable error to be injected.
796 static ssize_t
i7core_inject_addrmatch_store(struct mem_ctl_info
*mci
,
797 const char *data
, size_t count
)
799 struct i7core_pvt
*pvt
= mci
->pvt_info
;
804 if (pvt
->inject
.enable
)
808 cmd
= strsep((char **) &data
, ":");
811 val
= strsep((char **) &data
, " \n\t");
815 if (!strcasecmp(val
, "any"))
818 rc
= strict_strtol(val
, 10, &value
);
819 if ((rc
< 0) || (value
< 0))
823 if (!strcasecmp(cmd
, "channel")) {
825 pvt
->inject
.channel
= value
;
828 } else if (!strcasecmp(cmd
, "dimm")) {
830 pvt
->inject
.dimm
= value
;
833 } else if (!strcasecmp(cmd
, "rank")) {
835 pvt
->inject
.rank
= value
;
838 } else if (!strcasecmp(cmd
, "bank")) {
840 pvt
->inject
.bank
= value
;
843 } else if (!strcasecmp(cmd
, "page")) {
845 pvt
->inject
.page
= value
;
848 } else if (!strcasecmp(cmd
, "col") ||
849 !strcasecmp(cmd
, "column")) {
851 pvt
->inject
.col
= value
;
860 static ssize_t
i7core_inject_addrmatch_show(struct mem_ctl_info
*mci
,
863 struct i7core_pvt
*pvt
= mci
->pvt_info
;
864 char channel
[4], dimm
[4], bank
[4], rank
[4], page
[7], col
[7];
866 if (pvt
->inject
.channel
< 0)
867 sprintf(channel
, "any");
869 sprintf(channel
, "%d", pvt
->inject
.channel
);
870 if (pvt
->inject
.dimm
< 0)
871 sprintf(dimm
, "any");
873 sprintf(dimm
, "%d", pvt
->inject
.dimm
);
874 if (pvt
->inject
.bank
< 0)
875 sprintf(bank
, "any");
877 sprintf(bank
, "%d", pvt
->inject
.bank
);
878 if (pvt
->inject
.rank
< 0)
879 sprintf(rank
, "any");
881 sprintf(rank
, "%d", pvt
->inject
.rank
);
882 if (pvt
->inject
.page
< 0)
883 sprintf(page
, "any");
885 sprintf(page
, "0x%04x", pvt
->inject
.page
);
886 if (pvt
->inject
.col
< 0)
889 sprintf(col
, "0x%04x", pvt
->inject
.col
);
891 return sprintf(data
, "channel: %s\ndimm: %s\nbank: %s\n"
892 "rank: %s\npage: %s\ncolumn: %s\n",
893 channel
, dimm
, bank
, rank
, page
, col
);
896 static int write_and_test(struct pci_dev
*dev
, int where
, u32 val
)
901 debugf0("setting pci %02x:%02x.%x reg=%02x value=%08x\n",
902 dev
->bus
->number
, PCI_SLOT(dev
->devfn
), PCI_FUNC(dev
->devfn
),
905 for (count
= 0; count
< 10; count
++) {
908 pci_write_config_dword(dev
, where
, val
);
909 pci_read_config_dword(dev
, where
, &read
);
915 i7core_printk(KERN_ERR
, "Error during set pci %02x:%02x.%x reg=%02x "
916 "write=%08x. Read=%08x\n",
917 dev
->bus
->number
, PCI_SLOT(dev
->devfn
), PCI_FUNC(dev
->devfn
),
924 * This routine prepares the Memory Controller for error injection.
925 * The error will be injected when some process tries to write to the
926 * memory that matches the given criteria.
927 * The criteria can be set in terms of a mask where dimm, rank, bank, page
928 * and col can be specified.
929 * A -1 value for any of the mask items will make the MCU to ignore
930 * that matching criteria for error injection.
932 * It should be noticed that the error will only happen after a write operation
933 * on a memory that matches the condition. if REPEAT_EN is not enabled at
934 * inject mask, then it will produce just one error. Otherwise, it will repeat
935 * until the injectmask would be cleaned.
937 * FIXME: This routine assumes that MAXNUMDIMMS value of MC_MAX_DOD
938 * is reliable enough to check if the MC is using the
939 * three channels. However, this is not clear at the datasheet.
941 static ssize_t
i7core_inject_enable_store(struct mem_ctl_info
*mci
,
942 const char *data
, size_t count
)
944 struct i7core_pvt
*pvt
= mci
->pvt_info
;
950 if (!pvt
->pci_ch
[pvt
->inject
.socket
][pvt
->inject
.channel
][0])
953 rc
= strict_strtoul(data
, 10, &enable
);
958 pvt
->inject
.enable
= 1;
964 /* Sets pvt->inject.dimm mask */
965 if (pvt
->inject
.dimm
< 0)
968 if (pvt
->channel
[pvt
->inject
.socket
][pvt
->inject
.channel
].dimms
> 2)
969 mask
|= (pvt
->inject
.dimm
& 0x3L
) << 35;
971 mask
|= (pvt
->inject
.dimm
& 0x1L
) << 36;
974 /* Sets pvt->inject.rank mask */
975 if (pvt
->inject
.rank
< 0)
978 if (pvt
->channel
[pvt
->inject
.socket
][pvt
->inject
.channel
].dimms
> 2)
979 mask
|= (pvt
->inject
.rank
& 0x1L
) << 34;
981 mask
|= (pvt
->inject
.rank
& 0x3L
) << 34;
984 /* Sets pvt->inject.bank mask */
985 if (pvt
->inject
.bank
< 0)
988 mask
|= (pvt
->inject
.bank
& 0x15L
) << 30;
990 /* Sets pvt->inject.page mask */
991 if (pvt
->inject
.page
< 0)
994 mask
|= (pvt
->inject
.page
& 0xffffL
) << 14;
996 /* Sets pvt->inject.column mask */
997 if (pvt
->inject
.col
< 0)
1000 mask
|= (pvt
->inject
.col
& 0x3fffL
);
1004 * bits 1-2: MASK_HALF_CACHELINE
1006 * bit 4: INJECT_ADDR_PARITY
1009 injectmask
= (pvt
->inject
.type
& 1) |
1010 (pvt
->inject
.section
& 0x3) << 1 |
1011 (pvt
->inject
.type
& 0x6) << (3 - 1);
1013 /* Unlock writes to registers - this register is write only */
1014 pci_write_config_dword(pvt
->pci_noncore
[pvt
->inject
.socket
],
1015 MC_CFG_CONTROL
, 0x2);
1017 write_and_test(pvt
->pci_ch
[pvt
->inject
.socket
][pvt
->inject
.channel
][0],
1018 MC_CHANNEL_ADDR_MATCH
, mask
);
1019 write_and_test(pvt
->pci_ch
[pvt
->inject
.socket
][pvt
->inject
.channel
][0],
1020 MC_CHANNEL_ADDR_MATCH
+ 4, mask
>> 32L);
1022 write_and_test(pvt
->pci_ch
[pvt
->inject
.socket
][pvt
->inject
.channel
][0],
1023 MC_CHANNEL_ERROR_MASK
, pvt
->inject
.eccmask
);
1025 write_and_test(pvt
->pci_ch
[pvt
->inject
.socket
][pvt
->inject
.channel
][0],
1026 MC_CHANNEL_ERROR_INJECT
, injectmask
);
1029 * This is something undocumented, based on my tests
1030 * Without writing 8 to this register, errors aren't injected. Not sure
1033 pci_write_config_dword(pvt
->pci_noncore
[pvt
->inject
.socket
],
1036 debugf0("Error inject addr match 0x%016llx, ecc 0x%08x,"
1038 mask
, pvt
->inject
.eccmask
, injectmask
);
1044 static ssize_t
i7core_inject_enable_show(struct mem_ctl_info
*mci
,
1047 struct i7core_pvt
*pvt
= mci
->pvt_info
;
1050 pci_read_config_dword(pvt
->pci_ch
[pvt
->inject
.socket
][pvt
->inject
.channel
][0],
1051 MC_CHANNEL_ERROR_INJECT
, &injectmask
);
1053 debugf0("Inject error read: 0x%018x\n", injectmask
);
1055 if (injectmask
& 0x0c)
1056 pvt
->inject
.enable
= 1;
1058 return sprintf(data
, "%d\n", pvt
->inject
.enable
);
1061 static ssize_t
i7core_ce_regs_show(struct mem_ctl_info
*mci
, char *data
)
1063 unsigned i
, j
, count
, total
= 0;
1064 struct i7core_pvt
*pvt
= mci
->pvt_info
;
1066 for (i
= 0; i
< pvt
->sockets
; i
++) {
1067 if (!pvt
->ce_count_available
[i
]) {
1068 count
= sprintf(data
, "socket 0 data unavailable\n");
1071 if (!pvt
->is_registered
)
1072 count
= sprintf(data
, "socket %d, dimm0: %lu\n"
1073 "dimm1: %lu\ndimm2: %lu\n",
1075 pvt
->udimm_ce_count
[i
][0],
1076 pvt
->udimm_ce_count
[i
][1],
1077 pvt
->udimm_ce_count
[i
][2]);
1079 for (j
= 0; j
< NUM_CHANS
; j
++) {
1080 count
= sprintf(data
, "socket %d, channel %d"
1082 "dimm1: %lu\ndimm2: %lu\n",
1084 pvt
->rdimm_ce_count
[i
][j
][0],
1085 pvt
->rdimm_ce_count
[i
][j
][1],
1086 pvt
->rdimm_ce_count
[i
][j
][2]);
1098 static struct mcidev_sysfs_attribute i7core_inj_attrs
[] = {
1101 .name
= "inject_socket",
1102 .mode
= (S_IRUGO
| S_IWUSR
)
1104 .show
= i7core_inject_socket_show
,
1105 .store
= i7core_inject_socket_store
,
1108 .name
= "inject_section",
1109 .mode
= (S_IRUGO
| S_IWUSR
)
1111 .show
= i7core_inject_section_show
,
1112 .store
= i7core_inject_section_store
,
1115 .name
= "inject_type",
1116 .mode
= (S_IRUGO
| S_IWUSR
)
1118 .show
= i7core_inject_type_show
,
1119 .store
= i7core_inject_type_store
,
1122 .name
= "inject_eccmask",
1123 .mode
= (S_IRUGO
| S_IWUSR
)
1125 .show
= i7core_inject_eccmask_show
,
1126 .store
= i7core_inject_eccmask_store
,
1129 .name
= "inject_addrmatch",
1130 .mode
= (S_IRUGO
| S_IWUSR
)
1132 .show
= i7core_inject_addrmatch_show
,
1133 .store
= i7core_inject_addrmatch_store
,
1136 .name
= "inject_enable",
1137 .mode
= (S_IRUGO
| S_IWUSR
)
1139 .show
= i7core_inject_enable_show
,
1140 .store
= i7core_inject_enable_store
,
1143 .name
= "corrected_error_counts",
1144 .mode
= (S_IRUGO
| S_IWUSR
)
1146 .show
= i7core_ce_regs_show
,
1151 /****************************************************************************
1152 Device initialization routines: put/get, init/exit
1153 ****************************************************************************/
1156 * i7core_put_devices 'put' all the devices that we have
1157 * reserved via 'get'
1159 static void i7core_put_devices(void)
1163 for (i
= 0; i
< NUM_SOCKETS
; i
++)
1164 for (j
= 0; j
< N_DEVS
; j
++)
1165 pci_dev_put(pci_devs
[j
].pdev
[i
]);
1169 * i7core_get_devices Find and perform 'get' operation on the MCH's
1170 * device/functions we want to reference for this driver
1172 * Need to 'get' device 16 func 1 and func 2
1174 int i7core_get_onedevice(struct pci_dev
**prev
, int devno
)
1176 struct pci_dev
*pdev
= NULL
;
1180 pdev
= pci_get_device(PCI_VENDOR_ID_INTEL
,
1181 pci_devs
[devno
].dev_id
, *prev
);
1184 * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core pci buses
1185 * aren't announced by acpi. So, we need to use a legacy scan probing
1188 if (unlikely(!pdev
&& !devno
&& !prev
)) {
1189 pcibios_scan_specific_bus(254);
1190 pcibios_scan_specific_bus(255);
1192 pdev
= pci_get_device(PCI_VENDOR_ID_INTEL
,
1193 pci_devs
[devno
].dev_id
, *prev
);
1197 * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs
1198 * is at addr 8086:2c40, instead of 8086:2c41. So, we need
1199 * to probe for the alternate address in case of failure
1201 if (pci_devs
[devno
].dev_id
== PCI_DEVICE_ID_INTEL_I7_NOCORE
&& !pdev
)
1202 pdev
= pci_get_device(PCI_VENDOR_ID_INTEL
,
1203 PCI_DEVICE_ID_INTEL_I7_NOCORE_ALT
, *prev
);
1212 * Dev 3 function 2 only exists on chips with RDIMMs
1213 * so, it is ok to not found it
1215 if ((pci_devs
[devno
].dev
== 3) && (pci_devs
[devno
].func
== 2)) {
1220 i7core_printk(KERN_ERR
,
1221 "Device not found: dev %02x.%d PCI ID %04x:%04x\n",
1222 pci_devs
[devno
].dev
, pci_devs
[devno
].func
,
1223 PCI_VENDOR_ID_INTEL
, pci_devs
[devno
].dev_id
);
1225 /* End of list, leave */
1228 bus
= pdev
->bus
->number
;
1235 if (socket
>= NUM_SOCKETS
) {
1236 i7core_printk(KERN_ERR
,
1237 "Unexpected socket for "
1238 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1239 bus
, pci_devs
[devno
].dev
, pci_devs
[devno
].func
,
1240 PCI_VENDOR_ID_INTEL
, pci_devs
[devno
].dev_id
);
1245 if (pci_devs
[devno
].pdev
[socket
]) {
1246 i7core_printk(KERN_ERR
,
1247 "Duplicated device for "
1248 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1249 bus
, pci_devs
[devno
].dev
, pci_devs
[devno
].func
,
1250 PCI_VENDOR_ID_INTEL
, pci_devs
[devno
].dev_id
);
1255 pci_devs
[devno
].pdev
[socket
] = pdev
;
1258 if (unlikely(PCI_SLOT(pdev
->devfn
) != pci_devs
[devno
].dev
||
1259 PCI_FUNC(pdev
->devfn
) != pci_devs
[devno
].func
)) {
1260 i7core_printk(KERN_ERR
,
1261 "Device PCI ID %04x:%04x "
1262 "has dev %02x:%02x.%d instead of dev %02x:%02x.%d\n",
1263 PCI_VENDOR_ID_INTEL
, pci_devs
[devno
].dev_id
,
1264 bus
, PCI_SLOT(pdev
->devfn
), PCI_FUNC(pdev
->devfn
),
1265 bus
, pci_devs
[devno
].dev
, pci_devs
[devno
].func
);
1269 /* Be sure that the device is enabled */
1270 if (unlikely(pci_enable_device(pdev
) < 0)) {
1271 i7core_printk(KERN_ERR
,
1273 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1274 bus
, pci_devs
[devno
].dev
, pci_devs
[devno
].func
,
1275 PCI_VENDOR_ID_INTEL
, pci_devs
[devno
].dev_id
);
1279 i7core_printk(KERN_INFO
,
1280 "Registered socket %d "
1281 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1282 socket
, bus
, pci_devs
[devno
].dev
, pci_devs
[devno
].func
,
1283 PCI_VENDOR_ID_INTEL
, pci_devs
[devno
].dev_id
);
1290 static int i7core_get_devices(void)
1293 struct pci_dev
*pdev
= NULL
;
1295 for (i
= 0; i
< N_DEVS
; i
++) {
1298 if (i7core_get_onedevice(&pdev
, i
) < 0) {
1299 i7core_put_devices();
1307 static int mci_bind_devs(struct mem_ctl_info
*mci
)
1309 struct i7core_pvt
*pvt
= mci
->pvt_info
;
1310 struct pci_dev
*pdev
;
1311 int i
, j
, func
, slot
;
1313 for (i
= 0; i
< pvt
->sockets
; i
++) {
1314 for (j
= 0; j
< N_DEVS
; j
++) {
1315 pdev
= pci_devs
[j
].pdev
[i
];
1319 func
= PCI_FUNC(pdev
->devfn
);
1320 slot
= PCI_SLOT(pdev
->devfn
);
1322 if (unlikely(func
> MAX_MCR_FUNC
))
1324 pvt
->pci_mcr
[i
][func
] = pdev
;
1325 } else if (likely(slot
>= 4 && slot
< 4 + NUM_CHANS
)) {
1326 if (unlikely(func
> MAX_CHAN_FUNC
))
1328 pvt
->pci_ch
[i
][slot
- 4][func
] = pdev
;
1329 } else if (!slot
&& !func
)
1330 pvt
->pci_noncore
[i
] = pdev
;
1334 debugf0("Associated fn %d.%d, dev = %p, socket %d\n",
1335 PCI_SLOT(pdev
->devfn
), PCI_FUNC(pdev
->devfn
),
1343 i7core_printk(KERN_ERR
, "Device %d, function %d "
1344 "is out of the expected range\n",
1349 /****************************************************************************
1350 Error check routines
1351 ****************************************************************************/
1352 static void i7core_rdimm_update_csrow(struct mem_ctl_info
*mci
, int socket
,
1353 int chan
, int dimm
, int add
)
1356 struct i7core_pvt
*pvt
= mci
->pvt_info
;
1357 int row
= pvt
->csrow_map
[socket
][chan
][dimm
], i
;
1359 for (i
= 0; i
< add
; i
++) {
1360 msg
= kasprintf(GFP_KERNEL
, "Corrected error "
1361 "(Socket=%d channel=%d dimm=%d",
1362 socket
, chan
, dimm
);
1364 edac_mc_handle_fbd_ce(mci
, row
, 0, msg
);
1369 static void i7core_rdimm_update_ce_count(struct mem_ctl_info
*mci
,
1370 int socket
, int chan
, int new0
, int new1
, int new2
)
1372 struct i7core_pvt
*pvt
= mci
->pvt_info
;
1373 int add0
= 0, add1
= 0, add2
= 0;
1374 /* Updates CE counters if it is not the first time here */
1375 if (pvt
->ce_count_available
[socket
]) {
1376 /* Updates CE counters */
1378 add2
= new2
- pvt
->rdimm_last_ce_count
[socket
][chan
][2];
1379 add1
= new1
- pvt
->rdimm_last_ce_count
[socket
][chan
][1];
1380 add0
= new0
- pvt
->rdimm_last_ce_count
[socket
][chan
][0];
1384 pvt
->rdimm_ce_count
[socket
][chan
][2] += add2
;
1388 pvt
->rdimm_ce_count
[socket
][chan
][1] += add1
;
1392 pvt
->rdimm_ce_count
[socket
][chan
][0] += add0
;
1394 pvt
->ce_count_available
[socket
] = 1;
1396 /* Store the new values */
1397 pvt
->rdimm_last_ce_count
[socket
][chan
][2] = new2
;
1398 pvt
->rdimm_last_ce_count
[socket
][chan
][1] = new1
;
1399 pvt
->rdimm_last_ce_count
[socket
][chan
][0] = new0
;
1401 /*updated the edac core */
1403 i7core_rdimm_update_csrow(mci
, socket
, chan
, 0, add0
);
1405 i7core_rdimm_update_csrow(mci
, socket
, chan
, 1, add1
);
1407 i7core_rdimm_update_csrow(mci
, socket
, chan
, 2, add2
);
1411 static void i7core_rdimm_check_mc_ecc_err(struct mem_ctl_info
*mci
, u8 socket
)
1413 struct i7core_pvt
*pvt
= mci
->pvt_info
;
1415 int i
, new0
, new1
, new2
;
1417 /*Read DEV 3: FUN 2: MC_COR_ECC_CNT regs directly*/
1418 pci_read_config_dword(pvt
->pci_mcr
[socket
][2], MC_COR_ECC_CNT_0
,
1420 pci_read_config_dword(pvt
->pci_mcr
[socket
][2], MC_COR_ECC_CNT_1
,
1422 pci_read_config_dword(pvt
->pci_mcr
[socket
][2], MC_COR_ECC_CNT_2
,
1424 pci_read_config_dword(pvt
->pci_mcr
[socket
][2], MC_COR_ECC_CNT_3
,
1426 pci_read_config_dword(pvt
->pci_mcr
[socket
][2], MC_COR_ECC_CNT_4
,
1428 pci_read_config_dword(pvt
->pci_mcr
[socket
][2], MC_COR_ECC_CNT_5
,
1430 for (i
= 0 ; i
< 3; i
++) {
1431 debugf3("MC_COR_ECC_CNT%d = 0x%x; MC_COR_ECC_CNT%d = 0x%x\n",
1432 (i
* 2), rcv
[i
][0], (i
* 2) + 1, rcv
[i
][1]);
1433 /*if the channel has 3 dimms*/
1434 if (pvt
->channel
[socket
][i
].dimms
> 2) {
1435 new0
= DIMM_BOT_COR_ERR(rcv
[i
][0]);
1436 new1
= DIMM_TOP_COR_ERR(rcv
[i
][0]);
1437 new2
= DIMM_BOT_COR_ERR(rcv
[i
][1]);
1439 new0
= DIMM_TOP_COR_ERR(rcv
[i
][0]) +
1440 DIMM_BOT_COR_ERR(rcv
[i
][0]);
1441 new1
= DIMM_TOP_COR_ERR(rcv
[i
][1]) +
1442 DIMM_BOT_COR_ERR(rcv
[i
][1]);
1446 i7core_rdimm_update_ce_count(mci
, socket
, i
, new0
, new1
, new2
);
1450 /* This function is based on the device 3 function 4 registers as described on:
1451 * Intel Xeon Processor 5500 Series Datasheet Volume 2
1452 * http://www.intel.com/Assets/PDF/datasheet/321322.pdf
1453 * also available at:
1454 * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
1456 static void i7core_udimm_check_mc_ecc_err(struct mem_ctl_info
*mci
, u8 socket
)
1458 struct i7core_pvt
*pvt
= mci
->pvt_info
;
1460 int new0
, new1
, new2
;
1462 if (!pvt
->pci_mcr
[socket
][4]) {
1463 debugf0("%s MCR registers not found\n", __func__
);
1467 /* Corrected test errors */
1468 pci_read_config_dword(pvt
->pci_mcr
[socket
][4], MC_TEST_ERR_RCV1
, &rcv1
);
1469 pci_read_config_dword(pvt
->pci_mcr
[socket
][4], MC_TEST_ERR_RCV0
, &rcv0
);
1471 /* Store the new values */
1472 new2
= DIMM2_COR_ERR(rcv1
);
1473 new1
= DIMM1_COR_ERR(rcv0
);
1474 new0
= DIMM0_COR_ERR(rcv0
);
1476 /* Updates CE counters if it is not the first time here */
1477 if (pvt
->ce_count_available
[socket
]) {
1478 /* Updates CE counters */
1479 int add0
, add1
, add2
;
1481 add2
= new2
- pvt
->udimm_last_ce_count
[socket
][2];
1482 add1
= new1
- pvt
->udimm_last_ce_count
[socket
][1];
1483 add0
= new0
- pvt
->udimm_last_ce_count
[socket
][0];
1487 pvt
->udimm_ce_count
[socket
][2] += add2
;
1491 pvt
->udimm_ce_count
[socket
][1] += add1
;
1495 pvt
->udimm_ce_count
[socket
][0] += add0
;
1497 if (add0
| add1
| add2
)
1498 i7core_printk(KERN_ERR
, "New Corrected error(s): "
1499 "dimm0: +%d, dimm1: +%d, dimm2 +%d\n",
1502 pvt
->ce_count_available
[socket
] = 1;
1504 /* Store the new values */
1505 pvt
->udimm_last_ce_count
[socket
][2] = new2
;
1506 pvt
->udimm_last_ce_count
[socket
][1] = new1
;
1507 pvt
->udimm_last_ce_count
[socket
][0] = new0
;
1511 * According with tables E-11 and E-12 of chapter E.3.3 of Intel 64 and IA-32
1512 * Architectures Software Developer’s Manual Volume 3B.
1513 * Nehalem are defined as family 0x06, model 0x1a
1515 * The MCA registers used here are the following ones:
1516 * struct mce field MCA Register
1517 * m->status MSR_IA32_MC8_STATUS
1518 * m->addr MSR_IA32_MC8_ADDR
1519 * m->misc MSR_IA32_MC8_MISC
1520 * In the case of Nehalem, the error information is masked at .status and .misc
1523 static void i7core_mce_output_error(struct mem_ctl_info
*mci
,
1526 struct i7core_pvt
*pvt
= mci
->pvt_info
;
1527 char *type
, *optype
, *err
, *msg
;
1528 unsigned long error
= m
->status
& 0x1ff0000l
;
1529 u32 optypenum
= (m
->status
>> 4) & 0x07;
1530 u32 core_err_cnt
= (m
->status
>> 38) && 0x7fff;
1531 u32 dimm
= (m
->misc
>> 16) & 0x3;
1532 u32 channel
= (m
->misc
>> 18) & 0x3;
1533 u32 syndrome
= m
->misc
>> 32;
1534 u32 errnum
= find_first_bit(&error
, 32);
1537 if (m
->mcgstatus
& 1)
1542 switch (optypenum
) {
1544 optype
= "generic undef request";
1547 optype
= "read error";
1550 optype
= "write error";
1553 optype
= "addr/cmd error";
1556 optype
= "scrubbing error";
1559 optype
= "reserved";
1565 err
= "read ECC error";
1568 err
= "RAS ECC error";
1571 err
= "write parity error";
1574 err
= "redundacy loss";
1580 err
= "memory range error";
1583 err
= "RTID out of range";
1586 err
= "address parity error";
1589 err
= "byte enable parity error";
1595 /* FIXME: should convert addr into bank and rank information */
1596 msg
= kasprintf(GFP_ATOMIC
,
1597 "%s (addr = 0x%08llx, socket=%d, Dimm=%d, Channel=%d, "
1598 "syndrome=0x%08x, count=%d, Err=%08llx:%08llx (%s: %s))\n",
1599 type
, (long long) m
->addr
, m
->cpu
, dimm
, channel
,
1600 syndrome
, core_err_cnt
, (long long)m
->status
,
1601 (long long)m
->misc
, optype
, err
);
1605 csrow
= pvt
->csrow_map
[m
->cpu
][channel
][dimm
];
1607 /* Call the helper to output message */
1608 if (m
->mcgstatus
& 1)
1609 edac_mc_handle_fbd_ue(mci
, csrow
, 0,
1610 0 /* FIXME: should be channel here */, msg
);
1611 else if (!pvt
->is_registered
)
1612 edac_mc_handle_fbd_ce(mci
, csrow
,
1613 0 /* FIXME: should be channel here */, msg
);
1619 * i7core_check_error Retrieve and process errors reported by the
1620 * hardware. Called by the Core module.
1622 static void i7core_check_error(struct mem_ctl_info
*mci
)
1624 struct i7core_pvt
*pvt
= mci
->pvt_info
;
1627 struct mce
*m
= NULL
;
1628 unsigned long flags
;
1630 /* Copy all mce errors into a temporary buffer */
1631 spin_lock_irqsave(&pvt
->mce_lock
, flags
);
1632 if (pvt
->mce_count
) {
1633 m
= kmalloc(sizeof(*m
) * pvt
->mce_count
, GFP_ATOMIC
);
1635 count
= pvt
->mce_count
;
1636 memcpy(m
, &pvt
->mce_entry
, sizeof(*m
) * count
);
1640 spin_unlock_irqrestore(&pvt
->mce_lock
, flags
);
1642 /* proccess mcelog errors */
1643 for (i
= 0; i
< count
; i
++)
1644 i7core_mce_output_error(mci
, &m
[i
]);
1648 /* check memory count errors */
1649 for (i
= 0; i
< pvt
->sockets
; i
++)
1650 if (!pvt
->is_registered
)
1651 i7core_udimm_check_mc_ecc_err(mci
, i
);
1653 i7core_rdimm_check_mc_ecc_err(mci
, i
);
1657 * i7core_mce_check_error Replicates mcelog routine to get errors
1658 * This routine simply queues mcelog errors, and
1659 * return. The error itself should be handled later
1660 * by i7core_check_error.
1662 static int i7core_mce_check_error(void *priv
, struct mce
*mce
)
1664 struct mem_ctl_info
*mci
= priv
;
1665 struct i7core_pvt
*pvt
= mci
->pvt_info
;
1666 unsigned long flags
;
1669 * Just let mcelog handle it if the error is
1670 * outside the memory controller
1672 if (((mce
->status
& 0xffff) >> 7) != 1)
1675 /* Bank 8 registers are the only ones that we know how to handle */
1679 spin_lock_irqsave(&pvt
->mce_lock
, flags
);
1680 if (pvt
->mce_count
< MCE_LOG_LEN
) {
1681 memcpy(&pvt
->mce_entry
[pvt
->mce_count
], mce
, sizeof(*mce
));
1684 spin_unlock_irqrestore(&pvt
->mce_lock
, flags
);
1686 /* Handle fatal errors immediately */
1687 if (mce
->mcgstatus
& 1)
1688 i7core_check_error(mci
);
1690 /* Advice mcelog that the error were handled */
1695 * i7core_probe Probe for ONE instance of device to see if it is
1698 * 0 for FOUND a device
1699 * < 0 for error code
1701 static int __devinit
i7core_probe(struct pci_dev
*pdev
,
1702 const struct pci_device_id
*id
)
1704 struct mem_ctl_info
*mci
;
1705 struct i7core_pvt
*pvt
;
1706 int num_channels
= 0;
1709 int dev_idx
= id
->driver_data
;
1713 if (unlikely(dev_idx
>= ARRAY_SIZE(i7core_devs
)))
1716 /* get the pci devices we want to reserve for our use */
1717 rc
= i7core_get_devices();
1718 if (unlikely(rc
< 0))
1722 for (i
= NUM_SOCKETS
- 1; i
> 0; i
--)
1723 if (pci_devs
[0].pdev
[i
]) {
1728 for (i
= 0; i
< sockets
; i
++) {
1732 /* Check the number of active and not disabled channels */
1733 rc
= i7core_get_active_channels(i
, &channels
, &csrows
);
1734 if (unlikely(rc
< 0))
1737 num_channels
+= channels
;
1738 num_csrows
+= csrows
;
1741 /* allocate a new MC control structure */
1742 mci
= edac_mc_alloc(sizeof(*pvt
), num_csrows
, num_channels
, 0);
1743 if (unlikely(!mci
)) {
1748 debugf0("MC: " __FILE__
": %s(): mci = %p\n", __func__
, mci
);
1750 mci
->dev
= &pdev
->dev
; /* record ptr to the generic device */
1751 pvt
= mci
->pvt_info
;
1752 memset(pvt
, 0, sizeof(*pvt
));
1753 pvt
->sockets
= sockets
;
1757 * FIXME: how to handle RDDR3 at MCI level? It is possible to have
1758 * Mixed RDDR3/UDDR3 with Nehalem, provided that they are on different
1761 mci
->mtype_cap
= MEM_FLAG_DDR3
;
1762 mci
->edac_ctl_cap
= EDAC_FLAG_NONE
;
1763 mci
->edac_cap
= EDAC_FLAG_NONE
;
1764 mci
->mod_name
= "i7core_edac.c";
1765 mci
->mod_ver
= I7CORE_REVISION
;
1766 mci
->ctl_name
= i7core_devs
[dev_idx
].ctl_name
;
1767 mci
->dev_name
= pci_name(pdev
);
1768 mci
->ctl_page_to_phys
= NULL
;
1769 mci
->mc_driver_sysfs_attributes
= i7core_inj_attrs
;
1770 /* Set the function pointer to an actual operation function */
1771 mci
->edac_check
= i7core_check_error
;
1773 /* Store pci devices at mci for faster access */
1774 rc
= mci_bind_devs(mci
);
1775 if (unlikely(rc
< 0))
1778 /* Get dimm basic config */
1779 for (i
= 0; i
< sockets
; i
++)
1780 get_dimm_config(mci
, &csrow
, i
);
1782 /* add this new MC control structure to EDAC's list of MCs */
1783 if (unlikely(edac_mc_add_mc(mci
))) {
1784 debugf0("MC: " __FILE__
1785 ": %s(): failed edac_mc_add_mc()\n", __func__
);
1786 /* FIXME: perhaps some code should go here that disables error
1787 * reporting if we just enabled it
1794 /* allocating generic PCI control info */
1795 i7core_pci
= edac_pci_create_generic_ctl(&pdev
->dev
, EDAC_MOD_STR
);
1796 if (unlikely(!i7core_pci
)) {
1798 "%s(): Unable to create PCI control\n",
1801 "%s(): PCI error report via EDAC not setup\n",
1805 /* Default error mask is any memory */
1806 pvt
->inject
.channel
= 0;
1807 pvt
->inject
.dimm
= -1;
1808 pvt
->inject
.rank
= -1;
1809 pvt
->inject
.bank
= -1;
1810 pvt
->inject
.page
= -1;
1811 pvt
->inject
.col
= -1;
1813 /* Registers on edac_mce in order to receive memory errors */
1814 pvt
->edac_mce
.priv
= mci
;
1815 pvt
->edac_mce
.check_error
= i7core_mce_check_error
;
1816 spin_lock_init(&pvt
->mce_lock
);
1818 rc
= edac_mce_register(&pvt
->edac_mce
);
1819 if (unlikely(rc
< 0)) {
1820 debugf0("MC: " __FILE__
1821 ": %s(): failed edac_mce_register()\n", __func__
);
1825 i7core_printk(KERN_INFO
, "Driver loaded.\n");
1833 i7core_put_devices();
1838 * i7core_remove destructor for one instance of device
1841 static void __devexit
i7core_remove(struct pci_dev
*pdev
)
1843 struct mem_ctl_info
*mci
;
1844 struct i7core_pvt
*pvt
;
1846 debugf0(__FILE__
": %s()\n", __func__
);
1849 edac_pci_release_generic_ctl(i7core_pci
);
1852 mci
= edac_mc_del_mc(&pdev
->dev
);
1856 /* Unregisters on edac_mce in order to receive memory errors */
1857 pvt
= mci
->pvt_info
;
1858 edac_mce_unregister(&pvt
->edac_mce
);
1860 /* retrieve references to resources, and free those resources */
1861 i7core_put_devices();
1866 MODULE_DEVICE_TABLE(pci
, i7core_pci_tbl
);
1869 * i7core_driver pci_driver structure for this module
1872 static struct pci_driver i7core_driver
= {
1873 .name
= "i7core_edac",
1874 .probe
= i7core_probe
,
1875 .remove
= __devexit_p(i7core_remove
),
1876 .id_table
= i7core_pci_tbl
,
1880 * i7core_init Module entry function
1881 * Try to initialize this module for its devices
1883 static int __init
i7core_init(void)
1887 debugf2("MC: " __FILE__
": %s()\n", __func__
);
1889 /* Ensure that the OPSTATE is set correctly for POLL or NMI */
1892 pci_rc
= pci_register_driver(&i7core_driver
);
1897 i7core_printk(KERN_ERR
, "Failed to register device with error %d.\n",
1904 * i7core_exit() Module exit function
1905 * Unregister the driver
1907 static void __exit
i7core_exit(void)
1909 debugf2("MC: " __FILE__
": %s()\n", __func__
);
1910 pci_unregister_driver(&i7core_driver
);
1913 module_init(i7core_init
);
1914 module_exit(i7core_exit
);
1916 MODULE_LICENSE("GPL");
1917 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
1918 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
1919 MODULE_DESCRIPTION("MC Driver for Intel i7 Core memory controllers - "
1922 module_param(edac_op_state
, int, 0444);
1923 MODULE_PARM_DESC(edac_op_state
, "EDAC Error Reporting state: 0=Poll,1=NMI");