24 #include <linux/module.h>
27 #include <linux/pci.h>
34 #define I82443_REVISION "0.1"
36 #define EDAC_MOD_STR "i82443bxgx_edac"
59 #define I82443BXGX_NR_CSROWS 8
60 #define I82443BXGX_NR_CHANS 1
61 #define I82443BXGX_NR_DIMMS 4
64 #define I82443BXGX_NBXCFG 0x50
66 #define I82443BXGX_NBXCFG_OFFSET_NON_ECCROW 24
68 #define I82443BXGX_NBXCFG_OFFSET_DRAM_FREQ 12
70 #define I82443BXGX_NBXCFG_OFFSET_DRAM_INTEGRITY 7
71 #define I82443BXGX_NBXCFG_INTEGRITY_NONE 0x0
72 #define I82443BXGX_NBXCFG_INTEGRITY_EC 0x1
73 #define I82443BXGX_NBXCFG_INTEGRITY_ECC 0x2
74 #define I82443BXGX_NBXCFG_INTEGRITY_SCRUB 0x3
76 #define I82443BXGX_NBXCFG_OFFSET_ECC_DIAG_ENABLE 6
79 #define I82443BXGX_EAP 0x80
82 #define I82443BXGX_EAP_OFFSET_EAP 12
83 #define I82443BXGX_EAP_OFFSET_MBE BIT(1)
84 #define I82443BXGX_EAP_OFFSET_SBE BIT(0)
86 #define I82443BXGX_ERRCMD 0x90
88 #define I82443BXGX_ERRCMD_OFFSET_SERR_ON_MBE BIT(1)
89 #define I82443BXGX_ERRCMD_OFFSET_SERR_ON_SBE BIT(0)
91 #define I82443BXGX_ERRSTS 0x91
93 #define I82443BXGX_ERRSTS_OFFSET_MBFRE 5
94 #define I82443BXGX_ERRSTS_OFFSET_MEF BIT(4)
95 #define I82443BXGX_ERRSTS_OFFSET_SBFRE 1
96 #define I82443BXGX_ERRSTS_OFFSET_SEF BIT(0)
98 #define I82443BXGX_DRAMC 0x57
100 #define I82443BXGX_DRAMC_OFFSET_DT 3
101 #define I82443BXGX_DRAMC_DRAM_IS_EDO 0
102 #define I82443BXGX_DRAMC_DRAM_IS_SDRAM 1
103 #define I82443BXGX_DRAMC_DRAM_IS_RSDRAM 2
105 #define I82443BXGX_DRB 0x60
114 static struct edac_pci_ctl_info *i82443bxgx_pci;
116 static struct pci_dev *mci_pdev;
120 static int i82443bxgx_registered = 1;
142 static int i82443bxgx_edacmc_process_error_info(
struct mem_ctl_info *mci,
145 *info,
int handle_errors)
152 eapaddr = (info->
eap & 0xfffff000);
177 static void i82443bxgx_edacmc_check(
struct mem_ctl_info *mci)
182 i82443bxgx_edacmc_get_error_info(mci, &info);
183 i82443bxgx_edacmc_process_error_info(mci, &info, 1);
186 static void i82443bxgx_init_csrows(
struct mem_ctl_info *mci,
195 u32 row_base, row_high_limit, row_high_limit_last;
198 row_high_limit_last = 0;
199 for (index = 0; index < mci->
nr_csrows; index++) {
204 edac_dbg(1,
"MC%d: Row=%d DRB = %#0x\n",
205 mci->
mc_idx, index, drbar);
206 row_high_limit = ((
u32) drbar << 23);
208 edac_dbg(1,
"MC%d: Row=%d, Boundary Address=%#0x, Last = %#0x\n",
209 mci->
mc_idx, index, row_high_limit,
210 row_high_limit_last);
213 if (row_high_limit_last && !row_high_limit)
214 row_high_limit = 1
UL << 31;
217 if (row_high_limit == row_high_limit_last)
219 row_base = row_high_limit_last;
224 dimm->
grain = 1 << 12;
230 row_high_limit_last = row_high_limit;
234 static int i82443bxgx_edacmc_probe1(
struct pci_dev *pdev,
int dev_idx)
239 u32 nbxcfg, ecc_mode;
253 layers[0].is_virt_csrow =
true;
256 layers[1].is_virt_csrow =
false;
277 edac_dbg(0,
"Unknown/reserved DRAM type value in DRAMC register!\n");
306 edac_dbg(0,
"Unknown/reserved ECC state in NBXCFG register!\n");
311 i82443bxgx_init_csrows(mci, pdev, edac_mode, mtype);
330 edac_dbg(3,
"failed edac_mc_add_mc()\n");
336 if (!i82443bxgx_pci) {
338 "%s(): Unable to create PCI control\n",
341 "%s(): PCI error report via EDAC not setup\n",
364 rc = i82443bxgx_edacmc_probe1(pdev, ent->
driver_data);
366 if (mci_pdev ==
NULL)
399 static struct pci_driver i82443bxgx_edacmc_driver = {
401 .probe = i82443bxgx_edacmc_init_one,
402 .remove =
__devexit_p(i82443bxgx_edacmc_remove_one),
403 .id_table = i82443bxgx_pci_tbl,
406 static int __init i82443bxgx_edacmc_init(
void)
412 pci_rc = pci_register_driver(&i82443bxgx_edacmc_driver);
416 if (mci_pdev ==
NULL) {
419 i82443bxgx_registered = 0;
425 id = &i82443bxgx_pci_tbl[
i];
428 edac_dbg(0,
"i82443bxgx pci_get_device fail\n");
433 pci_rc = i82443bxgx_edacmc_init_one(mci_pdev, i82443bxgx_pci_tbl);
436 edac_dbg(0,
"i82443bxgx init fail\n");
448 if (mci_pdev !=
NULL)
454 static void __exit i82443bxgx_edacmc_exit(
void)
458 if (!i82443bxgx_registered)
459 i82443bxgx_edacmc_remove_one(mci_pdev);