1 // SPDX-License-Identifier: GPL-2.0 1 2 /* 3 * ip28-berr.c: Bus error handling. 4 * 5 * Copyright (C) 2002, 2003 Ladislav Michl (la 6 * Copyright (C) 2005 Peter Fuerst (pf@net.alp 7 */ 8 9 #include <linux/init.h> 10 #include <linux/kernel.h> 11 #include <linux/mm.h> 12 #include <linux/sched.h> 13 #include <linux/sched/debug.h> 14 #include <linux/sched/signal.h> 15 #include <linux/seq_file.h> 16 17 #include <asm/addrspace.h> 18 #include <asm/traps.h> 19 #include <asm/branch.h> 20 #include <asm/irq_regs.h> 21 #include <asm/sgi/mc.h> 22 #include <asm/sgi/hpc3.h> 23 #include <asm/sgi/ioc.h> 24 #include <asm/sgi/ip22.h> 25 #include <asm/r4kcache.h> 26 #include <linux/uaccess.h> 27 #include <asm/bootinfo.h> 28 29 static unsigned int count_be_is_fixup; 30 static unsigned int count_be_handler; 31 static unsigned int count_be_interrupt; 32 static int debug_be_interrupt; 33 34 static unsigned int cpu_err_stat; /* Sta 35 static unsigned int gio_err_stat; /* Sta 36 static unsigned int cpu_err_addr; /* Err 37 static unsigned int gio_err_addr; /* Err 38 static unsigned int extio_stat; 39 static unsigned int hpc3_berr_stat; /* Bus 40 41 struct hpc3_stat { 42 unsigned long addr; 43 unsigned int ctrl; 44 unsigned int cbp; 45 unsigned int ndptr; 46 }; 47 48 static struct { 49 struct hpc3_stat pbdma[8]; 50 struct hpc3_stat scsi[2]; 51 struct hpc3_stat ethrx, ethtx; 52 } hpc3; 53 54 static struct { 55 unsigned long err_addr; 56 struct { 57 u32 lo; 58 u32 hi; 59 } tags[1][2], tagd[4][2], tagi[4][2]; 60 } cache_tags; 61 62 static inline void save_cache_tags(unsigned bu 63 { 64 unsigned long addr = CAC_BASE | busadd 65 int i; 66 cache_tags.err_addr = addr; 67 68 /* 69 * Starting with a bus-address, save s 70 * PA[23..18:7..6]) tags first. 71 */ 72 addr &= ~1L; 73 #define tag cache_tags.tags[0] 74 cache_op(Index_Load_Tag_S, addr); 75 tag[0].lo = read_c0_taglo(); /* PA[ 76 tag[0].hi = read_c0_taghi(); /* PA[ 77 cache_op(Index_Load_Tag_S, addr | 1L); 78 tag[1].lo = read_c0_taglo(); /* PA[ 79 tag[1].hi = read_c0_taghi(); /* PA[ 80 #undef tag 81 82 /* 83 * Save all primary data cache (indexe 84 * might fit to this bus-address, know 85 * Saving all tags and evaluating them 86 * than relying on VA[13:12] from the 87 * matching primary tags here already. 88 */ 89 addr &= (0xffL << 56) | ((1 << 12) - 1 90 #define tag cache_tags.tagd[i] 91 for (i = 0; i < 4; ++i, addr += (1 << 92 cache_op(Index_Load_Tag_D, add 93 tag[0].lo = read_c0_taglo(); 94 tag[0].hi = read_c0_taghi(); 95 cache_op(Index_Load_Tag_D, add 96 tag[1].lo = read_c0_taglo(); 97 tag[1].hi = read_c0_taghi(); 98 } 99 #undef tag 100 101 /* 102 * Save primary instruction cache (ind 103 * the same way. 104 */ 105 addr &= (0xffL << 56) | ((1 << 12) - 1 106 #define tag cache_tags.tagi[i] 107 for (i = 0; i < 4; ++i, addr += (1 << 108 cache_op(Index_Load_Tag_I, add 109 tag[0].lo = read_c0_taglo(); 110 tag[0].hi = read_c0_taghi(); 111 cache_op(Index_Load_Tag_I, add 112 tag[1].lo = read_c0_taglo(); 113 tag[1].hi = read_c0_taghi(); 114 } 115 #undef tag 116 } 117 118 #define GIO_ERRMASK 0xff00 119 #define CPU_ERRMASK 0x3f00 120 121 static void save_and_clear_buserr(void) 122 { 123 int i; 124 125 /* save status registers */ 126 cpu_err_addr = sgimc->cerr; 127 cpu_err_stat = sgimc->cstat; 128 gio_err_addr = sgimc->gerr; 129 gio_err_stat = sgimc->gstat; 130 extio_stat = sgioc->extio; 131 hpc3_berr_stat = hpc3c0->bestat; 132 133 hpc3.scsi[0].addr = (unsigned long)&h 134 hpc3.scsi[0].ctrl = hpc3c0->scsi_chan 135 hpc3.scsi[0].cbp = hpc3c0->scsi_chan 136 hpc3.scsi[0].ndptr = hpc3c0->scsi_chan 137 138 hpc3.scsi[1].addr = (unsigned long)&h 139 hpc3.scsi[1].ctrl = hpc3c0->scsi_chan 140 hpc3.scsi[1].cbp = hpc3c0->scsi_chan 141 hpc3.scsi[1].ndptr = hpc3c0->scsi_chan 142 143 hpc3.ethrx.addr = (unsigned long)&hpc 144 hpc3.ethrx.ctrl = hpc3c0->ethregs.rx_ 145 hpc3.ethrx.cbp = hpc3c0->ethregs.rx_ 146 hpc3.ethrx.ndptr = hpc3c0->ethregs.rx_ 147 148 hpc3.ethtx.addr = (unsigned long)&hpc 149 hpc3.ethtx.ctrl = hpc3c0->ethregs.tx_ 150 hpc3.ethtx.cbp = hpc3c0->ethregs.tx_ 151 hpc3.ethtx.ndptr = hpc3c0->ethregs.tx_ 152 153 for (i = 0; i < 8; ++i) { 154 /* HPC3_PDMACTRL_ISACT ? */ 155 hpc3.pbdma[i].addr = (unsigne 156 hpc3.pbdma[i].ctrl = hpc3c0-> 157 hpc3.pbdma[i].cbp = hpc3c0-> 158 hpc3.pbdma[i].ndptr = hpc3c0-> 159 } 160 i = 0; 161 if (gio_err_stat & CPU_ERRMASK) 162 i = gio_err_addr; 163 if (cpu_err_stat & CPU_ERRMASK) 164 i = cpu_err_addr; 165 save_cache_tags(i); 166 167 sgimc->cstat = sgimc->gstat = 0; 168 } 169 170 static void print_cache_tags(void) 171 { 172 u32 scb, scw; 173 int i; 174 175 printk(KERN_ERR "Cache tags @ %08x:\n" 176 177 /* PA[31:12] shifted to PTag0 (PA[35:1 178 scw = (cache_tags.err_addr >> 4) & 0x0 179 180 scb = cache_tags.err_addr & ((1 << 12) 181 for (i = 0; i < 4; ++i) { /* for each 182 if ((cache_tags.tagd[i][0].lo 183 (cache_tags.tagd[i][1].lo 184 continue; 185 printk(KERN_ERR 186 "D: 0: %08x %08x, 1: %0 187 cache_tags.tagd[i][0]. 188 cache_tags.tagd[i][1]. 189 scb | (1 << 12)*i); 190 } 191 scb = cache_tags.err_addr & ((1 << 12) 192 for (i = 0; i < 4; ++i) { /* for each 193 if ((cache_tags.tagi[i][0].lo 194 (cache_tags.tagi[i][1].lo 195 continue; 196 printk(KERN_ERR 197 "I: 0: %08x %08x, 1: %0 198 cache_tags.tagi[i][0]. 199 cache_tags.tagi[i][1]. 200 scb | (1 << 12)*i); 201 } 202 i = read_c0_config(); 203 scb = i & (1 << 13) ? 7:6; /* scb 204 scw = ((i >> 16) & 7) + 19 - 1; /* scw 205 206 i = ((1 << scw) - 1) & ~((1 << scb) - 207 printk(KERN_ERR "S: 0: %08x %08x, 1: % 208 cache_tags.tags[0][0].hi, cach 209 cache_tags.tags[0][1].hi, cach 210 scw-1, scb, i & (unsigned)cach 211 } 212 213 static inline const char *cause_excode_text(in 214 { 215 static const char *txt[32] = 216 { "Interrupt", 217 "TLB modification", 218 "TLB (load or instruction fetc 219 "TLB (store)", 220 "Address error (load or instru 221 "Address error (store)", 222 "Bus error (instruction fetch) 223 "Bus error (data: load or stor 224 "Syscall", 225 "Breakpoint", 226 "Reserved instruction", 227 "Coprocessor unusable", 228 "Arithmetic Overflow", 229 "Trap", 230 "14", 231 "Floating-Point", 232 "16", "17", "18", "19", "20", 233 "Watch Hi/Lo", 234 "24", "25", "26", "27", "28", 235 }; 236 return txt[(cause & 0x7c) >> 2]; 237 } 238 239 static void print_buserr(const struct pt_regs 240 { 241 const int field = 2 * sizeof(unsigned 242 int error = 0; 243 244 if (extio_stat & EXTIO_MC_BUSERR) { 245 printk(KERN_ERR "MC Bus Error\ 246 error |= 1; 247 } 248 if (extio_stat & EXTIO_HPC3_BUSERR) { 249 printk(KERN_ERR "HPC3 Bus Erro 250 hpc3_berr_stat, 251 (hpc3_berr_stat & HPC3 252 HPC3 253 (hpc3_berr_stat & HPC3 254 hpc3_berr_stat & HPC3_ 255 error |= 2; 256 } 257 if (extio_stat & EXTIO_EISA_BUSERR) { 258 printk(KERN_ERR "EISA Bus Erro 259 error |= 4; 260 } 261 if (cpu_err_stat & CPU_ERRMASK) { 262 printk(KERN_ERR "CPU error 0x% 263 cpu_err_stat, 264 cpu_err_stat & SGIMC_C 265 cpu_err_stat & SGIMC_C 266 cpu_err_stat & SGIMC_C 267 cpu_err_stat & SGIMC_C 268 cpu_err_stat & SGIMC_C 269 cpu_err_stat & SGIMC_C 270 cpu_err_addr); 271 error |= 8; 272 } 273 if (gio_err_stat & GIO_ERRMASK) { 274 printk(KERN_ERR "GIO error 0x% 275 gio_err_stat, 276 gio_err_stat & SGIMC_G 277 gio_err_stat & SGIMC_G 278 gio_err_stat & SGIMC_G 279 gio_err_stat & SGIMC_G 280 gio_err_stat & SGIMC_G 281 gio_err_stat & SGIMC_G 282 gio_err_stat & SGIMC_G 283 gio_err_stat & SGIMC_G 284 gio_err_addr); 285 error |= 16; 286 } 287 if (!error) 288 printk(KERN_ERR "MC: Hmm, didn 289 else { 290 printk(KERN_ERR "CP0: config % 291 "MC: cpuctrl0/1: %08x/ 292 "MC: cpu/gio_memacc: % 293 read_c0_config(), 294 sgimc->cpuctrl0, sgimc 295 sgimc->cmacc, sgimc->g 296 sgimc->mconfig0, sgimc 297 print_cache_tags(); 298 } 299 printk(KERN_ALERT "%s, epc == %0*lx, r 300 cause_excode_text(regs->cp0_cau 301 field, regs->cp0_epc, field, re 302 } 303 304 static int check_microtlb(u32 hi, u32 lo, unsi 305 { 306 /* This is likely rather similar to co 307 308 vaddr &= 0x7fffffff; /* Doc. states th 309 310 /* If tlb-entry is valid and VPN-high 311 if ((lo & 2) && (vaddr >> 21) == ((hi< 312 u32 ctl = sgimc->dma_ctrl; 313 if (ctl & 1) { 314 unsigned int pgsz = (c 315 /* PTEIndex is VPN-low 316 unsigned long pte = (l 317 pte += 8*((vaddr >> pg 318 if (page_is_ram(PFN_DO 319 /* 320 * Note: Since 321 * translation 322 * match the T 323 */ 324 unsigned long 325 326 a = (a & 0x3f) 327 a += vaddr & ( 328 return cpu_err 329 } 330 } 331 } 332 return 0; 333 } 334 335 static int check_vdma_memaddr(void) 336 { 337 if (cpu_err_stat & CPU_ERRMASK) { 338 u32 a = sgimc->maddronly; 339 340 if (!(sgimc->dma_ctrl & 0x100) 341 return cpu_err_addr == 342 343 if (check_microtlb(sgimc->dtlb 344 check_microtlb(sgimc->dtlb 345 check_microtlb(sgimc->dtlb 346 check_microtlb(sgimc->dtlb 347 return 1; 348 } 349 return 0; 350 } 351 352 static int check_vdma_gioaddr(void) 353 { 354 if (gio_err_stat & GIO_ERRMASK) { 355 u32 a = sgimc->gio_dma_trans; 356 a = (sgimc->gmaddronly & ~a) | 357 return gio_err_addr == a; 358 } 359 return 0; 360 } 361 362 /* 363 * MC sends an interrupt whenever bus or parit 364 * if the error happened during a CPU read, it 365 * pin on the R4K. Code in bus error handler s 366 * and then clear the interrupt when this happ 367 */ 368 369 static int ip28_be_interrupt(const struct pt_r 370 { 371 int i; 372 373 save_and_clear_buserr(); 374 /* 375 * Try to find out, whether we got her 376 * load/store operation. If so, it's 377 */ 378 /* Any cause other than "Interrupt" (E 379 if (regs->cp0_cause & CAUSEF_EXCCODE) 380 goto mips_be_fatal; 381 382 /* Any cause other than "Bus error int 383 if ((regs->cp0_cause & CAUSEF_IP6) != 384 goto mips_be_fatal; 385 386 if (extio_stat & (EXTIO_HPC3_BUSERR | 387 goto mips_be_fatal; 388 389 /* Any state other than "Memory bus er 390 if (cpu_err_stat & CPU_ERRMASK & ~SGIM 391 goto mips_be_fatal; 392 393 /* GIO errors other than timeouts are 394 if (gio_err_stat & GIO_ERRMASK & ~SGIM 395 goto mips_be_fatal; 396 397 /* 398 * Now we have an asynchronous bus err 399 * Need to search all DMA descriptors 400 */ 401 for (i = 0; i < sizeof(hpc3)/sizeof(st 402 struct hpc3_stat *hp = (struct 403 if ((cpu_err_stat & CPU_ERRMAS 404 (cpu_err_addr == hp->ndptr 405 break; 406 if ((gio_err_stat & GIO_ERRMAS 407 (gio_err_addr == hp->ndptr 408 break; 409 } 410 if (i < sizeof(hpc3)/sizeof(struct hpc 411 struct hpc3_stat *hp = (struct 412 printk(KERN_ERR "at DMA addres 413 " ctl %08x, ndp %08x, c 414 CPHYSADDR(hp->addr), hp 415 goto mips_be_fatal; 416 } 417 /* Check MC's virtual DMA stuff. */ 418 if (check_vdma_memaddr()) { 419 printk(KERN_ERR "at GIO DMA: m 420 sgimc->maddronly); 421 goto mips_be_fatal; 422 } 423 if (check_vdma_gioaddr()) { 424 printk(KERN_ERR "at GIO DMA: g 425 sgimc->gmaddronly); 426 goto mips_be_fatal; 427 } 428 /* A speculative bus error... */ 429 if (debug_be_interrupt) { 430 print_buserr(regs); 431 printk(KERN_ERR "discarded!\n" 432 } 433 return MIPS_BE_DISCARD; 434 435 mips_be_fatal: 436 print_buserr(regs); 437 return MIPS_BE_FATAL; 438 } 439 440 void ip22_be_interrupt(int irq) 441 { 442 struct pt_regs *regs = get_irq_regs(); 443 444 count_be_interrupt++; 445 446 if (ip28_be_interrupt(regs) != MIPS_BE 447 /* Assume it would be too dang 448 die_if_kernel("Oops", regs); 449 force_sig(SIGBUS); 450 } else if (debug_be_interrupt) 451 show_regs(regs); 452 } 453 454 static int ip28_be_handler(struct pt_regs *reg 455 { 456 /* 457 * We arrive here only in the unusual 458 * i.e. by a bus error exception witho 459 */ 460 if (is_fixup) { 461 count_be_is_fixup++; 462 save_and_clear_buserr(); 463 return MIPS_BE_FIXUP; 464 } 465 count_be_handler++; 466 return ip28_be_interrupt(regs); 467 } 468 469 void __init ip22_be_init(void) 470 { 471 mips_set_be_handler(ip28_be_handler); 472 } 473 474 int ip28_show_be_info(struct seq_file *m) 475 { 476 seq_printf(m, "IP28 be fixups\t\t: %u\ 477 seq_printf(m, "IP28 be interrupts\t: % 478 seq_printf(m, "IP28 be handler\t\t: %u 479 480 return 0; 481 } 482 483 static int __init debug_be_setup(char *str) 484 { 485 debug_be_interrupt++; 486 return 1; 487 } 488 __setup("ip28_debug_be", debug_be_setup); 489
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.