0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/init.h>
0010 #include <linux/kernel.h>
0011 #include <linux/mm.h>
0012 #include <linux/sched.h>
0013 #include <linux/sched/debug.h>
0014 #include <linux/sched/signal.h>
0015 #include <linux/seq_file.h>
0016
0017 #include <asm/addrspace.h>
0018 #include <asm/traps.h>
0019 #include <asm/branch.h>
0020 #include <asm/irq_regs.h>
0021 #include <asm/sgi/mc.h>
0022 #include <asm/sgi/hpc3.h>
0023 #include <asm/sgi/ioc.h>
0024 #include <asm/sgi/ip22.h>
0025 #include <asm/r4kcache.h>
0026 #include <linux/uaccess.h>
0027 #include <asm/bootinfo.h>
0028
0029 static unsigned int count_be_is_fixup;
0030 static unsigned int count_be_handler;
0031 static unsigned int count_be_interrupt;
0032 static int debug_be_interrupt;
0033
0034 static unsigned int cpu_err_stat;
0035 static unsigned int gio_err_stat;
0036 static unsigned int cpu_err_addr;
0037 static unsigned int gio_err_addr;
0038 static unsigned int extio_stat;
0039 static unsigned int hpc3_berr_stat;
0040
0041 struct hpc3_stat {
0042 unsigned long addr;
0043 unsigned int ctrl;
0044 unsigned int cbp;
0045 unsigned int ndptr;
0046 };
0047
0048 static struct {
0049 struct hpc3_stat pbdma[8];
0050 struct hpc3_stat scsi[2];
0051 struct hpc3_stat ethrx, ethtx;
0052 } hpc3;
0053
0054 static struct {
0055 unsigned long err_addr;
0056 struct {
0057 u32 lo;
0058 u32 hi;
0059 } tags[1][2], tagd[4][2], tagi[4][2];
0060 } cache_tags;
0061
0062 static inline void save_cache_tags(unsigned busaddr)
0063 {
0064 unsigned long addr = CAC_BASE | busaddr;
0065 int i;
0066 cache_tags.err_addr = addr;
0067
0068
0069
0070
0071
0072 addr &= ~1L;
0073 #define tag cache_tags.tags[0]
0074 cache_op(Index_Load_Tag_S, addr);
0075 tag[0].lo = read_c0_taglo();
0076 tag[0].hi = read_c0_taghi();
0077 cache_op(Index_Load_Tag_S, addr | 1L);
0078 tag[1].lo = read_c0_taglo();
0079 tag[1].hi = read_c0_taghi();
0080 #undef tag
0081
0082
0083
0084
0085
0086
0087
0088
0089 addr &= (0xffL << 56) | ((1 << 12) - 1);
0090 #define tag cache_tags.tagd[i]
0091 for (i = 0; i < 4; ++i, addr += (1 << 12)) {
0092 cache_op(Index_Load_Tag_D, addr);
0093 tag[0].lo = read_c0_taglo();
0094 tag[0].hi = read_c0_taghi();
0095 cache_op(Index_Load_Tag_D, addr | 1L);
0096 tag[1].lo = read_c0_taglo();
0097 tag[1].hi = read_c0_taghi();
0098 }
0099 #undef tag
0100
0101
0102
0103
0104
0105 addr &= (0xffL << 56) | ((1 << 12) - 1);
0106 #define tag cache_tags.tagi[i]
0107 for (i = 0; i < 4; ++i, addr += (1 << 12)) {
0108 cache_op(Index_Load_Tag_I, addr);
0109 tag[0].lo = read_c0_taglo();
0110 tag[0].hi = read_c0_taghi();
0111 cache_op(Index_Load_Tag_I, addr | 1L);
0112 tag[1].lo = read_c0_taglo();
0113 tag[1].hi = read_c0_taghi();
0114 }
0115 #undef tag
0116 }
0117
0118 #define GIO_ERRMASK 0xff00
0119 #define CPU_ERRMASK 0x3f00
0120
0121 static void save_and_clear_buserr(void)
0122 {
0123 int i;
0124
0125
0126 cpu_err_addr = sgimc->cerr;
0127 cpu_err_stat = sgimc->cstat;
0128 gio_err_addr = sgimc->gerr;
0129 gio_err_stat = sgimc->gstat;
0130 extio_stat = sgioc->extio;
0131 hpc3_berr_stat = hpc3c0->bestat;
0132
0133 hpc3.scsi[0].addr = (unsigned long)&hpc3c0->scsi_chan0;
0134 hpc3.scsi[0].ctrl = hpc3c0->scsi_chan0.ctrl;
0135 hpc3.scsi[0].cbp = hpc3c0->scsi_chan0.cbptr;
0136 hpc3.scsi[0].ndptr = hpc3c0->scsi_chan0.ndptr;
0137
0138 hpc3.scsi[1].addr = (unsigned long)&hpc3c0->scsi_chan1;
0139 hpc3.scsi[1].ctrl = hpc3c0->scsi_chan1.ctrl;
0140 hpc3.scsi[1].cbp = hpc3c0->scsi_chan1.cbptr;
0141 hpc3.scsi[1].ndptr = hpc3c0->scsi_chan1.ndptr;
0142
0143 hpc3.ethrx.addr = (unsigned long)&hpc3c0->ethregs.rx_cbptr;
0144 hpc3.ethrx.ctrl = hpc3c0->ethregs.rx_ctrl;
0145 hpc3.ethrx.cbp = hpc3c0->ethregs.rx_cbptr;
0146 hpc3.ethrx.ndptr = hpc3c0->ethregs.rx_ndptr;
0147
0148 hpc3.ethtx.addr = (unsigned long)&hpc3c0->ethregs.tx_cbptr;
0149 hpc3.ethtx.ctrl = hpc3c0->ethregs.tx_ctrl;
0150 hpc3.ethtx.cbp = hpc3c0->ethregs.tx_cbptr;
0151 hpc3.ethtx.ndptr = hpc3c0->ethregs.tx_ndptr;
0152
0153 for (i = 0; i < 8; ++i) {
0154
0155 hpc3.pbdma[i].addr = (unsigned long)&hpc3c0->pbdma[i];
0156 hpc3.pbdma[i].ctrl = hpc3c0->pbdma[i].pbdma_ctrl;
0157 hpc3.pbdma[i].cbp = hpc3c0->pbdma[i].pbdma_bptr;
0158 hpc3.pbdma[i].ndptr = hpc3c0->pbdma[i].pbdma_dptr;
0159 }
0160 i = 0;
0161 if (gio_err_stat & CPU_ERRMASK)
0162 i = gio_err_addr;
0163 if (cpu_err_stat & CPU_ERRMASK)
0164 i = cpu_err_addr;
0165 save_cache_tags(i);
0166
0167 sgimc->cstat = sgimc->gstat = 0;
0168 }
0169
0170 static void print_cache_tags(void)
0171 {
0172 u32 scb, scw;
0173 int i;
0174
0175 printk(KERN_ERR "Cache tags @ %08x:\n", (unsigned)cache_tags.err_addr);
0176
0177
0178 scw = (cache_tags.err_addr >> 4) & 0x0fffff00;
0179
0180 scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 5) - 1);
0181 for (i = 0; i < 4; ++i) {
0182 if ((cache_tags.tagd[i][0].lo & 0x0fffff00) != scw &&
0183 (cache_tags.tagd[i][1].lo & 0x0fffff00) != scw)
0184 continue;
0185 printk(KERN_ERR
0186 "D: 0: %08x %08x, 1: %08x %08x (VA[13:5] %04x)\n",
0187 cache_tags.tagd[i][0].hi, cache_tags.tagd[i][0].lo,
0188 cache_tags.tagd[i][1].hi, cache_tags.tagd[i][1].lo,
0189 scb | (1 << 12)*i);
0190 }
0191 scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 6) - 1);
0192 for (i = 0; i < 4; ++i) {
0193 if ((cache_tags.tagi[i][0].lo & 0x0fffff00) != scw &&
0194 (cache_tags.tagi[i][1].lo & 0x0fffff00) != scw)
0195 continue;
0196 printk(KERN_ERR
0197 "I: 0: %08x %08x, 1: %08x %08x (VA[13:6] %04x)\n",
0198 cache_tags.tagi[i][0].hi, cache_tags.tagi[i][0].lo,
0199 cache_tags.tagi[i][1].hi, cache_tags.tagi[i][1].lo,
0200 scb | (1 << 12)*i);
0201 }
0202 i = read_c0_config();
0203 scb = i & (1 << 13) ? 7:6;
0204 scw = ((i >> 16) & 7) + 19 - 1;
0205
0206 i = ((1 << scw) - 1) & ~((1 << scb) - 1);
0207 printk(KERN_ERR "S: 0: %08x %08x, 1: %08x %08x (PA[%u:%u] %05x)\n",
0208 cache_tags.tags[0][0].hi, cache_tags.tags[0][0].lo,
0209 cache_tags.tags[0][1].hi, cache_tags.tags[0][1].lo,
0210 scw-1, scb, i & (unsigned)cache_tags.err_addr);
0211 }
0212
0213 static inline const char *cause_excode_text(int cause)
0214 {
0215 static const char *txt[32] =
0216 { "Interrupt",
0217 "TLB modification",
0218 "TLB (load or instruction fetch)",
0219 "TLB (store)",
0220 "Address error (load or instruction fetch)",
0221 "Address error (store)",
0222 "Bus error (instruction fetch)",
0223 "Bus error (data: load or store)",
0224 "Syscall",
0225 "Breakpoint",
0226 "Reserved instruction",
0227 "Coprocessor unusable",
0228 "Arithmetic Overflow",
0229 "Trap",
0230 "14",
0231 "Floating-Point",
0232 "16", "17", "18", "19", "20", "21", "22",
0233 "Watch Hi/Lo",
0234 "24", "25", "26", "27", "28", "29", "30", "31",
0235 };
0236 return txt[(cause & 0x7c) >> 2];
0237 }
0238
0239 static void print_buserr(const struct pt_regs *regs)
0240 {
0241 const int field = 2 * sizeof(unsigned long);
0242 int error = 0;
0243
0244 if (extio_stat & EXTIO_MC_BUSERR) {
0245 printk(KERN_ERR "MC Bus Error\n");
0246 error |= 1;
0247 }
0248 if (extio_stat & EXTIO_HPC3_BUSERR) {
0249 printk(KERN_ERR "HPC3 Bus Error 0x%x:<id=0x%x,%s,lane=0x%x>\n",
0250 hpc3_berr_stat,
0251 (hpc3_berr_stat & HPC3_BESTAT_PIDMASK) >>
0252 HPC3_BESTAT_PIDSHIFT,
0253 (hpc3_berr_stat & HPC3_BESTAT_CTYPE) ? "PIO" : "DMA",
0254 hpc3_berr_stat & HPC3_BESTAT_BLMASK);
0255 error |= 2;
0256 }
0257 if (extio_stat & EXTIO_EISA_BUSERR) {
0258 printk(KERN_ERR "EISA Bus Error\n");
0259 error |= 4;
0260 }
0261 if (cpu_err_stat & CPU_ERRMASK) {
0262 printk(KERN_ERR "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n",
0263 cpu_err_stat,
0264 cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "",
0265 cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "",
0266 cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "",
0267 cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "",
0268 cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "",
0269 cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "",
0270 cpu_err_addr);
0271 error |= 8;
0272 }
0273 if (gio_err_stat & GIO_ERRMASK) {
0274 printk(KERN_ERR "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x%08x\n",
0275 gio_err_stat,
0276 gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "",
0277 gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "",
0278 gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "",
0279 gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "",
0280 gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "",
0281 gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "",
0282 gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "",
0283 gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "",
0284 gio_err_addr);
0285 error |= 16;
0286 }
0287 if (!error)
0288 printk(KERN_ERR "MC: Hmm, didn't find any error condition.\n");
0289 else {
0290 printk(KERN_ERR "CP0: config %08x, "
0291 "MC: cpuctrl0/1: %08x/%05x, giopar: %04x\n"
0292 "MC: cpu/gio_memacc: %08x/%05x, memcfg0/1: %08x/%08x\n",
0293 read_c0_config(),
0294 sgimc->cpuctrl0, sgimc->cpuctrl0, sgimc->giopar,
0295 sgimc->cmacc, sgimc->gmacc,
0296 sgimc->mconfig0, sgimc->mconfig1);
0297 print_cache_tags();
0298 }
0299 printk(KERN_ALERT "%s, epc == %0*lx, ra == %0*lx\n",
0300 cause_excode_text(regs->cp0_cause),
0301 field, regs->cp0_epc, field, regs->regs[31]);
0302 }
0303
0304 static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr)
0305 {
0306
0307
0308 vaddr &= 0x7fffffff;
0309
0310
0311 if ((lo & 2) && (vaddr >> 21) == ((hi<<1) >> 22)) {
0312 u32 ctl = sgimc->dma_ctrl;
0313 if (ctl & 1) {
0314 unsigned int pgsz = (ctl & 2) ? 14:12;
0315
0316 unsigned long pte = (lo >> 6) << 12;
0317 pte += 8*((vaddr >> pgsz) & 0x1ff);
0318 if (page_is_ram(PFN_DOWN(pte))) {
0319
0320
0321
0322
0323
0324 unsigned long a = *(unsigned long *)
0325 PHYS_TO_XKSEG_UNCACHED(pte);
0326 a = (a & 0x3f) << 6;
0327 a += vaddr & ((1 << pgsz) - 1);
0328 return cpu_err_addr == a;
0329 }
0330 }
0331 }
0332 return 0;
0333 }
0334
0335 static int check_vdma_memaddr(void)
0336 {
0337 if (cpu_err_stat & CPU_ERRMASK) {
0338 u32 a = sgimc->maddronly;
0339
0340 if (!(sgimc->dma_ctrl & 0x100))
0341 return cpu_err_addr == a;
0342
0343 if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) ||
0344 check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) ||
0345 check_microtlb(sgimc->dtlb_hi2, sgimc->dtlb_lo2, a) ||
0346 check_microtlb(sgimc->dtlb_hi3, sgimc->dtlb_lo3, a))
0347 return 1;
0348 }
0349 return 0;
0350 }
0351
0352 static int check_vdma_gioaddr(void)
0353 {
0354 if (gio_err_stat & GIO_ERRMASK) {
0355 u32 a = sgimc->gio_dma_trans;
0356 a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a);
0357 return gio_err_addr == a;
0358 }
0359 return 0;
0360 }
0361
0362
0363
0364
0365
0366
0367
0368
0369 static int ip28_be_interrupt(const struct pt_regs *regs)
0370 {
0371 int i;
0372
0373 save_and_clear_buserr();
0374
0375
0376
0377
0378
0379 if (regs->cp0_cause & CAUSEF_EXCCODE)
0380 goto mips_be_fatal;
0381
0382
0383 if ((regs->cp0_cause & CAUSEF_IP6) != CAUSEF_IP6)
0384 goto mips_be_fatal;
0385
0386 if (extio_stat & (EXTIO_HPC3_BUSERR | EXTIO_EISA_BUSERR))
0387 goto mips_be_fatal;
0388
0389
0390 if (cpu_err_stat & CPU_ERRMASK & ~SGIMC_CSTAT_ADDR)
0391 goto mips_be_fatal;
0392
0393
0394 if (gio_err_stat & GIO_ERRMASK & ~SGIMC_GSTAT_TIME)
0395 goto mips_be_fatal;
0396
0397
0398
0399
0400
0401 for (i = 0; i < sizeof(hpc3)/sizeof(struct hpc3_stat); ++i) {
0402 struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
0403 if ((cpu_err_stat & CPU_ERRMASK) &&
0404 (cpu_err_addr == hp->ndptr || cpu_err_addr == hp->cbp))
0405 break;
0406 if ((gio_err_stat & GIO_ERRMASK) &&
0407 (gio_err_addr == hp->ndptr || gio_err_addr == hp->cbp))
0408 break;
0409 }
0410 if (i < sizeof(hpc3)/sizeof(struct hpc3_stat)) {
0411 struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
0412 printk(KERN_ERR "at DMA addresses: HPC3 @ %08lx:"
0413 " ctl %08x, ndp %08x, cbp %08x\n",
0414 CPHYSADDR(hp->addr), hp->ctrl, hp->ndptr, hp->cbp);
0415 goto mips_be_fatal;
0416 }
0417
0418 if (check_vdma_memaddr()) {
0419 printk(KERN_ERR "at GIO DMA: mem address 0x%08x.\n",
0420 sgimc->maddronly);
0421 goto mips_be_fatal;
0422 }
0423 if (check_vdma_gioaddr()) {
0424 printk(KERN_ERR "at GIO DMA: gio address 0x%08x.\n",
0425 sgimc->gmaddronly);
0426 goto mips_be_fatal;
0427 }
0428
0429 if (debug_be_interrupt) {
0430 print_buserr(regs);
0431 printk(KERN_ERR "discarded!\n");
0432 }
0433 return MIPS_BE_DISCARD;
0434
0435 mips_be_fatal:
0436 print_buserr(regs);
0437 return MIPS_BE_FATAL;
0438 }
0439
0440 void ip22_be_interrupt(int irq)
0441 {
0442 struct pt_regs *regs = get_irq_regs();
0443
0444 count_be_interrupt++;
0445
0446 if (ip28_be_interrupt(regs) != MIPS_BE_DISCARD) {
0447
0448 die_if_kernel("Oops", regs);
0449 force_sig(SIGBUS);
0450 } else if (debug_be_interrupt)
0451 show_regs(regs);
0452 }
0453
0454 static int ip28_be_handler(struct pt_regs *regs, int is_fixup)
0455 {
0456
0457
0458
0459
0460 if (is_fixup) {
0461 count_be_is_fixup++;
0462 save_and_clear_buserr();
0463 return MIPS_BE_FIXUP;
0464 }
0465 count_be_handler++;
0466 return ip28_be_interrupt(regs);
0467 }
0468
0469 void __init ip22_be_init(void)
0470 {
0471 mips_set_be_handler(ip28_be_handler);
0472 }
0473
0474 int ip28_show_be_info(struct seq_file *m)
0475 {
0476 seq_printf(m, "IP28 be fixups\t\t: %u\n", count_be_is_fixup);
0477 seq_printf(m, "IP28 be interrupts\t: %u\n", count_be_interrupt);
0478 seq_printf(m, "IP28 be handler\t\t: %u\n", count_be_handler);
0479
0480 return 0;
0481 }
0482
0483 static int __init debug_be_setup(char *str)
0484 {
0485 debug_be_interrupt++;
0486 return 1;
0487 }
0488 __setup("ip28_debug_be", debug_be_setup);