This source file includes following definitions.
- mk_conf_addr
- conf_read
- conf_write
- pcibios_read_config_byte
- pcibios_read_config_word
- pcibios_read_config_dword
- pcibios_write_config_byte
- pcibios_write_config_word
- pcibios_write_config_dword
- lca_init
- mem_error
- ioc_error
- lca_machine_check
1
2
3
4
5
6
7
8 #include <linux/kernel.h>
9 #include <linux/config.h>
10 #include <linux/types.h>
11 #include <linux/bios32.h>
12 #include <linux/pci.h>
13
14 #include <asm/ptrace.h>
15 #include <asm/system.h>
16 #include <asm/io.h>
17
18
19
20
21
22 #ifdef CONFIG_ALPHA_LCA
23
24 #define vulp volatile unsigned long *
25
26
27
28
29
30 #define MCHK_K_TPERR 0x0080
31 #define MCHK_K_TCPERR 0x0082
32 #define MCHK_K_HERR 0x0084
33 #define MCHK_K_ECC_C 0x0086
34 #define MCHK_K_ECC_NC 0x0088
35 #define MCHK_K_UNKNOWN 0x008A
36 #define MCHK_K_CACKSOFT 0x008C
37 #define MCHK_K_BUGCHECK 0x008E
38 #define MCHK_K_OS_BUGCHECK 0x0090
39 #define MCHK_K_DCPERR 0x0092
40 #define MCHK_K_ICPERR 0x0094
41
42
43
44
45 #define MCHK_K_SIO_SERR 0x204
46 #define MCHK_K_SIO_IOCHK 0x206
47 #define MCHK_K_DCSR 0x208
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 static int mk_conf_addr(unsigned char bus, unsigned char device_fn,
91 unsigned char where, unsigned long *pci_addr)
92 {
93 unsigned long addr;
94
95 if (bus == 0) {
96 int device = device_fn >> 3;
97 int func = device_fn & 0x7;
98
99
100
101 if (device > 12) {
102 return -1;
103 }
104
105 *((volatile unsigned long*) LCA_IOC_CONF) = 0;
106 addr = (1 << (11 + device)) | (func << 8) | where;
107 } else {
108
109 *((volatile unsigned long*) LCA_IOC_CONF) = 1;
110 addr = (bus << 16) | (device_fn << 8) | where;
111 }
112 *pci_addr = addr;
113 return 0;
114 }
115
116
117 static unsigned int conf_read(unsigned long addr)
118 {
119 unsigned long flags, code, stat0;
120 unsigned int value;
121
122 save_flags(flags);
123 cli();
124
125
126 stat0 = *((volatile unsigned long*)LCA_IOC_STAT0);
127 *((volatile unsigned long*)LCA_IOC_STAT0) = stat0;
128 mb();
129
130
131
132 value = *((volatile unsigned int*)addr);
133 draina();
134
135 stat0 = *((unsigned long*)LCA_IOC_STAT0);
136 if (stat0 & LCA_IOC_STAT0_ERR) {
137 code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
138 & LCA_IOC_STAT0_CODE_MASK);
139 if (code != 1) {
140 printk("lca.c:conf_read: got stat0=%lx\n", stat0);
141 }
142
143
144 *((volatile unsigned long*)LCA_IOC_STAT0) = stat0;
145 mb();
146 wrmces(0x7);
147
148 value = 0xffffffff;
149 }
150 restore_flags(flags);
151 return value;
152 }
153
154
155 static void conf_write(unsigned long addr, unsigned int value)
156 {
157 unsigned long flags, code, stat0;
158
159 save_flags(flags);
160 cli();
161
162
163 stat0 = *((volatile unsigned long*)LCA_IOC_STAT0);
164 *((volatile unsigned long*)LCA_IOC_STAT0) = stat0;
165 mb();
166
167
168
169 *((volatile unsigned int*)addr) = value;
170 draina();
171
172 stat0 = *((unsigned long*)LCA_IOC_STAT0);
173 if (stat0 & LCA_IOC_STAT0_ERR) {
174 code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
175 & LCA_IOC_STAT0_CODE_MASK);
176 if (code != 1) {
177 printk("lca.c:conf_write: got stat0=%lx\n", stat0);
178 }
179
180
181 *((volatile unsigned long*)LCA_IOC_STAT0) = stat0;
182 mb();
183 wrmces(0x7);
184 }
185 restore_flags(flags);
186 }
187
188
189 int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
190 unsigned char where, unsigned char *value)
191 {
192 unsigned long addr = LCA_CONF;
193 unsigned long pci_addr;
194
195 *value = 0xff;
196
197 if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
198 return PCIBIOS_SUCCESSFUL;
199 }
200 addr |= (pci_addr << 5) + 0x00;
201 *value = conf_read(addr) >> ((where & 3) * 8);
202 return PCIBIOS_SUCCESSFUL;
203 }
204
205
206 int pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
207 unsigned char where, unsigned short *value)
208 {
209 unsigned long addr = LCA_CONF;
210 unsigned long pci_addr;
211
212 *value = 0xffff;
213
214 if (where & 0x1) {
215 return PCIBIOS_BAD_REGISTER_NUMBER;
216 }
217 if (mk_conf_addr(bus, device_fn, where, &pci_addr)) {
218 return PCIBIOS_SUCCESSFUL;
219 }
220 addr |= (pci_addr << 5) + 0x08;
221 *value = conf_read(addr) >> ((where & 3) * 8);
222 return PCIBIOS_SUCCESSFUL;
223 }
224
225
226 int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
227 unsigned char where, unsigned int *value)
228 {
229 unsigned long addr = LCA_CONF;
230 unsigned long pci_addr;
231
232 *value = 0xffffffff;
233 if (where & 0x3) {
234 return PCIBIOS_BAD_REGISTER_NUMBER;
235 }
236 if (mk_conf_addr(bus, device_fn, where, &pci_addr)) {
237 return PCIBIOS_SUCCESSFUL;
238 }
239 addr |= (pci_addr << 5) + 0x18;
240 *value = conf_read(addr);
241 return PCIBIOS_SUCCESSFUL;
242 }
243
244
245 int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
246 unsigned char where, unsigned char value)
247 {
248 unsigned long addr = LCA_CONF;
249 unsigned long pci_addr;
250
251 if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
252 return PCIBIOS_SUCCESSFUL;
253 }
254 addr |= (pci_addr << 5) + 0x00;
255 conf_write(addr, value << ((where & 3) * 8));
256 return PCIBIOS_SUCCESSFUL;
257 }
258
259
260 int pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
261 unsigned char where, unsigned short value)
262 {
263 unsigned long addr = LCA_CONF;
264 unsigned long pci_addr;
265
266 if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
267 return PCIBIOS_SUCCESSFUL;
268 }
269 addr |= (pci_addr << 5) + 0x08;
270 conf_write(addr, value << ((where & 3) * 8));
271 return PCIBIOS_SUCCESSFUL;
272 }
273
274
275 int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
276 unsigned char where, unsigned int value)
277 {
278 unsigned long addr = LCA_CONF;
279 unsigned long pci_addr;
280
281 if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
282 return PCIBIOS_SUCCESSFUL;
283 }
284 addr |= (pci_addr << 5) + 0x18;
285 conf_write(addr, value << ((where & 3) * 8));
286 return PCIBIOS_SUCCESSFUL;
287 }
288
289
290 unsigned long lca_init(unsigned long mem_start, unsigned long mem_end)
291 {
292
293
294
295
296
297
298 *(vulp)LCA_IOC_W_BASE1 = 0UL<<33;
299 *(vulp)LCA_IOC_W_BASE0 = 1UL<<33 | LCA_DMA_WIN_BASE;
300 *(vulp)LCA_IOC_W_MASK0 = LCA_DMA_WIN_SIZE - 1;
301 *(vulp)LCA_IOC_T_BASE0 = 0;
302
303
304
305
306
307
308 *(vulp)LCA_IOC_PAR_DIS = 1UL<<5;
309 return mem_start;
310 }
311
312
313
314
315
316
317
318
319
320 #define ESR_EAV (1UL<< 0)
321 #define ESR_CEE (1UL<< 1)
322 #define ESR_UEE (1UL<< 2)
323 #define ESR_WRE (1UL<< 3)
324 #define ESR_SOR (1UL<< 4)
325 #define ESR_CTE (1UL<< 7)
326 #define ESR_MSE (1UL<< 9)
327 #define ESR_MHE (1UL<<10)
328 #define ESR_NXM (1UL<<12)
329
330 #define IOC_ERR ( 1<<4)
331 #define IOC_CMD_SHIFT 0
332 #define IOC_CMD (0xf<<IOC_CMD_SHIFT)
333 #define IOC_CODE_SHIFT 8
334 #define IOC_CODE (0xf<<IOC_CODE_SHIFT)
335 #define IOC_LOST ( 1<<5)
336 #define IOC_P_NBR ((__u32) ~((1<<13) - 1))
337
338
339 void mem_error (unsigned long esr, unsigned long ear)
340 {
341 printk(" %s %s error to %s occurred at address %x",
342 (esr & ESR_CEE) ? "Correctable" : ((esr & ESR_UEE) ? "Uncorrectable" : "A"),
343 (esr & ESR_WRE) ? "write" : "read",
344 (esr & ESR_SOR) ? "b-cache" : "memory",
345 (unsigned) (ear & 0x1ffffff8));
346 if (esr & ESR_CTE) {
347 printk(" A b-cache tag parity error was detected.\n");
348 }
349 if (esr & ESR_MSE) {
350 printk(" Several other correctable errors occurred.\n");
351 }
352 if (esr & ESR_MHE) {
353 printk(" Several other uncorrectable errors occurred.\n");
354 }
355 if (esr & ESR_NXM) {
356 printk(" Attempted to access non-existent memory.\n");
357 }
358 }
359
360
361 void ioc_error (__u32 stat0, __u32 stat1)
362 {
363 const char *pci_cmd[] = {
364 "Interrupt Acknowledge", "Special", "I/O Read", "I/O Write",
365 "Rsvd 1", "Rsvd 2", "Memory Read", "Memory Write", "Rsvd3", "Rsvd4",
366 "Configuration Read", "Configuration Write", "Memory Read Multiple",
367 "Dual Address", "Memory Read Line", "Memory Write and Invalidate"
368 };
369 const char *err_name[] = {
370 "exceeded retry limit", "no device", "bad data parity", "target abort",
371 "bad address parity", "page table read error", "invalid page", "data error"
372 };
373 unsigned code = (stat0 & IOC_CODE) >> IOC_CODE_SHIFT;
374 unsigned cmd = (stat0 & IOC_CMD) >> IOC_CMD_SHIFT;
375
376 printk(" %s initiated PCI %s cycle to address %x failed due to %s.\n",
377 code > 3 ? "PCI" : "CPU", pci_cmd[cmd], stat1, err_name[code]);
378 if (code == 5 || code == 6) {
379 printk(" (Error occurred at PCI memory address %x.)\n", (stat0 & ~IOC_P_NBR));
380 }
381 if (stat0 & IOC_LOST) {
382 printk(" Other PCI errors occurred simultaneously.\n");
383 }
384 }
385
386
387 void lca_machine_check (unsigned long vector, unsigned long la, struct pt_regs *regs)
388 {
389 const char * reason;
390 union el_lca el;
391 char buf[128];
392
393 printk("lca: machine check (la=0x%lx,pc=0x%lx)\n", la, regs->pc);
394 el.c = (struct el_common *) la;
395
396
397
398
399
400
401
402 switch (el.s->reason & 0xffffffff) {
403 case MCHK_K_TPERR: reason = "tag parity error"; break;
404 case MCHK_K_TCPERR: reason = "tag something parity error"; break;
405 case MCHK_K_HERR: reason = "access to non-existent memory"; break;
406 case MCHK_K_ECC_C: reason = "correctable ECC error"; break;
407 case MCHK_K_ECC_NC: reason = "non-correctable ECC error"; break;
408 case MCHK_K_CACKSOFT: reason = "MCHK_K_CACKSOFT"; break;
409 case MCHK_K_BUGCHECK: reason = "illegal exception in PAL mode"; break;
410 case MCHK_K_OS_BUGCHECK: reason = "callsys in kernel mode"; break;
411 case MCHK_K_DCPERR: reason = "d-cache parity error"; break;
412 case MCHK_K_ICPERR: reason = "i-cache parity error"; break;
413 case MCHK_K_SIO_SERR: reason = "SIO SERR occurred on on PCI bus"; break;
414 case MCHK_K_SIO_IOCHK: reason = "SIO IOCHK occurred on ISA bus"; break;
415 case MCHK_K_DCSR: reason = "MCHK_K_DCSR"; break;
416 case MCHK_K_UNKNOWN:
417 default:
418 sprintf(buf, "reason for machine-check unknown (0x%lx)",
419 el.s->reason & 0xffffffff);
420 reason = buf;
421 break;
422 }
423
424 wrmces(rdmces());
425
426 switch (el.c->size) {
427 case sizeof(struct el_lca_mcheck_short):
428 printk(" Reason: %s (short frame%s, dc_stat=%lx):\n",
429 reason, el.c->retry ? ", retryable" : "", el.s->dc_stat);
430 if (el.s->esr & ESR_EAV) {
431 mem_error(el.s->esr, el.s->ear);
432 }
433 if (el.s->ioc_stat0 & IOC_ERR) {
434 ioc_error(el.s->ioc_stat0, el.s->ioc_stat1);
435 }
436 break;
437
438 case sizeof(struct el_lca_mcheck_long):
439 printk(" Reason: %s (long frame%s):\n",
440 reason, el.c->retry ? ", retryable" : "");
441 printk(" reason: %lx exc_addr: %lx dc_stat: %lx\n",
442 el.l->pt[0], el.l->exc_addr, el.l->dc_stat);
443 printk(" car: %lx\n", el.l->car);
444 if (el.l->esr & ESR_EAV) {
445 mem_error(el.l->esr, el.l->ear);
446 }
447 if (el.l->ioc_stat0 & IOC_ERR) {
448 ioc_error(el.l->ioc_stat0, el.l->ioc_stat1);
449 }
450 break;
451
452 default:
453 printk(" Unknown errorlog size %d\n", el.c->size);
454 }
455 }
456
457 #endif