/* * linux/arch/alpha/kernel/err_marvel.c * * Copyright (C) 2001 Jeff Wiedemeier (Compaq Computer Corporation) * */ #include #include #include #include #include #include #include #include #include #include #include "err_impl.h" #include "proto.h" static void marvel_print_680_frame(struct ev7_lf_subpackets *lf_subpackets) { #ifdef CONFIG_VERBOSE_MCHECK struct ev7_pal_environmental_subpacket *env; struct { int type; char *name; } ev_packets[] = { { EL_TYPE__PAL__ENV__AMBIENT_TEMPERATURE, "Ambient Temperature" }, { EL_TYPE__PAL__ENV__AIRMOVER_FAN, "AirMover / Fan" }, { EL_TYPE__PAL__ENV__VOLTAGE, "Voltage" }, { EL_TYPE__PAL__ENV__INTRUSION, "Intrusion" }, { EL_TYPE__PAL__ENV__POWER_SUPPLY, "Power Supply" }, { EL_TYPE__PAL__ENV__LAN, "LAN" }, { EL_TYPE__PAL__ENV__HOT_PLUG, "Hot Plug" }, { 0, NULL } }; int i; for (i = 0; ev_packets[i].type != 0; i++) { env = lf_subpackets->env[ev7_lf_env_index(ev_packets[i].type)]; if (!env) continue; printk("%s**%s event (cabinet %d, drawer %d)\n", err_print_prefix, ev_packets[i].name, env->cabinet, env->drawer); printk("%s Module Type: 0x%x - Unit ID 0x%x - " "Condition 0x%x\n", err_print_prefix, env->module_type, env->unit_id, env->condition); } #endif /* CONFIG_VERBOSE_MCHECK */ } static int marvel_process_680_frame(struct ev7_lf_subpackets *lf_subpackets, int print) { int status = MCHK_DISPOSITION_UNKNOWN_ERROR; int i; for (i = ev7_lf_env_index(EL_TYPE__PAL__ENV__AMBIENT_TEMPERATURE); i <= ev7_lf_env_index(EL_TYPE__PAL__ENV__HOT_PLUG); i++) { if (lf_subpackets->env[i]) status = MCHK_DISPOSITION_REPORT; } if (print) marvel_print_680_frame(lf_subpackets); return status; } #ifdef CONFIG_VERBOSE_MCHECK static void marvel_print_err_cyc(u64 err_cyc) { static char *packet_desc[] = { "No Error", "UNKNOWN", "1 cycle (1 or 2 flit packet)", "2 cycles (3 flit packet)", "9 cycles (18 flit packet)", "10 cycles (19 flit packet)", "UNKNOWN", "UNKNOWN", "UNKNOWN" }; #define IO7__ERR_CYC__ODD_FLT (1UL << 0) #define IO7__ERR_CYC__EVN_FLT (1UL << 1) #define IO7__ERR_CYC__PACKET__S (6) #define IO7__ERR_CYC__PACKET__M (0x7) #define IO7__ERR_CYC__LOC (1UL << 5) #define IO7__ERR_CYC__CYCLE__S (2) #define IO7__ERR_CYC__CYCLE__M (0x7) printk("%s Packet In Error: %s\n" "%s Error in %s, cycle %lld%s%s\n", err_print_prefix, packet_desc[EXTRACT(err_cyc, IO7__ERR_CYC__PACKET)], err_print_prefix, (err_cyc & IO7__ERR_CYC__LOC) ? "DATA" : "HEADER", EXTRACT(err_cyc, IO7__ERR_CYC__CYCLE), (err_cyc & IO7__ERR_CYC__ODD_FLT) ? " [ODD Flit]": "", (err_cyc & IO7__ERR_CYC__EVN_FLT) ? " [Even Flit]": ""); } static void marvel_print_po7_crrct_sym(u64 crrct_sym) { #define IO7__PO7_CRRCT_SYM__SYN__S (0) #define IO7__PO7_CRRCT_SYM__SYN__M (0x7f) #define IO7__PO7_CRRCT_SYM__ERR_CYC__S (7) /* ERR_CYC + ODD_FLT + EVN_FLT */ #define IO7__PO7_CRRCT_SYM__ERR_CYC__M (0x1ff) printk("%s Correctable Error Symptoms:\n" "%s Syndrome: 0x%llx\n", err_print_prefix, err_print_prefix, EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__SYN)); marvel_print_err_cyc(EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__ERR_CYC)); } static void marvel_print_po7_uncrr_sym(u64 uncrr_sym, u64 valid_mask) { static char *clk_names[] = { "_h[0]", "_h[1]", "_n[0]", "_n[1]" }; static char *clk_decode[] = { "No Error", "One extra rising edge", "Two extra rising edges", "Lost one clock" }; static char *port_names[] = { "Port 0", "Port 1", "Port 2", "Port 3", "Unknown Port", "Unknown Port", "Unknown Port", "Port 7" }; int scratch, i; #define IO7__PO7_UNCRR_SYM__SYN__S (0) #define IO7__PO7_UNCRR_SYM__SYN__M (0x7f) #define IO7__PO7_UNCRR_SYM__ERR_CYC__S (7) /* ERR_CYC + ODD_FLT... */ #define IO7__PO7_UNCRR_SYM__ERR_CYC__M (0x1ff) /* ... + EVN_FLT */ #define IO7__PO7_UNCRR_SYM__CLK__S (16) #define IO7__PO7_UNCRR_SYM__CLK__M (0xff) #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__REQ (1UL << 24) #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__RIO (1UL << 25) #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__WIO (1UL << 26) #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__BLK (1UL << 27) #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__NBK (1UL << 28) #define IO7__PO7_UNCRR_SYM__OVF__READIO (1UL << 29) #define IO7__PO7_UNCRR_SYM__OVF__WRITEIO (1UL << 30) #define IO7__PO7_UNCRR_SYM__OVF__FWD (1UL << 31) #define IO7__PO7_UNCRR_SYM__VICTIM_SP__S (32) #define IO7__PO7_UNCRR_SYM__VICTIM_SP__M (0xff) #define IO7__PO7_UNCRR_SYM__DETECT_SP__S (40) #define IO7__PO7_UNCRR_SYM__DETECT_SP__M (0xff) #define IO7__PO7_UNCRR_SYM__STRV_VTR__S (48) #define IO7__PO7_UNCRR_SYM__STRV_VTR__M (0x3ff) #define IO7__STRV_VTR__LSI__INTX__S (0) #define IO7__STRV_VTR__LSI__INTX__M (0x3) #define IO7__STRV_VTR__LSI__SLOT__S (2) #define IO7__STRV_VTR__LSI__SLOT__M (0x7) #define IO7__STRV_VTR__LSI__BUS__S (5) #define IO7__STRV_VTR__LSI__BUS__M (0x3) #define IO7__STRV_VTR__MSI__INTNUM__S (0) #define IO7__STRV_VTR__MSI__INTNUM__M (0x1ff) #define IO7__STRV_VTR__IS_MSI (1UL << 9) printk("%s Uncorrectable Error Symptoms:\n", err_print_prefix); uncrr_sym &= valid_mask; if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__SYN)) printk("%s Syndrome: 0x%llx\n", err_print_prefix, EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__SYN)); if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__ERR_CYC)) marvel_print_err_cyc(EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__ERR_CYC)); scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__CLK); for (i = 0; i < 4; i++, scratch >>= 2) { if (scratch & 0x3) printk("%s Clock %s: %s\n", err_print_prefix, clk_names[i], clk_decode[scratch & 0x3]); } if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__REQ) printk("%s REQ Credit Timeout or Overflow\n", err_print_prefix); if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__RIO) printk("%s RIO Credit Timeout or Overflow\n", err_print_prefix); if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__WIO) printk("%s WIO Credit Timeout or Overflow\n", err_print_prefix); if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__BLK) printk("%s BLK Credit Timeout or Overflow\n", err_print_prefix); if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__NBK) printk("%s NBK Credit Timeout or Overflow\n", err_print_prefix); if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__READIO) printk("%s Read I/O Buffer Overflow\n", err_print_prefix); if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__WRITEIO) printk("%s Write I/O Buffer Overflow\n", err_print_prefix); if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__FWD) printk("%s FWD Buffer Overflow\n", err_print_prefix); if ((scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__VICTIM_SP))) { int lost = scratch & (1UL << 4); scratch &= ~lost; for (i = 0; i < 8; i++, scratch >>= 1) { if (!(scratch & 1)) continue; printk("%s Error Response sent to %s", err_print_prefix, port_names[i]); } if (lost) printk("%s Lost Error sent somewhere else\n", err_print_prefix); } if ((scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__DETECT_SP))) { for (i = 0; i < 8; i++, scratch >>= 1) { if (!(scratch & 1)) continue; printk("%s Error Reported by %s", err_print_prefix, port_names[i]); } } if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__STRV_VTR)) { char starvation_message[80]; scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__STRV_VTR); if (scratch & IO7__STRV_VTR__IS_MSI) sprintf(starvation_message, "MSI Interrupt 0x%x", EXTRACT(scratch, IO7__STRV_VTR__MSI__INTNUM)); else sprintf(starvation_message, "LSI INT%c for Bus:Slot (%d:%d)\n", 'A' + EXTRACT(scratch, IO7__STRV_VTR__LSI__INTX), EXTRACT(scratch, IO7__STRV_VTR__LSI__BUS), EXTRACT(scratch, IO7__STRV_VTR__LSI__SLOT)); printk("%s Starvation Int Trigger By: %s\n", err_print_prefix, starvation_message); } } static void marvel_print_po7_ugbge_sym(u64 ugbge_sym) { char opcode_str[10]; #define IO7__PO7_UGBGE_SYM__UPH_PKT_OFF__S (6) #define IO7__PO7_UGBGE_SYM__UPH_PKT_OFF__M (0xfffffffful) #define IO7__PO7_UGBGE_SYM__UPH_OPCODE__S (40) #define IO7__PO7_UGBGE_SYM__UPH_OPCODE__M (0xff) #define IO7__PO7_UGBGE_SYM__UPH_SRC_PORT__S (48) #define IO7__PO7_UGBGE_SYM__UPH_SRC_PORT__M (0xf) #define IO7__PO7_UGBGE_SYM__UPH_DEST_PID__S (52) #define IO7__PO7_UGBGE_SYM__UPH_DEST_PID__M (0x7ff) #define IO7__PO7_UGBGE_SYM__VALID (1UL << 63) if (!(ugbge_sym & IO7__PO7_UGBGE_SYM__VALID)) return; switch(EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE)) { case 0x51: sprintf(opcode_str, "Wr32"); break; case 0x50: sprintf(opcode_str, "WrQW"); break; case 0x54: sprintf(opcode_str, "WrIPR"); break; case 0xD8: sprintf(opcode_str, "Victim"); break; case 0xC5: sprintf(opcode_str, "BlkIO"); break; default: sprintf(opcode_str, "0x%llx\n", EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE)); break; } printk("%s Up Hose Garbage Symptom:\n" "%s Source Port: %lld - Dest PID: %lld - OpCode: %s\n", err_print_prefix, err_print_prefix, EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_SRC_PORT), EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_DEST_PID), opcode_str); if (0xC5 != EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE)) printk("%s Packet Offset 0x%08llx\n", err_print_prefix, EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_PKT_OFF)); } static void marvel_print_po7_err_sum(struct ev7_pal_io_subpacket *io) { u64 uncrr_sym_valid = 0; #define IO7__PO7_ERRSUM__CR_SBE (1UL << 32) #define IO7__PO7_ERRSUM__CR_SBE2 (1UL << 33) #define IO7__PO7_ERRSUM__CR_PIO_WBYTE (1UL << 34) #define IO7__PO7_ERRSUM__CR_CSR_NXM (1UL << 35) #define IO7__PO7_ERRSUM__CR_RPID_ACV (1UL << 36) #define IO7__PO7_ERRSUM__CR_RSP_NXM (1UL << 37) #define IO7__PO7_ERRSUM__CR_ERR_RESP (1UL << 38) #define IO7__PO7_ERRSUM__CR_CLK_DERR (1UL << 39) #define IO7__PO7_ERRSUM__CR_DAT_DBE (1UL << 40) #define IO7__PO7_ERRSUM__CR_DAT_GRBG (1UL << 41) #define IO7__PO7_ERRSUM__MAF_TO (1UL << 42) #define IO7__PO7_ERRSUM__UGBGE (1UL << 43) #define IO7__PO7_ERRSUM__UN_MAF_LOST (1UL << 44) #define IO7__PO7_ERRSUM__UN_PKT_OVF (1UL << 45) #define IO7__PO7_ERRSUM__UN_CDT_OVF (1UL << 46)