linux/arch/mips/sgi-ip22/ip28-berr.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * ip28-berr.c: Bus error handling.
   4 *
   5 * Copyright (C) 2002, 2003 Ladislav Michl (ladis@linux-mips.org)
   6 * Copyright (C) 2005 Peter Fuerst (pf@net.alphadv.de) - IP28
   7 */
   8
   9#include <linux/init.h>
  10#include <linux/kernel.h>
  11#include <linux/sched.h>
  12#include <linux/sched/debug.h>
  13#include <linux/sched/signal.h>
  14#include <linux/seq_file.h>
  15
  16#include <asm/addrspace.h>
  17#include <asm/traps.h>
  18#include <asm/branch.h>
  19#include <asm/irq_regs.h>
  20#include <asm/sgi/mc.h>
  21#include <asm/sgi/hpc3.h>
  22#include <asm/sgi/ioc.h>
  23#include <asm/sgi/ip22.h>
  24#include <asm/r4kcache.h>
  25#include <linux/uaccess.h>
  26#include <asm/bootinfo.h>
  27
  28static unsigned int count_be_is_fixup;
  29static unsigned int count_be_handler;
  30static unsigned int count_be_interrupt;
  31static int debug_be_interrupt;
  32
  33static unsigned int cpu_err_stat;       /* Status reg for CPU */
  34static unsigned int gio_err_stat;       /* Status reg for GIO */
  35static unsigned int cpu_err_addr;       /* Error address reg for CPU */
  36static unsigned int gio_err_addr;       /* Error address reg for GIO */
  37static unsigned int extio_stat;
  38static unsigned int hpc3_berr_stat;     /* Bus error interrupt status */
  39
  40struct hpc3_stat {
  41        unsigned long addr;
  42        unsigned int ctrl;
  43        unsigned int cbp;
  44        unsigned int ndptr;
  45};
  46
  47static struct {
  48        struct hpc3_stat pbdma[8];
  49        struct hpc3_stat scsi[2];
  50        struct hpc3_stat ethrx, ethtx;
  51} hpc3;
  52
  53static struct {
  54        unsigned long err_addr;
  55        struct {
  56                u32 lo;
  57                u32 hi;
  58        } tags[1][2], tagd[4][2], tagi[4][2]; /* Way 0/1 */
  59} cache_tags;
  60
  61static inline void save_cache_tags(unsigned busaddr)
  62{
  63        unsigned long addr = CAC_BASE | busaddr;
  64        int i;
  65        cache_tags.err_addr = addr;
  66
  67        /*
  68         * Starting with a bus-address, save secondary cache (indexed by
  69         * PA[23..18:7..6]) tags first.
  70         */
  71        addr &= ~1L;
  72#define tag cache_tags.tags[0]
  73        cache_op(Index_Load_Tag_S, addr);
  74        tag[0].lo = read_c0_taglo();    /* PA[35:18], VA[13:12] */
  75        tag[0].hi = read_c0_taghi();    /* PA[39:36] */
  76        cache_op(Index_Load_Tag_S, addr | 1L);
  77        tag[1].lo = read_c0_taglo();    /* PA[35:18], VA[13:12] */
  78        tag[1].hi = read_c0_taghi();    /* PA[39:36] */
  79#undef tag
  80
  81        /*
  82         * Save all primary data cache (indexed by VA[13:5]) tags which
  83         * might fit to this bus-address, knowing that VA[11:0] == PA[11:0].
  84         * Saving all tags and evaluating them later is easier and safer
  85         * than relying on VA[13:12] from the secondary cache tags to pick
  86         * matching primary tags here already.
  87         */
  88        addr &= (0xffL << 56) | ((1 << 12) - 1);
  89#define tag cache_tags.tagd[i]
  90        for (i = 0; i < 4; ++i, addr += (1 << 12)) {
  91                cache_op(Index_Load_Tag_D, addr);
  92                tag[0].lo = read_c0_taglo();    /* PA[35:12] */
  93                tag[0].hi = read_c0_taghi();    /* PA[39:36] */
  94                cache_op(Index_Load_Tag_D, addr | 1L);
  95                tag[1].lo = read_c0_taglo();    /* PA[35:12] */
  96                tag[1].hi = read_c0_taghi();    /* PA[39:36] */
  97        }
  98#undef tag
  99
 100        /*
 101         * Save primary instruction cache (indexed by VA[13:6]) tags
 102         * the same way.
 103         */
 104        addr &= (0xffL << 56) | ((1 << 12) - 1);
 105#define tag cache_tags.tagi[i]
 106        for (i = 0; i < 4; ++i, addr += (1 << 12)) {
 107                cache_op(Index_Load_Tag_I, addr);
 108                tag[0].lo = read_c0_taglo();    /* PA[35:12] */
 109                tag[0].hi = read_c0_taghi();    /* PA[39:36] */
 110                cache_op(Index_Load_Tag_I, addr | 1L);
 111                tag[1].lo = read_c0_taglo();    /* PA[35:12] */
 112                tag[1].hi = read_c0_taghi();    /* PA[39:36] */
 113        }
 114#undef tag
 115}
 116
 117#define GIO_ERRMASK     0xff00
 118#define CPU_ERRMASK     0x3f00
 119
 120static void save_and_clear_buserr(void)
 121{
 122        int i;
 123
 124        /* save status registers */
 125        cpu_err_addr = sgimc->cerr;
 126        cpu_err_stat = sgimc->cstat;
 127        gio_err_addr = sgimc->gerr;
 128        gio_err_stat = sgimc->gstat;
 129        extio_stat = sgioc->extio;
 130        hpc3_berr_stat = hpc3c0->bestat;
 131
 132        hpc3.scsi[0].addr  = (unsigned long)&hpc3c0->scsi_chan0;
 133        hpc3.scsi[0].ctrl  = hpc3c0->scsi_chan0.ctrl; /* HPC3_SCTRL_ACTIVE ? */
 134        hpc3.scsi[0].cbp   = hpc3c0->scsi_chan0.cbptr;
 135        hpc3.scsi[0].ndptr = hpc3c0->scsi_chan0.ndptr;
 136
 137        hpc3.scsi[1].addr  = (unsigned long)&hpc3c0->scsi_chan1;
 138        hpc3.scsi[1].ctrl  = hpc3c0->scsi_chan1.ctrl; /* HPC3_SCTRL_ACTIVE ? */
 139        hpc3.scsi[1].cbp   = hpc3c0->scsi_chan1.cbptr;
 140        hpc3.scsi[1].ndptr = hpc3c0->scsi_chan1.ndptr;
 141
 142        hpc3.ethrx.addr  = (unsigned long)&hpc3c0->ethregs.rx_cbptr;
 143        hpc3.ethrx.ctrl  = hpc3c0->ethregs.rx_ctrl; /* HPC3_ERXCTRL_ACTIVE ? */
 144        hpc3.ethrx.cbp   = hpc3c0->ethregs.rx_cbptr;
 145        hpc3.ethrx.ndptr = hpc3c0->ethregs.rx_ndptr;
 146
 147        hpc3.ethtx.addr  = (unsigned long)&hpc3c0->ethregs.tx_cbptr;
 148        hpc3.ethtx.ctrl  = hpc3c0->ethregs.tx_ctrl; /* HPC3_ETXCTRL_ACTIVE ? */
 149        hpc3.ethtx.cbp   = hpc3c0->ethregs.tx_cbptr;
 150        hpc3.ethtx.ndptr = hpc3c0->ethregs.tx_ndptr;
 151
 152        for (i = 0; i < 8; ++i) {
 153                /* HPC3_PDMACTRL_ISACT ? */
 154                hpc3.pbdma[i].addr  = (unsigned long)&hpc3c0->pbdma[i];
 155                hpc3.pbdma[i].ctrl  = hpc3c0->pbdma[i].pbdma_ctrl;
 156                hpc3.pbdma[i].cbp   = hpc3c0->pbdma[i].pbdma_bptr;
 157                hpc3.pbdma[i].ndptr = hpc3c0->pbdma[i].pbdma_dptr;
 158        }
 159        i = 0;
 160        if (gio_err_stat & CPU_ERRMASK)
 161                i = gio_err_addr;
 162        if (cpu_err_stat & CPU_ERRMASK)
 163                i = cpu_err_addr;
 164        save_cache_tags(i);
 165
 166        sgimc->cstat = sgimc->gstat = 0;
 167}
 168
 169static void print_cache_tags(void)
 170{
 171        u32 scb, scw;
 172        int i;
 173
 174        printk(KERN_ERR "Cache tags @ %08x:\n", (unsigned)cache_tags.err_addr);
 175
 176        /* PA[31:12] shifted to PTag0 (PA[35:12]) format */
 177        scw = (cache_tags.err_addr >> 4) & 0x0fffff00;
 178
 179        scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 5) - 1);
 180        for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */
 181                if ((cache_tags.tagd[i][0].lo & 0x0fffff00) != scw &&
 182                    (cache_tags.tagd[i][1].lo & 0x0fffff00) != scw)
 183                    continue;
 184                printk(KERN_ERR
 185                       "D: 0: %08x %08x, 1: %08x %08x  (VA[13:5]  %04x)\n",
 186                        cache_tags.tagd[i][0].hi, cache_tags.tagd[i][0].lo,
 187                        cache_tags.tagd[i][1].hi, cache_tags.tagd[i][1].lo,
 188                        scb | (1 << 12)*i);
 189        }
 190        scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 6) - 1);
 191        for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */
 192                if ((cache_tags.tagi[i][0].lo & 0x0fffff00) != scw &&
 193                    (cache_tags.tagi[i][1].lo & 0x0fffff00) != scw)
 194                    continue;
 195                printk(KERN_ERR
 196                       "I: 0: %08x %08x, 1: %08x %08x  (VA[13:6]  %04x)\n",
 197                        cache_tags.tagi[i][0].hi, cache_tags.tagi[i][0].lo,
 198                        cache_tags.tagi[i][1].hi, cache_tags.tagi[i][1].lo,
 199                        scb | (1 << 12)*i);
 200        }
 201        i = read_c0_config();
 202        scb = i & (1 << 13) ? 7:6;      /* scblksize = 2^[7..6] */
 203        scw = ((i >> 16) & 7) + 19 - 1; /* scwaysize = 2^[24..19] / 2 */
 204
 205        i = ((1 << scw) - 1) & ~((1 << scb) - 1);
 206        printk(KERN_ERR "S: 0: %08x %08x, 1: %08x %08x  (PA[%u:%u] %05x)\n",
 207                cache_tags.tags[0][0].hi, cache_tags.tags[0][0].lo,
 208                cache_tags.tags[0][1].hi, cache_tags.tags[0][1].lo,
 209                scw-1, scb, i & (unsigned)cache_tags.err_addr);
 210}
 211
 212static inline const char *cause_excode_text(int cause)
 213{
 214        static const char *txt[32] =
 215        {       "Interrupt",
 216                "TLB modification",
 217                "TLB (load or instruction fetch)",
 218                "TLB (store)",
 219                "Address error (load or instruction fetch)",
 220                "Address error (store)",
 221                "Bus error (instruction fetch)",
 222                "Bus error (data: load or store)",
 223                "Syscall",
 224                "Breakpoint",
 225                "Reserved instruction",
 226                "Coprocessor unusable",
 227                "Arithmetic Overflow",
 228                "Trap",
 229                "14",
 230                "Floating-Point",
 231                "16", "17", "18", "19", "20", "21", "22",
 232                "Watch Hi/Lo",
 233                "24", "25", "26", "27", "28", "29", "30", "31",
 234        };
 235        return txt[(cause & 0x7c) >> 2];
 236}
 237
 238static void print_buserr(const struct pt_regs *regs)
 239{
 240        const int field = 2 * sizeof(unsigned long);
 241        int error = 0;
 242
 243        if (extio_stat & EXTIO_MC_BUSERR) {
 244                printk(KERN_ERR "MC Bus Error\n");
 245                error |= 1;
 246        }
 247        if (extio_stat & EXTIO_HPC3_BUSERR) {
 248                printk(KERN_ERR "HPC3 Bus Error 0x%x:<id=0x%x,%s,lane=0x%x>\n",
 249                        hpc3_berr_stat,
 250                        (hpc3_berr_stat & HPC3_BESTAT_PIDMASK) >>
 251                                          HPC3_BESTAT_PIDSHIFT,
 252                        (hpc3_berr_stat & HPC3_BESTAT_CTYPE) ? "PIO" : "DMA",
 253                        hpc3_berr_stat & HPC3_BESTAT_BLMASK);
 254                error |= 2;
 255        }
 256        if (extio_stat & EXTIO_EISA_BUSERR) {
 257                printk(KERN_ERR "EISA Bus Error\n");
 258                error |= 4;
 259        }
 260        if (cpu_err_stat & CPU_ERRMASK) {
 261                printk(KERN_ERR "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n",
 262                        cpu_err_stat,
 263                        cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "",
 264                        cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "",
 265                        cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "",
 266                        cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "",
 267                        cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "",
 268                        cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "",
 269                        cpu_err_addr);
 270                error |= 8;
 271        }
 272        if (gio_err_stat & GIO_ERRMASK) {
 273                printk(KERN_ERR "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x%08x\n",
 274                        gio_err_stat,
 275                        gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "",
 276                        gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "",
 277                        gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "",
 278                        gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "",
 279                        gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "",
 280                        gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "",
 281                        gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "",
 282                        gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "",
 283                        gio_err_addr);
 284                error |= 16;
 285        }
 286        if (!error)
 287                printk(KERN_ERR "MC: Hmm, didn't find any error condition.\n");
 288        else {
 289                printk(KERN_ERR "CP0: config %08x,  "
 290                        "MC: cpuctrl0/1: %08x/%05x, giopar: %04x\n"
 291                        "MC: cpu/gio_memacc: %08x/%05x, memcfg0/1: %08x/%08x\n",
 292                        read_c0_config(),
 293                        sgimc->cpuctrl0, sgimc->cpuctrl0, sgimc->giopar,
 294                        sgimc->cmacc, sgimc->gmacc,
 295                        sgimc->mconfig0, sgimc->mconfig1);
 296                print_cache_tags();
 297        }
 298        printk(KERN_ALERT "%s, epc == %0*lx, ra == %0*lx\n",
 299               cause_excode_text(regs->cp0_cause),
 300               field, regs->cp0_epc, field, regs->regs[31]);
 301}
 302
 303/*
 304 * Check, whether MC's (virtual) DMA address caused the bus error.
 305 * See "Virtual DMA Specification", Draft 1.5, Feb 13 1992, SGI
 306 */
 307
 308static int addr_is_ram(unsigned long addr, unsigned sz)
 309{
 310        int i;
 311
 312        for (i = 0; i < boot_mem_map.nr_map; i++) {
 313                unsigned long a = boot_mem_map.map[i].addr;
 314                if (a <= addr && addr+sz <= a+boot_mem_map.map[i].size)
 315                        return 1;
 316        }
 317        return 0;
 318}
 319
 320static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr)
 321{
 322        /* This is likely rather similar to correct code ;-) */
 323
 324        vaddr &= 0x7fffffff; /* Doc. states that top bit is ignored */
 325
 326        /* If tlb-entry is valid and VPN-high (bits [30:21] ?) matches... */
 327        if ((lo & 2) && (vaddr >> 21) == ((hi<<1) >> 22)) {
 328                u32 ctl = sgimc->dma_ctrl;
 329                if (ctl & 1) {
 330                        unsigned int pgsz = (ctl & 2) ? 14:12; /* 16k:4k */
 331                        /* PTEIndex is VPN-low (bits [22:14]/[20:12] ?) */
 332                        unsigned long pte = (lo >> 6) << 12; /* PTEBase */
 333                        pte += 8*((vaddr >> pgsz) & 0x1ff);
 334                        if (addr_is_ram(pte, 8)) {
 335                                /*
 336                                 * Note: Since DMA hardware does look up
 337                                 * translation on its own, this PTE *must*
 338                                 * match the TLB/EntryLo-register format !
 339                                 */
 340                                unsigned long a = *(unsigned long *)
 341                                                PHYS_TO_XKSEG_UNCACHED(pte);
 342                                a = (a & 0x3f) << 6; /* PFN */
 343                                a += vaddr & ((1 << pgsz) - 1);
 344                                return cpu_err_addr == a;
 345                        }
 346                }
 347        }
 348        return 0;
 349}
 350
 351static int check_vdma_memaddr(void)
 352{
 353        if (cpu_err_stat & CPU_ERRMASK) {
 354                u32 a = sgimc->maddronly;
 355
 356                if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */
 357                        return cpu_err_addr == a;
 358
 359                if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) ||
 360                    check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) ||
 361                    check_microtlb(sgimc->dtlb_hi2, sgimc->dtlb_lo2, a) ||
 362                    check_microtlb(sgimc->dtlb_hi3, sgimc->dtlb_lo3, a))
 363                        return 1;
 364        }
 365        return 0;
 366}
 367
 368static int check_vdma_gioaddr(void)
 369{
 370        if (gio_err_stat & GIO_ERRMASK) {
 371                u32 a = sgimc->gio_dma_trans;
 372                a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a);
 373                return gio_err_addr == a;
 374        }
 375        return 0;
 376}
 377
 378/*
 379 * MC sends an interrupt whenever bus or parity errors occur. In addition,
 380 * if the error happened during a CPU read, it also asserts the bus error
 381 * pin on the R4K. Code in bus error handler save the MC bus error registers
 382 * and then clear the interrupt when this happens.
 383 */
 384
 385static int ip28_be_interrupt(const struct pt_regs *regs)
 386{
 387        int i;
 388
 389        save_and_clear_buserr();
 390        /*
 391         * Try to find out, whether we got here by a mispredicted speculative
 392         * load/store operation.  If so, it's not fatal, we can go on.
 393         */
 394        /* Any cause other than "Interrupt" (ExcCode 0) is fatal. */
 395        if (regs->cp0_cause & CAUSEF_EXCCODE)
 396                goto mips_be_fatal;
 397
 398        /* Any cause other than "Bus error interrupt" (IP6) is weird. */
 399        if ((regs->cp0_cause & CAUSEF_IP6) != CAUSEF_IP6)
 400                goto mips_be_fatal;
 401
 402        if (extio_stat & (EXTIO_HPC3_BUSERR | EXTIO_EISA_BUSERR))
 403                goto mips_be_fatal;
 404
 405        /* Any state other than "Memory bus error" is fatal. */
 406        if (cpu_err_stat & CPU_ERRMASK & ~SGIMC_CSTAT_ADDR)
 407                goto mips_be_fatal;
 408
 409        /* GIO errors other than timeouts are fatal */
 410        if (gio_err_stat & GIO_ERRMASK & ~SGIMC_GSTAT_TIME)
 411                goto mips_be_fatal;
 412
 413        /*
 414         * Now we have an asynchronous bus error, speculatively or DMA caused.
 415         * Need to search all DMA descriptors for the error address.
 416         */
 417        for (i = 0; i < sizeof(hpc3)/sizeof(struct hpc3_stat); ++i) {
 418                struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
 419                if ((cpu_err_stat & CPU_ERRMASK) &&
 420                    (cpu_err_addr == hp->ndptr || cpu_err_addr == hp->cbp))
 421                        break;
 422                if ((gio_err_stat & GIO_ERRMASK) &&
 423                    (gio_err_addr == hp->ndptr || gio_err_addr == hp->cbp))
 424                        break;
 425        }
 426        if (i < sizeof(hpc3)/sizeof(struct hpc3_stat)) {
 427                struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
 428                printk(KERN_ERR "at DMA addresses: HPC3 @ %08lx:"
 429                       " ctl %08x, ndp %08x, cbp %08x\n",
 430                       CPHYSADDR(hp->addr), hp->ctrl, hp->ndptr, hp->cbp);
 431                goto mips_be_fatal;
 432        }
 433        /* Check MC's virtual DMA stuff. */
 434        if (check_vdma_memaddr()) {
 435                printk(KERN_ERR "at GIO DMA: mem address 0x%08x.\n",
 436                        sgimc->maddronly);
 437                goto mips_be_fatal;
 438        }
 439        if (check_vdma_gioaddr()) {
 440                printk(KERN_ERR "at GIO DMA: gio address 0x%08x.\n",
 441                        sgimc->gmaddronly);
 442                goto mips_be_fatal;
 443        }
 444        /* A speculative bus error... */
 445        if (debug_be_interrupt) {
 446                print_buserr(regs);
 447                printk(KERN_ERR "discarded!\n");
 448        }
 449        return MIPS_BE_DISCARD;
 450
 451mips_be_fatal:
 452        print_buserr(regs);
 453        return MIPS_BE_FATAL;
 454}
 455
 456void ip22_be_interrupt(int irq)
 457{
 458        struct pt_regs *regs = get_irq_regs();
 459
 460        count_be_interrupt++;
 461
 462        if (ip28_be_interrupt(regs) != MIPS_BE_DISCARD) {
 463                /* Assume it would be too dangerous to continue ... */
 464                die_if_kernel("Oops", regs);
 465                force_sig(SIGBUS);
 466        } else if (debug_be_interrupt)
 467                show_regs(regs);
 468}
 469
 470static int ip28_be_handler(struct pt_regs *regs, int is_fixup)
 471{
 472        /*
 473         * We arrive here only in the unusual case of do_be() invocation,
 474         * i.e. by a bus error exception without a bus error interrupt.
 475         */
 476        if (is_fixup) {
 477                count_be_is_fixup++;
 478                save_and_clear_buserr();
 479                return MIPS_BE_FIXUP;
 480        }
 481        count_be_handler++;
 482        return ip28_be_interrupt(regs);
 483}
 484
 485void __init ip22_be_init(void)
 486{
 487        board_be_handler = ip28_be_handler;
 488}
 489
 490int ip28_show_be_info(struct seq_file *m)
 491{
 492        seq_printf(m, "IP28 be fixups\t\t: %u\n", count_be_is_fixup);
 493        seq_printf(m, "IP28 be interrupts\t: %u\n", count_be_interrupt);
 494        seq_printf(m, "IP28 be handler\t\t: %u\n", count_be_handler);
 495
 496        return 0;
 497}
 498
 499static int __init debug_be_setup(char *str)
 500{
 501        debug_be_interrupt++;
 502        return 1;
 503}
 504__setup("ip28_debug_be", debug_be_setup);
 505