Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[deliverable/linux.git] / arch / mips / dec / ecc-berr.c
CommitLineData
1da177e4
LT
1/*
2 * linux/arch/mips/dec/ecc-berr.c
3 *
4 * Bus error event handling code for systems equipped with ECC
5 * handling logic, i.e. DECstation/DECsystem 5000/200 (KN02),
6 * 5000/240 (KN03), 5000/260 (KN05) and DECsystem 5900 (KN03),
7 * 5900/260 (KN05) systems.
8 *
64dac503 9 * Copyright (c) 2003, 2005 Maciej W. Rozycki
1da177e4
LT
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 */
16
17#include <linux/init.h>
64dac503 18#include <linux/interrupt.h>
1da177e4
LT
19#include <linux/kernel.h>
20#include <linux/sched.h>
1da177e4
LT
21#include <linux/types.h>
22
23#include <asm/addrspace.h>
24#include <asm/bootinfo.h>
25#include <asm/cpu.h>
6dab2f45 26#include <asm/irq_regs.h>
1da177e4
LT
27#include <asm/processor.h>
28#include <asm/system.h>
29#include <asm/traps.h>
30
31#include <asm/dec/ecc.h>
32#include <asm/dec/kn02.h>
33#include <asm/dec/kn03.h>
34#include <asm/dec/kn05.h>
35
36static volatile u32 *kn0x_erraddr;
37static volatile u32 *kn0x_chksyn;
38
39static inline void dec_ecc_be_ack(void)
40{
41 *kn0x_erraddr = 0; /* any write clears the IRQ */
42 iob();
43}
44
45static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
46{
47 static const char excstr[] = "exception";
48 static const char intstr[] = "interrupt";
49 static const char cpustr[] = "CPU";
50 static const char dmastr[] = "DMA";
51 static const char readstr[] = "read";
52 static const char mreadstr[] = "memory read";
53 static const char writestr[] = "write";
54 static const char mwritstr[] = "partial memory write";
55 static const char timestr[] = "timeout";
56 static const char overstr[] = "overrun";
57 static const char eccstr[] = "ECC error";
58
59 const char *kind, *agent, *cycle, *event;
60 const char *status = "", *xbit = "", *fmt = "";
64dac503 61 unsigned long address;
1da177e4
LT
62 u16 syn = 0, sngl;
63
64 int i = 0;
65
66 u32 erraddr = *kn0x_erraddr;
67 u32 chksyn = *kn0x_chksyn;
68 int action = MIPS_BE_FATAL;
69
64dac503 70 /* For non-ECC ack ASAP, so that any subsequent errors get caught. */
1da177e4
LT
71 if ((erraddr & (KN0X_EAR_VALID | KN0X_EAR_ECCERR)) == KN0X_EAR_VALID)
72 dec_ecc_be_ack();
73
74 kind = invoker ? intstr : excstr;
75
76 if (!(erraddr & KN0X_EAR_VALID)) {
77 /* No idea what happened. */
64dac503 78 printk(KERN_ALERT "Unidentified bus error %s\n", kind);
1da177e4
LT
79 return action;
80 }
81
82 agent = (erraddr & KN0X_EAR_CPU) ? cpustr : dmastr;
83
84 if (erraddr & KN0X_EAR_ECCERR) {
85 /* An ECC error on a CPU or DMA transaction. */
86 cycle = (erraddr & KN0X_EAR_WRITE) ? mwritstr : mreadstr;
87 event = eccstr;
88 } else {
89 /* A CPU timeout or a DMA overrun. */
90 cycle = (erraddr & KN0X_EAR_WRITE) ? writestr : readstr;
91 event = (erraddr & KN0X_EAR_CPU) ? timestr : overstr;
92 }
93
94 address = erraddr & KN0X_EAR_ADDRESS;
95 /* For ECC errors on reads adjust for MT pipelining. */
96 if ((erraddr & (KN0X_EAR_WRITE | KN0X_EAR_ECCERR)) == KN0X_EAR_ECCERR)
97 address = (address & ~0xfffLL) | ((address - 5) & 0xfffLL);
98 address <<= 2;
99
100 /* Only CPU errors are fixable. */
101 if (erraddr & KN0X_EAR_CPU && is_fixup)
102 action = MIPS_BE_FIXUP;
103
104 if (erraddr & KN0X_EAR_ECCERR) {
105 static const u8 data_sbit[32] = {
106 0x4f, 0x4a, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d,
107 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x31, 0x34,
108 0x0e, 0x0b, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c,
109 0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x70, 0x75,
110 };
111 static const u8 data_mbit[25] = {
112 0x07, 0x0d, 0x1f,
113 0x2f, 0x32, 0x37, 0x38, 0x3b, 0x3d, 0x3e,
114 0x43, 0x45, 0x46, 0x49, 0x4c, 0x51, 0x5e,
115 0x61, 0x6e, 0x73, 0x76, 0x79, 0x7a, 0x7c, 0x7f,
116 };
117 static const char sbestr[] = "corrected single";
118 static const char dbestr[] = "uncorrectable double";
119 static const char mbestr[] = "uncorrectable multiple";
120
121 if (!(address & 0x4))
122 syn = chksyn; /* Low bank. */
123 else
124 syn = chksyn >> 16; /* High bank. */
125
126 if (!(syn & KN0X_ESR_VLDLO)) {
127 /* Ack now, no rewrite will happen. */
128 dec_ecc_be_ack();
129
64dac503 130 fmt = KERN_ALERT "%s" "invalid\n";
1da177e4
LT
131 } else {
132 sngl = syn & KN0X_ESR_SNGLO;
133 syn &= KN0X_ESR_SYNLO;
134
135 /*
136 * Multibit errors may be tagged incorrectly;
137 * check the syndrome explicitly.
138 */
139 for (i = 0; i < 25; i++)
140 if (syn == data_mbit[i])
141 break;
142
143 if (i < 25) {
144 status = mbestr;
145 } else if (!sngl) {
146 status = dbestr;
147 } else {
3bd4c902
MR
148 volatile u32 *ptr =
149 (void *)CKSEG1ADDR(address);
1da177e4
LT
150
151 *ptr = *ptr; /* Rewrite. */
152 iob();
153
154 status = sbestr;
155 action = MIPS_BE_DISCARD;
156 }
157
158 /* Ack now, now we've rewritten (or not). */
159 dec_ecc_be_ack();
160
161 if (syn && syn == (syn & -syn)) {
162 if (syn == 0x01) {
163 fmt = KERN_ALERT "%s"
164 "%#04x -- %s bit error "
64dac503 165 "at check bit C%s\n";
1da177e4
LT
166 xbit = "X";
167 } else {
168 fmt = KERN_ALERT "%s"
169 "%#04x -- %s bit error "
64dac503 170 "at check bit C%s%u\n";
1da177e4
LT
171 }
172 i = syn >> 2;
173 } else {
174 for (i = 0; i < 32; i++)
175 if (syn == data_sbit[i])
176 break;
177 if (i < 32)
178 fmt = KERN_ALERT "%s"
179 "%#04x -- %s bit error "
64dac503 180 "at data bit D%s%u\n";
1da177e4
LT
181 else
182 fmt = KERN_ALERT "%s"
64dac503 183 "%#04x -- %s bit error\n";
1da177e4
LT
184 }
185 }
186 }
187
188 if (action != MIPS_BE_FIXUP)
64dac503 189 printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
1da177e4
LT
190 kind, agent, cycle, event, address);
191
192 if (action != MIPS_BE_FIXUP && erraddr & KN0X_EAR_ECCERR)
193 printk(fmt, " ECC syndrome ", syn, status, xbit, i);
194
195 return action;
196}
197
198int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup)
199{
200 return dec_ecc_be_backend(regs, is_fixup, 0);
201}
202
6dab2f45 203irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id)
1da177e4 204{
6dab2f45
RB
205 struct pt_regs *regs = get_irq_regs();
206
1da177e4
LT
207 int action = dec_ecc_be_backend(regs, 0, 1);
208
209 if (action == MIPS_BE_DISCARD)
68e4a86c 210 return IRQ_HANDLED;
1da177e4
LT
211
212 /*
64dac503
MR
213 * FIXME: Find the affected processes and kill them, otherwise
214 * we must die.
1da177e4
LT
215 *
216 * The interrupt is asynchronously delivered thus EPC and RA
217 * may be irrelevant, but are printed for a reference.
218 */
219 printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n",
220 regs->cp0_epc, regs->regs[31]);
221 die("Unrecoverable bus error", regs);
222}
223
224
225/*
226 * Initialization differs a bit between KN02 and KN03/KN05, so we
227 * need two variants. Once set up, all systems can be handled the
228 * same way.
229 */
230static inline void dec_kn02_be_init(void)
231{
a5fc9c0b 232 volatile u32 *csr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR);
1da177e4 233
a5fc9c0b
MR
234 kn0x_erraddr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_ERRADDR);
235 kn0x_chksyn = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CHKSYN);
1da177e4 236
1da177e4 237 /* Preset write-only bits of the Control Register cache. */
64dac503 238 cached_kn02_csr = *csr | KN02_CSR_LEDS;
1da177e4
LT
239
240 /* Set normal ECC detection and generation. */
241 cached_kn02_csr &= ~(KN02_CSR_DIAGCHK | KN02_CSR_DIAGGEN);
242 /* Enable ECC correction. */
243 cached_kn02_csr |= KN02_CSR_CORRECT;
244 *csr = cached_kn02_csr;
245 iob();
1da177e4
LT
246}
247
248static inline void dec_kn03_be_init(void)
249{
a5fc9c0b
MR
250 volatile u32 *mcr = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_MCR);
251 volatile u32 *mbcs = (void *)CKSEG1ADDR(KN4K_SLOT_BASE + KN4K_MB_CSR);
1da177e4 252
a5fc9c0b
MR
253 kn0x_erraddr = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_ERRADDR);
254 kn0x_chksyn = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_CHKSYN);
42a3b4f2 255
1da177e4
LT
256 /*
257 * Set normal ECC detection and generation, enable ECC correction.
258 * For KN05 we also need to make sure EE (?) is enabled in the MB.
259 * Otherwise DBE/IBE exceptions would be masked but bus error
260 * interrupts would still arrive, resulting in an inevitable crash
261 * if get_dbe() triggers one.
262 */
263 *mcr = (*mcr & ~(KN03_MCR_DIAGCHK | KN03_MCR_DIAGGEN)) |
264 KN03_MCR_CORRECT;
265 if (current_cpu_data.cputype == CPU_R4400SC)
64dac503 266 *mbcs |= KN4K_MB_CSR_EE;
1da177e4
LT
267 fast_iob();
268}
269
270void __init dec_ecc_be_init(void)
271{
272 if (mips_machtype == MACH_DS5000_200)
273 dec_kn02_be_init();
274 else
275 dec_kn03_be_init();
276
277 /* Clear any leftover errors from the firmware. */
278 dec_ecc_be_ack();
279}
This page took 0.177156 seconds and 5 git commands to generate.