1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Machine check handling for Tsunami/Typhoon systems. 4 * Author: Magnus Lindholm <linmag7@gmail.com> 5 * Based on Titan error handling by Jeff Wiedemeier (Compaq). 6 * Register definitions: 21272 Hardware Reference Manual, revision 4.0. 7 */ 8 #include <linux/init.h> 9 #include <linux/pci.h> 10 #include <linux/sched.h> 11 #include <asm/io.h> 12 #include <asm/core_tsunami.h> 13 #include <asm/smp.h> 14 #include <asm/err_common.h> 15 #include <asm/irq_regs.h> 16 #include "err_impl.h" 17 #include "proto.h" 18 #include "pci_impl.h" 19 20 #define TSUNAMI_PERROR_ERRMASK 0xdffUL 21 #define TSUNAMI_PERROR_ECCMASK (perror_m_uecc | perror_m_cre) 22 #define TSUNAMI_PERROR_INV (1UL << 51) 23 #define TSUNAMI_MISC_NXM (1UL << 28) 24 25 static int 26 tsunami_frame_valid(struct el_common *header, size_t size) 27 { 28 return !((header->sys_offset | header->size) & 7) && 29 header->sys_offset >= sizeof(*header) && 30 header->sys_offset <= header->size && 31 size <= header->size - header->sys_offset; 32 } 33 34 static int 35 tsunami_parse_p_perror(int which, u64 perror, int print) 36 { 37 static const char * const errors[] = { 38 "Lost error", "SERR asserted", "PERR asserted", 39 "Delayed-completion retry timeout", "Invalid scatter-gather PTE", 40 "Address parity error", "Target abort", "Read data parity error", 41 "No DEVSEL (master abort)", NULL, 42 "Uncorrectable ECC error", "Correctable ECC error" 43 }; 44 static const char * const pci_cmd[] = { 45 "Interrupt acknowledge", "Special cycle", "I/O read", "I/O write", 46 "Reserved", "Reserved", "Memory read", "Memory write", 47 "Reserved", "Reserved", "Configuration read", "Configuration write", 48 "Memory read multiple", "Dual address cycle", 49 "Memory read line", "Memory write and invalidate" 50 }; 51 unsigned long addr; 52 unsigned int cmd; 53 int i; 54 55 if (!(perror & TSUNAMI_PERROR_ERRMASK)) 56 return MCHK_DISPOSITION_UNKNOWN_ERROR; 57 /* Do not import Titan's BIOS master-abort dismissal policy. */ 58 if (!print) 59 return MCHK_DISPOSITION_REPORT; 60 61 printk("%s Pchip %d PERROR: %016llx\n", err_print_prefix, which, perror); 62 for (i = 0; i < ARRAY_SIZE(errors); i++) 63 if ((perror & TSUNAMI_PERROR_ERRMASK & (1UL << i)) && errors[i]) 64 printk("%s %s\n", err_print_prefix, errors[i]); 65 66 /* 67 * INV invalidates SYN, CMD and ADDR. HRM 8.8.2.6 leaves command/address 68 * undefined whenever SERR is set, including with other error bits. 69 */ 70 if (perror & (TSUNAMI_PERROR_INV | perror_m_serr)) { 71 printk("%s Transaction information unavailable\n", err_print_prefix); 72 return MCHK_DISPOSITION_REPORT; 73 } 74 cmd = (perror & perror_m_cmd) >> 52; 75 /* 76 * Table 10-42 selects the ECC fields whenever CRE or UECC is set. 77 * The first error freezes PERROR (10.2.5.6); mixed error bits were 78 * detected together. Only LOST can be set afterwards. 79 */ 80 if (perror & TSUNAMI_PERROR_ECCMASK) { 81 const char *command = "Reserved"; 82 83 if (cmd == 0) 84 command = "DMA read"; 85 else if (cmd == 1) 86 command = "DMA RMW"; 87 else if (cmd == 3) 88 command = "SGTE read"; 89 addr = ((perror >> 19) & 0xffffffffUL) << 3; 90 printk("%s Command: %s (%x), syndrome: %02llx\n", 91 err_print_prefix, command, cmd, (perror & perror_m_syn) >> 56); 92 printk("%s System address: %lx\n", err_print_prefix, addr); 93 } else { 94 addr = ((perror >> 18) & 0x3fffffffUL) << 2; 95 /* SGE captures only PCI address bits <31:13> (8KB page). */ 96 if (perror & perror_m_sge) 97 addr &= ~0x1fffUL; 98 printk("%s Command: %s (%x), PCI address: %lx%s\n", 99 err_print_prefix, pci_cmd[cmd], cmd, addr, 100 (perror & perror_m_sge) ? " (8KB page)" : ""); 101 if (perror & (1UL << 17)) 102 printk("%s Monster window\n", err_print_prefix); 103 else if (perror & (1UL << 16)) 104 printk("%s DAC scatter-gather window 3\n", err_print_prefix); 105 } 106 return MCHK_DISPOSITION_REPORT; 107 } 108 109 /* SESF bits 0/1 identify PCI errors, bit 2 covers ECC on either Pchip/CPU. */ 110 static u64 111 tsunami_pchip_error(struct el_TSUNAMI_sysdata_mcheck *frame, int which) 112 { 113 u64 perror = which ? frame->p1_perror : frame->p0_perror; 114 115 if (frame->sesf & (1UL << which)) 116 return perror; 117 if ((frame->sesf & 4) && (perror & TSUNAMI_PERROR_ECCMASK)) 118 return perror; 119 return 0; 120 } 121 122 static struct el_TSUNAMI_sysdata_mcheck * 123 tsunami_system_frame(struct el_common *header) 124 { 125 if (!tsunami_frame_valid(header, sizeof(struct el_TSUNAMI_sysdata_mcheck))) 126 return NULL; 127 return (void *)header + header->sys_offset; 128 } 129 130 static int 131 tsunami_process_logout_frame(struct el_common *header, int print) 132 { 133 struct el_TSUNAMI_sysdata_mcheck *frame = tsunami_system_frame(header); 134 int status = MCHK_DISPOSITION_UNKNOWN_ERROR; 135 int i; 136 137 if (!frame) { 138 if (print) { 139 printk("%s Invalid Tsunami system frame; raw frame follows\n", 140 err_print_prefix); 141 mchk_dump_logout_frame_raw(header); 142 } 143 return MCHK_DISPOSITION_UNKNOWN_ERROR; 144 } 145 if (print) 146 printk("%s SESF: %016llx DIR: %016llx MISC: %016llx\n", 147 err_print_prefix, frame->sesf, frame->dir, frame->misc); 148 if (frame->misc & TSUNAMI_MISC_NXM) { 149 status = MCHK_DISPOSITION_REPORT; 150 if (print) 151 printk("%s Non-existent memory, NXS: %llu\n", 152 err_print_prefix, (frame->misc >> 29) & 7); 153 } 154 for (i = 0; i < 2; i++) 155 status |= tsunami_parse_p_perror(i, tsunami_pchip_error(frame, i), print); 156 return status; 157 } 158 159 struct tsunami_error_state { 160 u64 perror[2]; 161 u64 misc; 162 }; 163 164 static void 165 tsunami_ack_pchip(tsunami_pchip *pchip, u64 perror) 166 { 167 if (!(perror & TSUNAMI_PERROR_ERRMASK)) 168 return; 169 pchip->perror.csr = perror & TSUNAMI_PERROR_ERRMASK; 170 /* Complete the W1C write before releasing the logout frame. */ 171 mb(); 172 pchip->perror.csr; 173 } 174 175 static void 176 tsunami_clear_errors(struct tsunami_error_state *state) 177 { 178 bool pchip1 = TSUNAMI_cchip->csc.csr & (1UL << 14); 179 180 /* Preserve each chip's transaction and the NXM source before clearing. */ 181 state->perror[0] = TSUNAMI_pchip0->perror.csr; 182 state->perror[1] = pchip1 ? TSUNAMI_pchip1->perror.csr : 0; 183 state->misc = TSUNAMI_cchip->misc.csr; 184 185 /* 186 * Acknowledge both present Pchips: the saved frame may predate 187 * live errors. This can consume another chip's pending error 188 * with INV set before it reaches DRIR, losing its transaction 189 * details and subsequent system-error notification. 190 */ 191 tsunami_ack_pchip(TSUNAMI_pchip0, state->perror[0]); 192 /* Do not access the second Pchip on single-Pchip systems. */ 193 if (pchip1) 194 tsunami_ack_pchip(TSUNAMI_pchip1, state->perror[1]); 195 if (state->misc & TSUNAMI_MISC_NXM) { 196 /* Zero writes leave the other MISC fields unchanged. */ 197 TSUNAMI_cchip->misc.csr = TSUNAMI_MISC_NXM; 198 /* Complete the NXM acknowledgment before releasing the frame. */ 199 mb(); 200 TSUNAMI_cchip->misc.csr; 201 } 202 } 203 204 static void 205 tsunami_report_live_errors(struct tsunami_error_state *state, 206 struct el_TSUNAMI_sysdata_mcheck *frame) 207 { 208 int i; 209 210 /* PALcode's frame may predate these errors, or describe another chip. */ 211 for (i = 0; i < 2; i++) { 212 if (!(state->perror[i] & TSUNAMI_PERROR_ERRMASK) || 213 (frame && state->perror[i] == tsunami_pchip_error(frame, i))) 214 continue; 215 printk("%s Live Pchip status before acknowledgment:\n", err_print_prefix); 216 tsunami_parse_p_perror(i, state->perror[i], 1); 217 } 218 if ((state->misc & TSUNAMI_MISC_NXM) && 219 (!frame || ((state->misc ^ frame->misc) & (0xfUL << 28)))) 220 printk("%s Live MISC: %016llx, non-existent memory, NXS: %llu\n", 221 err_print_prefix, state->misc, (state->misc >> 29) & 7); 222 } 223 224 void 225 tsunami_machine_check(unsigned long vector, unsigned long la_ptr) 226 { 227 struct el_common *header = (void *)la_ptr; 228 struct el_TSUNAMI_sysdata_mcheck *frame = NULL; 229 struct tsunami_error_state live = {}; 230 char *saved_err_prefix = err_print_prefix; 231 bool show_regs = vector == SCB_Q_SYSMCHK; 232 233 /* Synchronize pending accesses before inspecting the chipset. */ 234 mb(); 235 mb(); 236 draina(); 237 /* CPU/event vectors must not consume a pending Pchip system error. */ 238 if (vector == SCB_Q_SYSMCHK || vector == SCB_Q_SYSERR) { 239 tsunami_clear_errors(&live); 240 frame = tsunami_system_frame(header); 241 } 242 243 #ifdef CONFIG_VERBOSE_MCHECK 244 show_regs |= alpha_verbose_mcheck != 0; 245 #endif 246 err_print_prefix = KERN_CRIT; 247 if (vector == SCB_Q_SYSMCHK || vector == SCB_Q_SYSERR) { 248 printk("%sSystem %s error (vector %lx, code %x) on CPU %d:\n", 249 err_print_prefix, vector == SCB_Q_SYSERR ? "correctable" : 250 "uncorrectable", vector, header->code, smp_processor_id()); 251 tsunami_process_logout_frame(header, 1); 252 if (show_regs) 253 dik_show_regs(get_irq_regs(), NULL); 254 tsunami_report_live_errors(&live, frame); 255 } else if (vector == SCB_Q_SYSEVENT) { 256 printk("%sTsunami environmental event (code %x): layout unknown\n", 257 err_print_prefix, header->code); 258 mchk_dump_logout_frame_raw(header); 259 } 260 err_print_prefix = saved_err_prefix; 261 262 if (vector != SCB_Q_SYSMCHK && vector != SCB_Q_SYSERR && 263 vector != SCB_Q_SYSEVENT) { 264 /* EV6 decoding also releases the logout frame. */ 265 ev6_machine_check(vector, la_ptr); 266 } else { 267 wrmces(0x7); 268 /* Complete acknowledgment before resuming. */ 269 mb(); 270 } 271 } 272