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/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
  29static unsigned int count_be_is_fixup;
  30static unsigned int count_be_handler;
  31static unsigned int count_be_interrupt;
  32static int debug_be_interrupt;
  33
  34static unsigned int cpu_err_stat;       /* Status reg for CPU */
  35static unsigned int gio_err_stat;       /* Status reg for GIO */
  36static unsigned int cpu_err_addr;       /* Error address reg for CPU */
  37static unsigned int gio_err_addr;       /* Error address reg for GIO */
  38static unsigned int extio_stat;
  39static unsigned int hpc3_berr_stat;     /* Bus error interrupt status */
  40
  41struct hpc3_stat {
  42        unsigned long addr;
  43        unsigned int ctrl;
  44        unsigned int cbp;
  45        unsigned int ndptr;
  46};
  47
  48static struct {
  49        struct hpc3_stat pbdma[8];
  50        struct hpc3_stat scsi[2];
  51        struct hpc3_stat ethrx, ethtx;
  52} hpc3;
  53
  54static struct {
  55        unsigned long err_addr;
  56        struct {
  57                u32 lo;
  58                u32 hi;
  59        } tags[1][2], tagd[4][2], tagi[4][2]; /* Way 0/1 */
  60} cache_tags;
  61
  62static inline void save_cache_tags(unsigned busaddr)
  63{
  64        unsigned long addr = CAC_BASE | busaddr;
  65        int i;
  66        cache_tags.err_addr = addr;
  67
  68        /*
  69         * Starting with a bus-address, save secondary cache (indexed by
  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[35:18], VA[13:12] */
  76        tag[0].hi = read_c0_taghi();    /* PA[39:36] */
  77        cache_op(Index_Load_Tag_S, addr | 1L);
  78        tag[1].lo = read_c0_taglo();    /* PA[35:18], VA[13:12] */
  79        tag[1].hi = read_c0_taghi();    /* PA[39:36] */
  80#undef tag
  81
  82        /*
  83         * Save all primary data cache (indexed by VA[13:5]) tags which
  84         * might fit to this bus-address, knowing that VA[11:0] == PA[11:0].
  85         * Saving all tags and evaluating them later is easier and safer
  86         * than relying on VA[13:12] from the secondary cache tags to pick
  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 << 12)) {
  92                cache_op(Index_Load_Tag_D, addr);
  93                tag[0].lo = read_c0_taglo();    /* PA[35:12] */
  94                tag[0].hi = read_c0_taghi();    /* PA[39:36] */
  95                cache_op(Index_Load_Tag_D, addr | 1L);
  96                tag[1].lo = read_c0_taglo();    /* PA[35:12] */
  97                tag[1].hi = read_c0_taghi();    /* PA[39:36] */
  98        }
  99#undef tag
 100
 101        /*
 102         * Save primary instruction cache (indexed by VA[13:6]) tags
 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 << 12)) {
 108                cache_op(Index_Load_Tag_I, addr);
 109                tag[0].lo = read_c0_taglo();    /* PA[35:12] */
 110                tag[0].hi = read_c0_taghi();    /* PA[39:36] */
 111                cache_op(Index_Load_Tag_I, addr | 1L);
 112                tag[1].lo = read_c0_taglo();    /* PA[35:12] */
 113                tag[1].hi = read_c0_taghi();    /* PA[39:36] */
 114        }
 115#undef tag
 116}
 117
 118#define GIO_ERRMASK     0xff00
 119#define CPU_ERRMASK     0x3f00
 120
 121static 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)&hpc3c0->scsi_chan0;
 134        hpc3.scsi[0].ctrl  = hpc3c0->scsi_chan0.ctrl; /* HPC3_SCTRL_ACTIVE ? */
 135        hpc3.scsi[0].cbp   = hpc3c0->scsi_chan0.cbptr;
 136        hpc3.scsi[0].ndptr = hpc3c0->scsi_chan0.ndptr;
 137
 138        hpc3.scsi[1].addr  = (unsigned long)&hpc3c0->scsi_chan1;
 139        hpc3.scsi[1].ctrl  = hpc3c0->scsi_chan1.ctrl; /* HPC3_SCTRL_ACTIVE ? */
 140        hpc3.scsi[1].cbp   = hpc3c0->scsi_chan1.cbptr;
 141        hpc3.scsi[1].ndptr = hpc3c0->scsi_chan1.ndptr;
 142
 143        hpc3.ethrx.addr  = (unsigned long)&hpc3c0->ethregs.rx_cbptr;
 144        hpc3.ethrx.ctrl  = hpc3c0->ethregs.rx_ctrl; /* HPC3_ERXCTRL_ACTIVE ? */
 145        hpc3.ethrx.cbp   = hpc3c0->ethregs.rx_cbptr;
 146        hpc3.ethrx.ndptr = hpc3c0->ethregs.rx_ndptr;
 147
 148        hpc3.ethtx.addr  = (unsigned long)&hpc3c0->ethregs.tx_cbptr;
 149        hpc3.ethtx.ctrl  = hpc3c0->ethregs.tx_ctrl; /* HPC3_ETXCTRL_ACTIVE ? */
 150        hpc3.ethtx.cbp   = hpc3c0->ethregs.tx_cbptr;
 151        hpc3.ethtx.ndptr = hpc3c0->ethregs.tx_ndptr;
 152
 153        for (i = 0; i < 8; ++i) {
 154                /* HPC3_PDMACTRL_ISACT ? */
 155                hpc3.pbdma[i].addr  = (unsigned long)&hpc3c0->pbdma[i];
 156                hpc3.pbdma[i].ctrl  = hpc3c0->pbdma[i].pbdma_ctrl;
 157                hpc3.pbdma[i].cbp   = hpc3c0->pbdma[i].pbdma_bptr;
 158                hpc3.pbdma[i].ndptr = hpc3c0->pbdma[i].pbdma_dptr;
 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
 170static void print_cache_tags(void)
 171{
 172        u32 scb, scw;
 173        int i;
 174
 175        printk(KERN_ERR "Cache tags @ %08x:\n", (unsigned)cache_tags.err_addr);
 176
 177        /* PA[31:12] shifted to PTag0 (PA[35:12]) format */
 178        scw = (cache_tags.err_addr >> 4) & 0x0fffff00;
 179
 180        scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 5) - 1);
 181        for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */
 182                if ((cache_tags.tagd[i][0].lo & 0x0fffff00) != scw &&
 183                    (cache_tags.tagd[i][1].lo & 0x0fffff00) != scw)
 184                    continue;
 185                printk(KERN_ERR
 186                       "D: 0: %08x %08x, 1: %08x %08x  (VA[13:5]  %04x)\n",
 187                        cache_tags.tagd[i][0].hi, cache_tags.tagd[i][0].lo,
 188                        cache_tags.tagd[i][1].hi, cache_tags.tagd[i][1].lo,
 189                        scb | (1 << 12)*i);
 190        }
 191        scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 6) - 1);
 192        for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */
 193                if ((cache_tags.tagi[i][0].lo & 0x0fffff00) != scw &&
 194                    (cache_tags.tagi[i][1].lo & 0x0fffff00) != scw)
 195                    continue;
 196                printk(KERN_ERR
 197                       "I: 0: %08x %08x, 1: %08x %08x  (VA[13:6]  %04x)\n",
 198                        cache_tags.tagi[i][0].hi, cache_tags.tagi[i][0].lo,
 199                        cache_tags.tagi[i][1].hi, cache_tags.tagi[i][1].lo,
 200                        scb | (1 << 12)*i);
 201        }
 202        i = read_c0_config();
 203        scb = i & (1 << 13) ? 7:6;      /* scblksize = 2^[7..6] */
 204        scw = ((i >> 16) & 7) + 19 - 1; /* scwaysize = 2^[24..19] / 2 */
 205
 206        i = ((1 << scw) - 1) & ~((1 << scb) - 1);
 207        printk(KERN_ERR "S: 0: %08x %08x, 1: %08x %08x  (PA[%u:%u] %05x)\n",
 208                cache_tags.tags[0][0].hi, cache_tags.tags[0][0].lo,
 209                cache_tags.tags[0][1].hi, cache_tags.tags[0][1].lo,
 210                scw-1, scb, i & (unsigned)cache_tags.err_addr);
 211}
 212
 213static inline const char *cause_excode_text(int cause)
 214{
 215        static const char *txt[32] =
 216        {       "Interrupt",
 217                "TLB modification",
 218                "TLB (load or instruction fetch)",
 219                "TLB (store)",
 220                "Address error (load or instruction fetch)",
 221                "Address error (store)",
 222                "Bus error (instruction fetch)",
 223                "Bus error (data: load or store)",
 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", "21", "22",
 233                "Watch Hi/Lo",
 234                "24", "25", "26", "27", "28", "29", "30", "31",
 235        };
 236        return txt[(cause & 0x7c) >> 2];
 237}
 238
 239static void print_buserr(const struct pt_regs *regs)
 240{
 241        const int field = 2 * sizeof(unsigned long);
 242        int error = 0;
 243
 244        if (extio_stat & EXTIO_MC_BUSERR) {
 245                printk(KERN_ERR "MC Bus Error\n");
 246                error |= 1;
 247        }
 248        if (extio_stat & EXTIO_HPC3_BUSERR) {
 249                printk(KERN_ERR "HPC3 Bus Error 0x%x:<id=0x%x,%s,lane=0x%x>\n",
 250                        hpc3_berr_stat,
 251                        (hpc3_berr_stat & HPC3_BESTAT_PIDMASK) >>
 252                                          HPC3_BESTAT_PIDSHIFT,
 253                        (hpc3_berr_stat & HPC3_BESTAT_CTYPE) ? "PIO" : "DMA",
 254                        hpc3_berr_stat & HPC3_BESTAT_BLMASK);
 255                error |= 2;
 256        }
 257        if (extio_stat & EXTIO_EISA_BUSERR) {
 258                printk(KERN_ERR "EISA Bus Error\n");
 259                error |= 4;
 260        }
 261        if (cpu_err_stat & CPU_ERRMASK) {
 262                printk(KERN_ERR "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n",
 263                        cpu_err_stat,
 264                        cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "",
 265                        cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "",
 266                        cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "",
 267                        cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "",
 268                        cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "",
 269                        cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "",
 270                        cpu_err_addr);
 271                error |= 8;
 272        }
 273        if (gio_err_stat & GIO_ERRMASK) {
 274                printk(KERN_ERR "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x%08x\n",
 275                        gio_err_stat,
 276                        gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "",
 277                        gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "",
 278                        gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "",
 279                        gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "",
 280                        gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "",
 281                        gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "",
 282                        gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "",
 283                        gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "",
 284                        gio_err_addr);
 285                error |= 16;
 286        }
 287        if (!error)
 288                printk(KERN_ERR "MC: Hmm, didn't find any error condition.\n");
 289        else {
 290                printk(KERN_ERR "CP0: config %08x,  "
 291                        "MC: cpuctrl0/1: %08x/%05x, giopar: %04x\n"
 292                        "MC: cpu/gio_memacc: %08x/%05x, memcfg0/1: %08x/%08x\n",
 293                        read_c0_config(),
 294                        sgimc->cpuctrl0, sgimc->cpuctrl0, sgimc->giopar,
 295                        sgimc->cmacc, sgimc->gmacc,
 296                        sgimc->mconfig0, sgimc->mconfig1);
 297                print_cache_tags();
 298        }
 299        printk(KERN_ALERT "%s, epc == %0*lx, ra == %0*lx\n",
 300               cause_excode_text(regs->cp0_cause),
 301               field, regs->cp0_epc, field, regs->regs[31]);
 302}
 303
 304static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr)
 305{
 306        /* This is likely rather similar to correct code ;-) */
 307
 308        vaddr &= 0x7fffffff; /* Doc. states that top bit is ignored */
 309
 310        /* If tlb-entry is valid and VPN-high (bits [30:21] ?) matches... */
 311        if ((lo & 2) && (vaddr >> 21) == ((hi<<1) >> 22)) {
 312                u32 ctl = sgimc->dma_ctrl;
 313                if (ctl & 1) {
 314                        unsigned int pgsz = (ctl & 2) ? 14:12; /* 16k:4k */
 315                        /* PTEIndex is VPN-low (bits [22:14]/[20:12] ?) */
 316                        unsigned long pte = (lo >> 6) << 12; /* PTEBase */
 317                        pte += 8*((vaddr >> pgsz) & 0x1ff);
 318                        if (page_is_ram(PFN_DOWN(pte))) {
 319                                /*
 320                                 * Note: Since DMA hardware does look up
 321                                 * translation on its own, this PTE *must*
 322                                 * match the TLB/EntryLo-register format !
 323                                 */
 324                                unsigned long a = *(unsigned long *)
 325                                                PHYS_TO_XKSEG_UNCACHED(pte);
 326                                a = (a & 0x3f) << 6; /* PFN */
 327                                a += vaddr & ((1 << pgsz) - 1);
 328                                return cpu_err_addr == a;
 329                        }
 330                }
 331        }
 332        return 0;
 333}
 334
 335static 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)) /* Xlate-bit clear ? */
 341                        return cpu_err_addr == a;
 342
 343                if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) ||
 344                    check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) ||
 345                    check_microtlb(sgimc->dtlb_hi2, sgimc->dtlb_lo2, a) ||
 346                    check_microtlb(sgimc->dtlb_hi3, sgimc->dtlb_lo3, a))
 347                        return 1;
 348        }
 349        return 0;
 350}
 351
 352static 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) | (sgimc->gio_dma_sbits & a);
 357                return gio_err_addr == a;
 358        }
 359        return 0;
 360}
 361
 362/*
 363 * MC sends an interrupt whenever bus or parity errors occur. In addition,
 364 * if the error happened during a CPU read, it also asserts the bus error
 365 * pin on the R4K. Code in bus error handler save the MC bus error registers
 366 * and then clear the interrupt when this happens.
 367 */
 368
 369static int ip28_be_interrupt(const struct pt_regs *regs)
 370{
 371        int i;
 372
 373        save_and_clear_buserr();
 374        /*
 375         * Try to find out, whether we got here by a mispredicted speculative
 376         * load/store operation.  If so, it's not fatal, we can go on.
 377         */
 378        /* Any cause other than "Interrupt" (ExcCode 0) is fatal. */
 379        if (regs->cp0_cause & CAUSEF_EXCCODE)
 380                goto mips_be_fatal;
 381
 382        /* Any cause other than "Bus error interrupt" (IP6) is weird. */
 383        if ((regs->cp0_cause & CAUSEF_IP6) != CAUSEF_IP6)
 384                goto mips_be_fatal;
 385
 386        if (extio_stat & (EXTIO_HPC3_BUSERR | EXTIO_EISA_BUSERR))
 387                goto mips_be_fatal;
 388
 389        /* Any state other than "Memory bus error" is fatal. */
 390        if (cpu_err_stat & CPU_ERRMASK & ~SGIMC_CSTAT_ADDR)
 391                goto mips_be_fatal;
 392
 393        /* GIO errors other than timeouts are fatal */
 394        if (gio_err_stat & GIO_ERRMASK & ~SGIMC_GSTAT_TIME)
 395                goto mips_be_fatal;
 396
 397        /*
 398         * Now we have an asynchronous bus error, speculatively or DMA caused.
 399         * Need to search all DMA descriptors for the error address.
 400         */
 401        for (i = 0; i < sizeof(hpc3)/sizeof(struct hpc3_stat); ++i) {
 402                struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
 403                if ((cpu_err_stat & CPU_ERRMASK) &&
 404                    (cpu_err_addr == hp->ndptr || cpu_err_addr == hp->cbp))
 405                        break;
 406                if ((gio_err_stat & GIO_ERRMASK) &&
 407                    (gio_err_addr == hp->ndptr || gio_err_addr == hp->cbp))
 408                        break;
 409        }
 410        if (i < sizeof(hpc3)/sizeof(struct hpc3_stat)) {
 411                struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
 412                printk(KERN_ERR "at DMA addresses: HPC3 @ %08lx:"
 413                       " ctl %08x, ndp %08x, cbp %08x\n",
 414                       CPHYSADDR(hp->addr), hp->ctrl, hp->ndptr, hp->cbp);
 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: mem address 0x%08x.\n",
 420                        sgimc->maddronly);
 421                goto mips_be_fatal;
 422        }
 423        if (check_vdma_gioaddr()) {
 424                printk(KERN_ERR "at GIO DMA: gio address 0x%08x.\n",
 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
 435mips_be_fatal:
 436        print_buserr(regs);
 437        return MIPS_BE_FATAL;
 438}
 439
 440void 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_DISCARD) {
 447                /* Assume it would be too dangerous to continue ... */
 448                die_if_kernel("Oops", regs);
 449                force_sig(SIGBUS);
 450        } else if (debug_be_interrupt)
 451                show_regs(regs);
 452}
 453
 454static int ip28_be_handler(struct pt_regs *regs, int is_fixup)
 455{
 456        /*
 457         * We arrive here only in the unusual case of do_be() invocation,
 458         * i.e. by a bus error exception without a bus error interrupt.
 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
 469void __init ip22_be_init(void)
 470{
 471        board_be_handler = ip28_be_handler;
 472}
 473
 474int ip28_show_be_info(struct seq_file *m)
 475{
 476        seq_printf(m, "IP28 be fixups\t\t: %u\n", count_be_is_fixup);
 477        seq_printf(m, "IP28 be interrupts\t: %u\n", count_be_interrupt);
 478        seq_printf(m, "IP28 be handler\t\t: %u\n", count_be_handler);
 479
 480        return 0;
 481}
 482
 483static 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