Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/mips/sgi-ip22/ip28-berr.c
10817 views
1
/*
2
* ip28-berr.c: Bus error handling.
3
*
4
* Copyright (C) 2002, 2003 Ladislav Michl ([email protected])
5
* Copyright (C) 2005 Peter Fuerst ([email protected]) - 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);
503
504