📄 pcibr_error.c
字号:
/* * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. */#include <linux/types.h>#include <linux/slab.h>#include <linux/module.h>#include <asm/sn/sgi.h>#include <asm/sn/sn_cpuid.h>#include <asm/sn/addrs.h>#include <asm/sn/arch.h>#include <asm/sn/iograph.h>#include <asm/sn/invent.h>#include <asm/sn/hcl.h>#include <asm/sn/labelcl.h>#include <asm/sn/xtalk/xwidget.h>#include <asm/sn/pci/bridge.h>#include <asm/sn/pci/pciio.h>#include <asm/sn/pci/pcibr.h>#include <asm/sn/pci/pcibr_private.h>#include <asm/sn/pci/pci_defs.h>#include <asm/sn/prio.h>#include <asm/sn/xtalk/xbow.h>#include <asm/sn/ioc3.h>#include <asm/sn/eeprom.h>#include <asm/sn/io.h>#include <asm/sn/sn_private.h>#ifdef __ia64#define rmallocmap atemapalloc#define rmfreemap atemapfree#define rmfree atefree#define rmalloc atealloc#endifextern int hubii_check_widget_disabled(nasid_t, int);#ifdef BRIDGE_B_DATACORR_WARextern int ql_bridge_rev_b_war(devfs_handle_t);extern int bridge_rev_b_data_check_disable;char *rev_b_datacorr_warning ="***************************** WARNING! ******************************\n";char *rev_b_datacorr_mesg ="UNRECOVERABLE IO LINK ERROR. CONTACT SERVICE PROVIDER\n";#endif/* ===================================================================== * ERROR HANDLING */#ifdef DEBUG#ifdef ERROR_DEBUG#define BRIDGE_PIOERR_TIMEOUT 100 /* Timeout with ERROR_DEBUG defined */#else#define BRIDGE_PIOERR_TIMEOUT 40 /* Timeout in debug mode */#endif#else#define BRIDGE_PIOERR_TIMEOUT 1 /* Timeout in non-debug mode */#endif/* PIC has 64bit interrupt error registers, but BRIDGE has 32bit registers. * Thus 'bridge_errors_to_dump needs' to default to the larger of the two. */#ifdef DEBUG#ifdef ERROR_DEBUGuint64_t bridge_errors_to_dump = ~BRIDGE_ISR_INT_MSK;#elseuint64_t bridge_errors_to_dump = BRIDGE_ISR_ERROR_DUMP;#endif#elseuint64_t bridge_errors_to_dump = BRIDGE_ISR_ERROR_FATAL | BRIDGE_ISR_PCIBUS_PIOERR;#endif#if defined (PCIBR_LLP_CONTROL_WAR)int pcibr_llp_control_war_cnt;#endif /* PCIBR_LLP_CONTROL_WAR *//* FIXME: can these arrays be local ? */struct reg_values xio_cmd_pactyp[] ={ {0x0, "RdReq"}, {0x1, "RdResp"}, {0x2, "WrReqWithResp"}, {0x3, "WrResp"}, {0x4, "WrReqNoResp"}, {0x5, "Reserved(5)"}, {0x6, "FetchAndOp"}, {0x7, "Reserved(7)"}, {0x8, "StoreAndOp"}, {0x9, "Reserved(9)"}, {0xa, "Reserved(a)"}, {0xb, "Reserved(b)"}, {0xc, "Reserved(c)"}, {0xd, "Reserved(d)"}, {0xe, "SpecialReq"}, {0xf, "SpecialResp"}, {0}};struct reg_desc xio_cmd_bits[] ={ {WIDGET_DIDN, -28, "DIDN", "%x"}, {WIDGET_SIDN, -24, "SIDN", "%x"}, {WIDGET_PACTYP, -20, "PACTYP", 0, xio_cmd_pactyp}, {WIDGET_TNUM, -15, "TNUM", "%x"}, {WIDGET_COHERENT, 0, "COHERENT"}, {WIDGET_DS, 0, "DS"}, {WIDGET_GBR, 0, "GBR"}, {WIDGET_VBPM, 0, "VBPM"}, {WIDGET_ERROR, 0, "ERROR"}, {WIDGET_BARRIER, 0, "BARRIER"}, {0}};#define F(s,n) { 1l<<(s),-(s), n }struct reg_desc bridge_int_status_desc[] ={ F(45, "PCI_X_SPLIT_MES_PE"),/* PIC ONLY */ F(44, "PCI_X_SPLIT_EMES"), /* PIC ONLY */ F(43, "PCI_X_SPLIT_TO"), /* PIC ONLY */ F(42, "PCI_X_UNEX_COMP"), /* PIC ONLY */ F(41, "INT_RAM_PERR"), /* PIC ONLY */ F(40, "PCI_X_ARB_ERR"), /* PIC ONLY */ F(39, "PCI_X_REQ_TOUT"), /* PIC ONLY */ F(38, "PCI_X_TABORT"), /* PIC ONLY */ F(37, "PCI_X_PERR"), /* PIC ONLY */ F(36, "PCI_X_SERR"), /* PIC ONLY */ F(35, "PCI_X_MRETRY"), /* PIC ONLY */ F(34, "PCI_X_MTOUT"), /* PIC ONLY */ F(33, "PCI_X_DA_PARITY"), /* PIC ONLY */ F(32, "PCI_X_AD_PARITY"), /* PIC ONLY */ F(31, "MULTI_ERR"), /* BRIDGE ONLY */ F(30, "PMU_ESIZE_EFAULT"), F(29, "UNEXPECTED_RESP"), F(28, "BAD_XRESP_PACKET"), F(27, "BAD_XREQ_PACKET"), F(26, "RESP_XTALK_ERROR"), F(25, "REQ_XTALK_ERROR"), F(24, "INVALID_ADDRESS"), F(23, "UNSUPPORTED_XOP"), F(22, "XREQ_FIFO_OFLOW"), F(21, "LLP_REC_SNERROR"), F(20, "LLP_REC_CBERROR"), F(19, "LLP_RCTY"), F(18, "LLP_TX_RETRY"), F(17, "LLP_TCTY"), F(16, "SSRAM_PERR"), /* BRIDGE ONLY */ F(15, "PCI_ABORT"), F(14, "PCI_PARITY"), F(13, "PCI_SERR"), F(12, "PCI_PERR"), F(11, "PCI_MASTER_TOUT"), F(10, "PCI_RETRY_CNT"), F(9, "XREAD_REQ_TOUT"), F(8, "GIO_BENABLE_ERR"), /* BRIDGE ONLY */ F(7, "INT7"), F(6, "INT6"), F(5, "INT5"), F(4, "INT4"), F(3, "INT3"), F(2, "INT2"), F(1, "INT1"), F(0, "INT0"), {0}};struct reg_values space_v[] ={ {PCIIO_SPACE_NONE, "none"}, {PCIIO_SPACE_ROM, "ROM"}, {PCIIO_SPACE_IO, "I/O"}, {PCIIO_SPACE_MEM, "MEM"}, {PCIIO_SPACE_MEM32, "MEM(32)"}, {PCIIO_SPACE_MEM64, "MEM(64)"}, {PCIIO_SPACE_CFG, "CFG"}, {PCIIO_SPACE_WIN(0), "WIN(0)"}, {PCIIO_SPACE_WIN(1), "WIN(1)"}, {PCIIO_SPACE_WIN(2), "WIN(2)"}, {PCIIO_SPACE_WIN(3), "WIN(3)"}, {PCIIO_SPACE_WIN(4), "WIN(4)"}, {PCIIO_SPACE_WIN(5), "WIN(5)"}, {PCIIO_SPACE_BAD, "BAD"}, {0}};struct reg_desc space_desc[] ={ {0xFF, 0, "space", 0, space_v}, {0}};#define device_desc device_bitsstruct reg_desc device_bits[] ={ {BRIDGE_DEV_ERR_LOCK_EN, 0, "ERR_LOCK_EN"}, {BRIDGE_DEV_PAGE_CHK_DIS, 0, "PAGE_CHK_DIS"}, {BRIDGE_DEV_FORCE_PCI_PAR, 0, "FORCE_PCI_PAR"}, {BRIDGE_DEV_VIRTUAL_EN, 0, "VIRTUAL_EN"}, {BRIDGE_DEV_PMU_WRGA_EN, 0, "PMU_WRGA_EN"}, {BRIDGE_DEV_DIR_WRGA_EN, 0, "DIR_WRGA_EN"}, {BRIDGE_DEV_DEV_SIZE, 0, "DEV_SIZE"}, {BRIDGE_DEV_RT, 0, "RT"}, {BRIDGE_DEV_SWAP_PMU, 0, "SWAP_PMU"}, {BRIDGE_DEV_SWAP_DIR, 0, "SWAP_DIR"}, {BRIDGE_DEV_PREF, 0, "PREF"}, {BRIDGE_DEV_PRECISE, 0, "PRECISE"}, {BRIDGE_DEV_COH, 0, "COH"}, {BRIDGE_DEV_BARRIER, 0, "BARRIER"}, {BRIDGE_DEV_GBR, 0, "GBR"}, {BRIDGE_DEV_DEV_SWAP, 0, "DEV_SWAP"}, {BRIDGE_DEV_DEV_IO_MEM, 0, "DEV_IO_MEM"}, {BRIDGE_DEV_OFF_MASK, BRIDGE_DEV_OFF_ADDR_SHFT, "DEV_OFF", "%x"}, {0}};voidprint_bridge_errcmd(uint32_t cmdword, char *errtype){ printk("\t Bridge %s Error Command Word Register ", errtype); print_register(cmdword, xio_cmd_bits);}char *pcibr_isr_errs[] ={ "", "", "", "", "", "", "", "", "08: GIO non-contiguous byte enable in crosstalk packet", /* BRIDGE ONLY */ "09: PCI to Crosstalk read request timeout", "10: PCI retry operation count exhausted.", "11: PCI bus device select timeout", "12: PCI device reported parity error", "13: PCI Address/Cmd parity error ", "14: PCI Bridge detected parity error", "15: PCI abort condition", "16: SSRAM parity error", /* BRIDGE ONLY */ "17: LLP Transmitter Retry count wrapped", "18: LLP Transmitter side required Retry", "19: LLP Receiver retry count wrapped", "20: LLP Receiver check bit error", "21: LLP Receiver sequence number error", "22: Request packet overflow", "23: Request operation not supported by bridge", "24: Request packet has invalid address for bridge widget", "25: Incoming request xtalk command word error bit set or invalid sideband", "26: Incoming response xtalk command word error bit set or invalid sideband", "27: Framing error, request cmd data size does not match actual", "28: Framing error, response cmd data size does not match actual", "29: Unexpected response arrived", "30: PMU Access Fault", "31: Multiple errors occurred", /* BRIDGE ONLY */ /* bits 32-45 are PIC ONLY */ "32: PCI-X address or attribute cycle parity error", "33: PCI-X data cycle parity error", "34: PCI-X master timeout (ie. master abort)", "35: PCI-X pio retry counter exhausted", "36: PCI-X SERR", "37: PCI-X PERR", "38: PCI-X target abort", "39: PCI-X read request timeout", "40: PCI / PCI-X device requestin arbitration error", "41: internal RAM parity error", "42: PCI-X unexpected completion cycle to master", "43: PCI-X split completion timeout", "44: PCI-X split completion error message", "45: PCI-X split completion message parity error",};#define BEM_ADD_STR(s) printk("%s", (s))#define BEM_ADD_VAR(v) printk("\t%20s: 0x%llx\n", #v, ((unsigned long long)v))#define BEM_ADD_REG(r) printk("\t%20s: ", #r); print_register((r), r ## _desc)#define BEM_ADD_NSPC(n,s) printk("\t%20s: ", n); print_register(s, space_desc)#define BEM_ADD_SPC(s) BEM_ADD_NSPC(#s, s)/* * display memory directory state */voidpcibr_show_dir_state(paddr_t paddr, char *prefix){#ifdef LATER int state; uint64_t vec_ptr; hubreg_t elo; extern char *dir_state_str[]; extern void get_dir_ent(paddr_t, int *, uint64_t *, hubreg_t *); get_dir_ent(paddr, &state, &vec_ptr, &elo); printk("%saddr 0x%lx: state 0x%x owner 0x%lx (%s)\n", prefix, paddr, state, vec_ptr, dir_state_str[state]);#endif}/* * Dump relevant error information for Bridge error interrupts. *//*ARGSUSED */voidpcibr_error_dump(pcibr_soft_t pcibr_soft){ bridge_t *bridge = pcibr_soft->bs_base; uint64_t int_status; bridgereg_t int_status_32; picreg_t int_status_64; uint64_t mult_int; bridgereg_t mult_int_32; picreg_t mult_int_64; uint64_t bit; int number_bits; int i; char *reg_desc; paddr_t addr = (paddr_t)0; /* We read the INT_STATUS register as a 64bit picreg_t for PIC and a * 32bit bridgereg_t for BRIDGE, but always process the result as a * 64bit value so the code can be "common" for both PIC and BRIDGE... */ if (IS_PIC_SOFT(pcibr_soft)) { int_status_64 = (bridge->p_int_status_64 & ~BRIDGE_ISR_INT_MSK); int_status = (uint64_t)int_status_64; number_bits = PCIBR_ISR_MAX_ERRS_PIC; } else { int_status_32 = (bridge->b_int_status & ~BRIDGE_ISR_INT_MSK); int_status = ((uint64_t)int_status_32) & 0xffffffff; number_bits = PCIBR_ISR_MAX_ERRS_BRIDGE; } if (!int_status) { /* No error bits set */ return; } /* Check if dumping the same error information multiple times */ if ( pcibr_soft->bs_errinfo.bserr_intstat == int_status ) return; pcibr_soft->bs_errinfo.bserr_intstat = int_status; printk(KERN_ALERT "PCI BRIDGE ERROR: int_status is 0x%lx for %s\n" " Dumping relevant %s registers for each bit set...\n", int_status, pcibr_soft->bs_name, (IS_PIC_SOFT(pcibr_soft) ? "PIC" : (IS_BRIDGE_SOFT(pcibr_soft) ? "BRIDGE" : "XBRIDGE"))); for (i = PCIBR_ISR_ERR_START; i < number_bits; i++) { bit = 1ull << i; /* * A number of int_status bits are only defined for Bridge. * Ignore them in the case of an XBridge or PIC. */ if ((IS_XBRIDGE_SOFT(pcibr_soft) || IS_PIC_SOFT(pcibr_soft)) && ((bit == BRIDGE_ISR_MULTI_ERR) || (bit == BRIDGE_ISR_SSRAM_PERR) || (bit == BRIDGE_ISR_GIO_B_ENBL_ERR))) { continue; } /* A number of int_status bits are only valid for PIC's bus0 */ if ((IS_PIC_SOFT(pcibr_soft) && (pcibr_soft->bs_busnum != 0)) && ((bit == BRIDGE_ISR_UNSUPPORTED_XOP) || (bit == BRIDGE_ISR_LLP_REC_SNERR) || (bit == BRIDGE_ISR_LLP_REC_CBERR) || (bit == BRIDGE_ISR_LLP_RCTY) || (bit == BRIDGE_ISR_LLP_TX_RETRY) || (bit == BRIDGE_ISR_LLP_TCTY))) { continue; } if (int_status & bit) { printk("\t%s\n", pcibr_isr_errs[i]); switch (bit) { case PIC_ISR_INT_RAM_PERR: /* bit41 INT_RAM_PERR */ /* XXX: should breakdown meaning of bits in reg */ printk( "\t Internal RAM Parity Error: 0x%lx\n", bridge->p_ate_parity_err_64); break; case PIC_ISR_PCIX_ARB_ERR: /* bit40 PCI_X_ARB_ERR */ /* XXX: should breakdown meaning of bits in reg */ printk( "\t Arbitration Reg: 0x%x\n", bridge->b_arb); break; case PIC_ISR_PCIX_REQ_TOUT: /* bit39 PCI_X_REQ_TOUT */ /* XXX: should breakdown meaning of attribute bit */ printk( "\t PCI-X DMA Request Error Address Reg: 0x%lx\n" "\t PCI-X DMA Request Error Attribute Reg: 0x%lx\n", bridge->p_pcix_dma_req_err_addr_64, bridge->p_pcix_dma_req_err_attr_64); break; case PIC_ISR_PCIX_SPLIT_MSG_PE: /* bit45 PCI_X_SPLIT_MES_PE */ case PIC_ISR_PCIX_SPLIT_EMSG: /* bit44 PCI_X_SPLIT_EMESS */ case PIC_ISR_PCIX_SPLIT_TO: /* bit43 PCI_X_SPLIT_TO */ /* XXX: should breakdown meaning of attribute bit */ printk( "\t PCI-X Split Request Address Reg: 0x%lx\n" "\t PCI-X Split Request Attribute Reg: 0x%lx\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -