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