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