9 #include <linux/kernel.h>
10 #include <linux/sched.h>
13 #include <asm/addrspace.h>
14 #include <asm/traps.h>
16 #include <asm/irq_regs.h>
22 #include <asm/uaccess.h>
23 #include <asm/bootinfo.h>
25 static unsigned int count_be_is_fixup;
26 static unsigned int count_be_handler;
27 static unsigned int count_be_interrupt;
28 static int debug_be_interrupt;
30 static unsigned int cpu_err_stat;
31 static unsigned int gio_err_stat;
32 static unsigned int cpu_err_addr;
33 static unsigned int gio_err_addr;
34 static unsigned int extio_stat;
35 static unsigned int hpc3_berr_stat;
58 static inline void save_cache_tags(
unsigned busaddr)
62 cache_tags.err_addr =
addr;
69 #define tag cache_tags.tags[0]
85 addr &= (0xff
L << 56) | ((1 << 12) - 1);
86 #define tag cache_tags.tagd[i]
87 for (i = 0; i < 4; ++
i, addr += (1 << 12)) {
101 addr &= (0xff
L << 56) | ((1 << 12) - 1);
102 #define tag cache_tags.tagi[i]
103 for (i = 0; i < 4; ++
i, addr += (1 << 12)) {
114 #define GIO_ERRMASK 0xff00
115 #define CPU_ERRMASK 0x3f00
117 static void save_and_clear_buserr(
void)
122 cpu_err_addr =
sgimc->cerr;
123 cpu_err_stat =
sgimc->cstat;
124 gio_err_addr =
sgimc->gerr;
125 gio_err_stat =
sgimc->gstat;
126 extio_stat =
sgioc->extio;
127 hpc3_berr_stat =
hpc3c0->bestat;
129 hpc3.scsi[0].addr = (
unsigned long)&
hpc3c0->scsi_chan0;
130 hpc3.scsi[0].ctrl =
hpc3c0->scsi_chan0.ctrl;
131 hpc3.scsi[0].cbp =
hpc3c0->scsi_chan0.cbptr;
132 hpc3.scsi[0].ndptr =
hpc3c0->scsi_chan0.ndptr;
134 hpc3.scsi[1].addr = (
unsigned long)&
hpc3c0->scsi_chan1;
135 hpc3.scsi[1].ctrl =
hpc3c0->scsi_chan1.ctrl;
136 hpc3.scsi[1].cbp =
hpc3c0->scsi_chan1.cbptr;
137 hpc3.scsi[1].ndptr =
hpc3c0->scsi_chan1.ndptr;
139 hpc3.ethrx.addr = (
unsigned long)&
hpc3c0->ethregs.rx_cbptr;
140 hpc3.ethrx.ctrl =
hpc3c0->ethregs.rx_ctrl;
141 hpc3.ethrx.cbp =
hpc3c0->ethregs.rx_cbptr;
142 hpc3.ethrx.ndptr =
hpc3c0->ethregs.rx_ndptr;
144 hpc3.ethtx.addr = (
unsigned long)&
hpc3c0->ethregs.tx_cbptr;
145 hpc3.ethtx.ctrl =
hpc3c0->ethregs.tx_ctrl;
146 hpc3.ethtx.cbp =
hpc3c0->ethregs.tx_cbptr;
147 hpc3.ethtx.ndptr =
hpc3c0->ethregs.tx_ndptr;
149 for (i = 0; i < 8; ++
i) {
151 hpc3.pbdma[
i].addr = (
unsigned long)&
hpc3c0->pbdma[i];
152 hpc3.pbdma[i].ctrl =
hpc3c0->pbdma[i].pbdma_ctrl;
153 hpc3.pbdma[i].cbp =
hpc3c0->pbdma[i].pbdma_bptr;
154 hpc3.pbdma[i].ndptr =
hpc3c0->pbdma[i].pbdma_dptr;
159 if (cpu_err_stat & CPU_ERRMASK)
166 static void print_cache_tags(
void)
171 printk(
KERN_ERR "Cache tags @ %08x:\n", (
unsigned)cache_tags.err_addr);
174 scw = (cache_tags.err_addr >> 4) & 0x0fffff00;
176 scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 5) - 1);
177 for (i = 0; i < 4; ++
i) {
178 if ((cache_tags.tagd[i][0].lo & 0x0fffff00) != scw &&
179 (cache_tags.tagd[
i][1].lo & 0x0fffff00) != scw)
182 "D: 0: %08x %08x, 1: %08x %08x (VA[13:5] %04x)\n",
183 cache_tags.tagd[i][0].hi, cache_tags.tagd[i][0].lo,
184 cache_tags.tagd[i][1].hi, cache_tags.tagd[i][1].lo,
187 scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 6) - 1);
188 for (i = 0; i < 4; ++
i) {
189 if ((cache_tags.tagi[i][0].lo & 0x0fffff00) != scw &&
190 (cache_tags.tagi[
i][1].lo & 0x0fffff00) != scw)
193 "I: 0: %08x %08x, 1: %08x %08x (VA[13:6] %04x)\n",
194 cache_tags.tagi[i][0].hi, cache_tags.tagi[i][0].lo,
195 cache_tags.tagi[i][1].hi, cache_tags.tagi[i][1].lo,
199 scb = i & (1 << 13) ? 7:6;
200 scw = ((i >> 16) & 7) + 19 - 1;
202 i = ((1 << scw) - 1) & ~((1 <<
scb) - 1);
203 printk(
KERN_ERR "S: 0: %08x %08x, 1: %08x %08x (PA[%u:%u] %05x)\n",
204 cache_tags.tags[0][0].hi, cache_tags.tags[0][0].lo,
205 cache_tags.tags[0][1].hi, cache_tags.tags[0][1].lo,
206 scw-1, scb, i & (
unsigned)cache_tags.err_addr);
209 static inline const char *cause_excode_text(
int cause)
211 static const char *txt[32] =
214 "TLB (load or instruction fetch)",
216 "Address error (load or instruction fetch)",
217 "Address error (store)",
218 "Bus error (instruction fetch)",
219 "Bus error (data: load or store)",
222 "Reserved instruction",
223 "Coprocessor unusable",
224 "Arithmetic Overflow",
228 "16",
"17",
"18",
"19",
"20",
"21",
"22",
230 "24",
"25",
"26",
"27",
"28",
"29",
"30",
"31",
232 return txt[(cause & 0x7c) >> 2];
235 static void print_buserr(
const struct pt_regs *
regs)
237 const int field = 2 *
sizeof(
unsigned long);
287 "MC: cpuctrl0/1: %08x/%05x, giopar: %04x\n"
288 "MC: cpu/gio_memacc: %08x/%05x, memcfg0/1: %08x/%08x\n",
305 static int addr_is_ram(
unsigned long addr,
unsigned sz)
317 static int check_microtlb(
u32 hi,
u32 lo,
unsigned long vaddr)
324 if ((lo & 2) && (vaddr >> 21) == ((hi<<1) >> 22)) {
327 unsigned int pgsz = (ctl & 2) ? 14:12;
329 unsigned long pte = (lo >> 6) << 12;
330 pte += 8*((vaddr >> pgsz) & 0x1ff);
331 if (addr_is_ram(pte, 8)) {
337 unsigned long a = *(
unsigned long *)
340 a += vaddr & ((1 << pgsz) - 1);
341 return (cpu_err_addr == a);
348 static int check_vdma_memaddr(
void)
350 if (cpu_err_stat & CPU_ERRMASK) {
353 if (!(
sgimc->dma_ctrl & 0x100))
354 return (cpu_err_addr == a);
356 if (check_microtlb(
sgimc->dtlb_hi0,
sgimc->dtlb_lo0, a) ||
357 check_microtlb(
sgimc->dtlb_hi1,
sgimc->dtlb_lo1, a) ||
358 check_microtlb(
sgimc->dtlb_hi2,
sgimc->dtlb_lo2, a) ||
359 check_microtlb(
sgimc->dtlb_hi3,
sgimc->dtlb_lo3, a))
365 static int check_vdma_gioaddr(
void)
367 if (gio_err_stat & GIO_ERRMASK) {
369 a = (
sgimc->gmaddronly & ~a) | (
sgimc->gio_dma_sbits & a);
370 return (gio_err_addr == a);
382 static int ip28_be_interrupt(
const struct pt_regs *regs)
386 save_and_clear_buserr();
399 if (extio_stat & (EXTIO_HPC3_BUSERR | EXTIO_EISA_BUSERR))
414 for (i = 0; i <
sizeof(hpc3)/
sizeof(
struct hpc3_stat); ++
i) {
416 if ((cpu_err_stat & CPU_ERRMASK) &&
417 (cpu_err_addr == hp->
ndptr || cpu_err_addr == hp->
cbp))
419 if ((gio_err_stat & GIO_ERRMASK) &&
420 (gio_err_addr == hp->
ndptr || gio_err_addr == hp->
cbp))
423 if (i <
sizeof(hpc3)/
sizeof(
struct hpc3_stat)) {
426 " ctl %08x, ndp %08x, cbp %08x\n",
431 if (check_vdma_memaddr()) {
436 if (check_vdma_gioaddr()) {
442 if (debug_be_interrupt) {
457 count_be_interrupt++;
463 }
else if (debug_be_interrupt)
467 static int ip28_be_handler(
struct pt_regs *regs,
int is_fixup)
475 save_and_clear_buserr();
479 return ip28_be_interrupt(regs);
489 seq_printf(m,
"IP28 be fixups\t\t: %u\n", count_be_is_fixup);
490 seq_printf(m,
"IP28 be interrupts\t: %u\n", count_be_interrupt);
491 seq_printf(m,
"IP28 be handler\t\t: %u\n", count_be_handler);
496 static int __init debug_be_setup(
char *
str)
498 debug_be_interrupt++;
501 __setup(
"ip28_debug_be", debug_be_setup);