Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * ip28-berr.c: Bus error handling.
0004  *
0005  * Copyright (C) 2002, 2003 Ladislav Michl (ladis@linux-mips.org)
0006  * Copyright (C) 2005 Peter Fuerst (pf@net.alphadv.de) - IP28
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;   /* Status reg for CPU */
0035 static unsigned int gio_err_stat;   /* Status reg for GIO */
0036 static unsigned int cpu_err_addr;   /* Error address reg for CPU */
0037 static unsigned int gio_err_addr;   /* Error address reg for GIO */
0038 static unsigned int extio_stat;
0039 static unsigned int hpc3_berr_stat; /* Bus error interrupt status */
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]; /* Way 0/1 */
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      * Starting with a bus-address, save secondary cache (indexed by
0070      * PA[23..18:7..6]) tags first.
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();    /* PA[35:18], VA[13:12] */
0076     tag[0].hi = read_c0_taghi();    /* PA[39:36] */
0077     cache_op(Index_Load_Tag_S, addr | 1L);
0078     tag[1].lo = read_c0_taglo();    /* PA[35:18], VA[13:12] */
0079     tag[1].hi = read_c0_taghi();    /* PA[39:36] */
0080 #undef tag
0081 
0082     /*
0083      * Save all primary data cache (indexed by VA[13:5]) tags which
0084      * might fit to this bus-address, knowing that VA[11:0] == PA[11:0].
0085      * Saving all tags and evaluating them later is easier and safer
0086      * than relying on VA[13:12] from the secondary cache tags to pick
0087      * matching primary tags here already.
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();    /* PA[35:12] */
0094         tag[0].hi = read_c0_taghi();    /* PA[39:36] */
0095         cache_op(Index_Load_Tag_D, addr | 1L);
0096         tag[1].lo = read_c0_taglo();    /* PA[35:12] */
0097         tag[1].hi = read_c0_taghi();    /* PA[39:36] */
0098     }
0099 #undef tag
0100 
0101     /*
0102      * Save primary instruction cache (indexed by VA[13:6]) tags
0103      * the same way.
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();    /* PA[35:12] */
0110         tag[0].hi = read_c0_taghi();    /* PA[39:36] */
0111         cache_op(Index_Load_Tag_I, addr | 1L);
0112         tag[1].lo = read_c0_taglo();    /* PA[35:12] */
0113         tag[1].hi = read_c0_taghi();    /* PA[39:36] */
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     /* save status registers */
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; /* HPC3_SCTRL_ACTIVE ? */
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; /* HPC3_SCTRL_ACTIVE ? */
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; /* HPC3_ERXCTRL_ACTIVE ? */
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; /* HPC3_ETXCTRL_ACTIVE ? */
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         /* HPC3_PDMACTRL_ISACT ? */
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     /* PA[31:12] shifted to PTag0 (PA[35:12]) format */
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) { /* for each possible VA[13:12] value */
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) { /* for each possible VA[13:12] value */
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;  /* scblksize = 2^[7..6] */
0204     scw = ((i >> 16) & 7) + 19 - 1; /* scwaysize = 2^[24..19] / 2 */
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     /* This is likely rather similar to correct code ;-) */
0307 
0308     vaddr &= 0x7fffffff; /* Doc. states that top bit is ignored */
0309 
0310     /* If tlb-entry is valid and VPN-high (bits [30:21] ?) matches... */
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; /* 16k:4k */
0315             /* PTEIndex is VPN-low (bits [22:14]/[20:12] ?) */
0316             unsigned long pte = (lo >> 6) << 12; /* PTEBase */
0317             pte += 8*((vaddr >> pgsz) & 0x1ff);
0318             if (page_is_ram(PFN_DOWN(pte))) {
0319                 /*
0320                  * Note: Since DMA hardware does look up
0321                  * translation on its own, this PTE *must*
0322                  * match the TLB/EntryLo-register format !
0323                  */
0324                 unsigned long a = *(unsigned long *)
0325                         PHYS_TO_XKSEG_UNCACHED(pte);
0326                 a = (a & 0x3f) << 6; /* PFN */
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)) /* Xlate-bit clear ? */
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  * MC sends an interrupt whenever bus or parity errors occur. In addition,
0364  * if the error happened during a CPU read, it also asserts the bus error
0365  * pin on the R4K. Code in bus error handler save the MC bus error registers
0366  * and then clear the interrupt when this happens.
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      * Try to find out, whether we got here by a mispredicted speculative
0376      * load/store operation.  If so, it's not fatal, we can go on.
0377      */
0378     /* Any cause other than "Interrupt" (ExcCode 0) is fatal. */
0379     if (regs->cp0_cause & CAUSEF_EXCCODE)
0380         goto mips_be_fatal;
0381 
0382     /* Any cause other than "Bus error interrupt" (IP6) is weird. */
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     /* Any state other than "Memory bus error" is fatal. */
0390     if (cpu_err_stat & CPU_ERRMASK & ~SGIMC_CSTAT_ADDR)
0391         goto mips_be_fatal;
0392 
0393     /* GIO errors other than timeouts are fatal */
0394     if (gio_err_stat & GIO_ERRMASK & ~SGIMC_GSTAT_TIME)
0395         goto mips_be_fatal;
0396 
0397     /*
0398      * Now we have an asynchronous bus error, speculatively or DMA caused.
0399      * Need to search all DMA descriptors for the error address.
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     /* Check MC's virtual DMA stuff. */
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     /* A speculative bus error... */
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         /* Assume it would be too dangerous to continue ... */
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      * We arrive here only in the unusual case of do_be() invocation,
0458      * i.e. by a bus error exception without a bus error interrupt.
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);