e752x_edac.c
来自「linux 内核源代码」· C语言 代码 · 共 1,153 行 · 第 1/3 页
C
1,153 行
/* * Intel e752x Memory Controller kernel module * (C) 2004 Linux Networx (http://lnxi.com) * This file may be distributed under the terms of the * GNU General Public License. * * See "enum e752x_chips" below for supported chipsets * * Written by Tom Zimmerman * * Contributors: * Thayne Harbaugh at realmsys.com (?) * Wang Zhenyu at intel.com * Dave Jiang at mvista.com * * $Id: edac_e752x.c,v 1.5.2.11 2005/10/05 00:43:44 dsp_llnl Exp $ * */#include <linux/module.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/pci_ids.h>#include <linux/slab.h>#include <linux/edac.h>#include "edac_core.h"#define E752X_REVISION " Ver: 2.0.2 " __DATE__#define EDAC_MOD_STR "e752x_edac"static int force_function_unhide;static struct edac_pci_ctl_info *e752x_pci;#define e752x_printk(level, fmt, arg...) \ edac_printk(level, "e752x", fmt, ##arg)#define e752x_mc_printk(mci, level, fmt, arg...) \ edac_mc_chipset_printk(mci, level, "e752x", fmt, ##arg)#ifndef PCI_DEVICE_ID_INTEL_7520_0#define PCI_DEVICE_ID_INTEL_7520_0 0x3590#endif /* PCI_DEVICE_ID_INTEL_7520_0 */#ifndef PCI_DEVICE_ID_INTEL_7520_1_ERR#define PCI_DEVICE_ID_INTEL_7520_1_ERR 0x3591#endif /* PCI_DEVICE_ID_INTEL_7520_1_ERR */#ifndef PCI_DEVICE_ID_INTEL_7525_0#define PCI_DEVICE_ID_INTEL_7525_0 0x359E#endif /* PCI_DEVICE_ID_INTEL_7525_0 */#ifndef PCI_DEVICE_ID_INTEL_7525_1_ERR#define PCI_DEVICE_ID_INTEL_7525_1_ERR 0x3593#endif /* PCI_DEVICE_ID_INTEL_7525_1_ERR */#ifndef PCI_DEVICE_ID_INTEL_7320_0#define PCI_DEVICE_ID_INTEL_7320_0 0x3592#endif /* PCI_DEVICE_ID_INTEL_7320_0 */#ifndef PCI_DEVICE_ID_INTEL_7320_1_ERR#define PCI_DEVICE_ID_INTEL_7320_1_ERR 0x3593#endif /* PCI_DEVICE_ID_INTEL_7320_1_ERR */#define E752X_NR_CSROWS 8 /* number of csrows *//* E752X register addresses - device 0 function 0 */#define E752X_DRB 0x60 /* DRAM row boundary register (8b) */#define E752X_DRA 0x70 /* DRAM row attribute register (8b) */ /* * 31:30 Device width row 7 * 01=x8 10=x4 11=x8 DDR2 * 27:26 Device width row 6 * 23:22 Device width row 5 * 19:20 Device width row 4 * 15:14 Device width row 3 * 11:10 Device width row 2 * 7:6 Device width row 1 * 3:2 Device width row 0 */#define E752X_DRC 0x7C /* DRAM controller mode reg (32b) */ /* FIXME:IS THIS RIGHT? */ /* * 22 Number channels 0=1,1=2 * 19:18 DRB Granularity 32/64MB */#define E752X_DRM 0x80 /* Dimm mapping register */#define E752X_DDRCSR 0x9A /* DDR control and status reg (16b) */ /* * 14:12 1 single A, 2 single B, 3 dual */#define E752X_TOLM 0xC4 /* DRAM top of low memory reg (16b) */#define E752X_REMAPBASE 0xC6 /* DRAM remap base address reg (16b) */#define E752X_REMAPLIMIT 0xC8 /* DRAM remap limit address reg (16b) */#define E752X_REMAPOFFSET 0xCA /* DRAM remap limit offset reg (16b) *//* E752X register addresses - device 0 function 1 */#define E752X_FERR_GLOBAL 0x40 /* Global first error register (32b) */#define E752X_NERR_GLOBAL 0x44 /* Global next error register (32b) */#define E752X_HI_FERR 0x50 /* Hub interface first error reg (8b) */#define E752X_HI_NERR 0x52 /* Hub interface next error reg (8b) */#define E752X_HI_ERRMASK 0x54 /* Hub interface error mask reg (8b) */#define E752X_HI_SMICMD 0x5A /* Hub interface SMI command reg (8b) */#define E752X_SYSBUS_FERR 0x60 /* System buss first error reg (16b) */#define E752X_SYSBUS_NERR 0x62 /* System buss next error reg (16b) */#define E752X_SYSBUS_ERRMASK 0x64 /* System buss error mask reg (16b) */#define E752X_SYSBUS_SMICMD 0x6A /* System buss SMI command reg (16b) */#define E752X_BUF_FERR 0x70 /* Memory buffer first error reg (8b) */#define E752X_BUF_NERR 0x72 /* Memory buffer next error reg (8b) */#define E752X_BUF_ERRMASK 0x74 /* Memory buffer error mask reg (8b) */#define E752X_BUF_SMICMD 0x7A /* Memory buffer SMI command reg (8b) */#define E752X_DRAM_FERR 0x80 /* DRAM first error register (16b) */#define E752X_DRAM_NERR 0x82 /* DRAM next error register (16b) */#define E752X_DRAM_ERRMASK 0x84 /* DRAM error mask register (8b) */#define E752X_DRAM_SMICMD 0x8A /* DRAM SMI command register (8b) */#define E752X_DRAM_RETR_ADD 0xAC /* DRAM Retry address register (32b) */#define E752X_DRAM_SEC1_ADD 0xA0 /* DRAM first correctable memory */ /* error address register (32b) */ /* * 31 Reserved * 30:2 CE address (64 byte block 34:6) * 1 Reserved * 0 HiLoCS */#define E752X_DRAM_SEC2_ADD 0xC8 /* DRAM first correctable memory */ /* error address register (32b) */ /* * 31 Reserved * 30:2 CE address (64 byte block 34:6) * 1 Reserved * 0 HiLoCS */#define E752X_DRAM_DED_ADD 0xA4 /* DRAM first uncorrectable memory */ /* error address register (32b) */ /* * 31 Reserved * 30:2 CE address (64 byte block 34:6) * 1 Reserved * 0 HiLoCS */#define E752X_DRAM_SCRB_ADD 0xA8 /* DRAM first uncorrectable scrub memory */ /* error address register (32b) */ /* * 31 Reserved * 30:2 CE address (64 byte block 34:6) * 1 Reserved * 0 HiLoCS */#define E752X_DRAM_SEC1_SYNDROME 0xC4 /* DRAM first correctable memory */ /* error syndrome register (16b) */#define E752X_DRAM_SEC2_SYNDROME 0xC6 /* DRAM second correctable memory */ /* error syndrome register (16b) */#define E752X_DEVPRES1 0xF4 /* Device Present 1 register (8b) *//* ICH5R register addresses - device 30 function 0 */#define ICH5R_PCI_STAT 0x06 /* PCI status register (16b) */#define ICH5R_PCI_2ND_STAT 0x1E /* PCI status secondary reg (16b) */#define ICH5R_PCI_BRIDGE_CTL 0x3E /* PCI bridge control register (16b) */enum e752x_chips { E7520 = 0, E7525 = 1, E7320 = 2};struct e752x_pvt { struct pci_dev *bridge_ck; struct pci_dev *dev_d0f0; struct pci_dev *dev_d0f1; u32 tolm; u32 remapbase; u32 remaplimit; int mc_symmetric; u8 map[8]; int map_type; const struct e752x_dev_info *dev_info;};struct e752x_dev_info { u16 err_dev; u16 ctl_dev; const char *ctl_name;};struct e752x_error_info { u32 ferr_global; u32 nerr_global; u8 hi_ferr; u8 hi_nerr; u16 sysbus_ferr; u16 sysbus_nerr; u8 buf_ferr; u8 buf_nerr; u16 dram_ferr; u16 dram_nerr; u32 dram_sec1_add; u32 dram_sec2_add; u16 dram_sec1_syndrome; u16 dram_sec2_syndrome; u32 dram_ded_add; u32 dram_scrb_add; u32 dram_retr_add;};static const struct e752x_dev_info e752x_devs[] = { [E7520] = { .err_dev = PCI_DEVICE_ID_INTEL_7520_1_ERR, .ctl_dev = PCI_DEVICE_ID_INTEL_7520_0, .ctl_name = "E7520"}, [E7525] = { .err_dev = PCI_DEVICE_ID_INTEL_7525_1_ERR, .ctl_dev = PCI_DEVICE_ID_INTEL_7525_0, .ctl_name = "E7525"}, [E7320] = { .err_dev = PCI_DEVICE_ID_INTEL_7320_1_ERR, .ctl_dev = PCI_DEVICE_ID_INTEL_7320_0, .ctl_name = "E7320"},};static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci, unsigned long page){ u32 remap; struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info; debugf3("%s()\n", __func__); if (page < pvt->tolm) return page; if ((page >= 0x100000) && (page < pvt->remapbase)) return page; remap = (page - pvt->tolm) + pvt->remapbase; if (remap < pvt->remaplimit) return remap; e752x_printk(KERN_ERR, "Invalid page %lx - out of range\n", page); return pvt->tolm - 1;}static void do_process_ce(struct mem_ctl_info *mci, u16 error_one, u32 sec1_add, u16 sec1_syndrome){ u32 page; int row; int channel; int i; struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info; debugf3("%s()\n", __func__); /* convert the addr to 4k page */ page = sec1_add >> (PAGE_SHIFT - 4); /* FIXME - check for -1 */ if (pvt->mc_symmetric) { /* chip select are bits 14 & 13 */ row = ((page >> 1) & 3); e752x_printk(KERN_WARNING, "Test row %d Table %d %d %d %d %d %d %d %d\n", row, pvt->map[0], pvt->map[1], pvt->map[2], pvt->map[3], pvt->map[4], pvt->map[5], pvt->map[6], pvt->map[7]); /* test for channel remapping */ for (i = 0; i < 8; i++) { if (pvt->map[i] == row) break; } e752x_printk(KERN_WARNING, "Test computed row %d\n", i); if (i < 8) row = i; else e752x_mc_printk(mci, KERN_WARNING, "row %d not found in remap table\n", row); } else row = edac_mc_find_csrow_by_page(mci, page); /* 0 = channel A, 1 = channel B */ channel = !(error_one & 1); /* e752x mc reads 34:6 of the DRAM linear address */ edac_mc_handle_ce(mci, page, offset_in_page(sec1_add << 4), sec1_syndrome, row, channel, "e752x CE");}static inline void process_ce(struct mem_ctl_info *mci, u16 error_one, u32 sec1_add, u16 sec1_syndrome, int *error_found, int handle_error){ *error_found = 1; if (handle_error) do_process_ce(mci, error_one, sec1_add, sec1_syndrome);}static void do_process_ue(struct mem_ctl_info *mci, u16 error_one, u32 ded_add, u32 scrb_add){ u32 error_2b, block_page; int row; struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info; debugf3("%s()\n", __func__); if (error_one & 0x0202) { error_2b = ded_add; /* convert to 4k address */ block_page = error_2b >> (PAGE_SHIFT - 4); row = pvt->mc_symmetric ? /* chip select are bits 14 & 13 */ ((block_page >> 1) & 3) : edac_mc_find_csrow_by_page(mci, block_page); /* e752x mc reads 34:6 of the DRAM linear address */ edac_mc_handle_ue(mci, block_page, offset_in_page(error_2b << 4), row, "e752x UE from Read"); } if (error_one & 0x0404) { error_2b = scrb_add; /* convert to 4k address */ block_page = error_2b >> (PAGE_SHIFT - 4); row = pvt->mc_symmetric ? /* chip select are bits 14 & 13 */ ((block_page >> 1) & 3) : edac_mc_find_csrow_by_page(mci, block_page); /* e752x mc reads 34:6 of the DRAM linear address */ edac_mc_handle_ue(mci, block_page, offset_in_page(error_2b << 4), row, "e752x UE from Scruber"); }}static inline void process_ue(struct mem_ctl_info *mci, u16 error_one, u32 ded_add, u32 scrb_add, int *error_found, int handle_error){ *error_found = 1; if (handle_error) do_process_ue(mci, error_one, ded_add, scrb_add);}static inline void process_ue_no_info_wr(struct mem_ctl_info *mci, int *error_found, int handle_error){ *error_found = 1; if (!handle_error) return; debugf3("%s()\n", __func__); edac_mc_handle_ue_no_info(mci, "e752x UE log memory write");}static void do_process_ded_retry(struct mem_ctl_info *mci, u16 error, u32 retry_add){ u32 error_1b, page; int row; struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info; error_1b = retry_add; page = error_1b >> (PAGE_SHIFT - 4); /* convert the addr to 4k page */ row = pvt->mc_symmetric ? ((page >> 1) & 3) : /* chip select are bits 14 & 13 */ edac_mc_find_csrow_by_page(mci, page); e752x_mc_printk(mci, KERN_WARNING, "CE page 0x%lx, row %d : Memory read retry\n", (long unsigned int)page, row);}static inline void process_ded_retry(struct mem_ctl_info *mci, u16 error, u32 retry_add, int *error_found, int handle_error)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?