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 + -
显示快捷键?