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
- apecs_init
- apecs_pci_clr_err
- apecs_machine_check
1
2
3
4
5
6
7
8
9
10 #include <linux/kernel.h>
11 #include <linux/config.h>
12 #include <linux/types.h>
13 #include <linux/bios32.h>
14 #include <linux/pci.h>
15
16 #include <asm/system.h>
17 #include <asm/io.h>
18 #include <asm/hwrpb.h>
19 #include <asm/ptrace.h>
20
21 extern struct hwrpb_struct *hwrpb;
22 extern asmlinkage void wrmces(unsigned long mces);
23 extern int alpha_sys_type;
24
25
26
27
28 #ifdef CONFIG_ALPHA_APECS
29
30 #ifdef DEBUG
31 # define DBG(args) printk args
32 #else
33 # define DBG(args)
34 #endif
35
36 #define vulp volatile unsigned long *
37 #define vuip volatile unsigned int *
38
39 static volatile unsigned int apecs_mcheck_expected = 0;
40 static volatile unsigned int apecs_mcheck_taken = 0;
41 static unsigned long apecs_jd, apecs_jd1, apecs_jd2;
42
43
44
45
46
47
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 static int mk_conf_addr(unsigned char bus, unsigned char device_fn,
86 unsigned char where, unsigned long *pci_addr,
87 unsigned char *type1)
88 {
89 unsigned long addr;
90
91 DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p, type1=0x%p)\n",
92 bus, device_fn, where, pci_addr, type1));
93
94 if (bus == 0) {
95 int device = device_fn >> 3;
96
97
98
99 if (device > 20) {
100 DBG(("mk_conf_addr: device (%d) > 20, returning -1\n", device));
101 return -1;
102 }
103
104 *type1 = 0;
105 addr = (device_fn << 8) | (where);
106 } else {
107
108 *type1 = 1;
109 addr = (bus << 16) | (device_fn << 8) | (where);
110 }
111 *pci_addr = addr;
112 DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
113 return 0;
114 }
115
116
117 static unsigned int conf_read(unsigned long addr, unsigned char type1)
118 {
119 unsigned long flags;
120 unsigned int stat0, value;
121 unsigned int haxr2 = 0;
122
123 #ifdef CONFIG_ALPHA_SRM
124
125 register long s0 asm ("9");
126 register long s1 asm ("10");
127 register long s2 asm ("11");
128 register long s3 asm ("12");
129 register long s4 asm ("13");
130 register long s5 asm ("14");
131 asm volatile ("# %0" : "r="(s0));
132 asm volatile ("# %0" : "r="(s1));
133 asm volatile ("# %0" : "r="(s2));
134 asm volatile ("# %0" : "r="(s3));
135 asm volatile ("# %0" : "r="(s4));
136 asm volatile ("# %0" : "r="(s5));
137 #endif
138
139 save_flags(flags);
140 cli();
141
142 DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
143
144
145 stat0 = *((volatile unsigned int *)APECS_IOC_DCSR);
146 *((volatile unsigned int *)APECS_IOC_DCSR) = stat0;
147 mb();
148 DBG(("conf_read: APECS DCSR was 0x%x\n", stat0));
149
150 if (type1) {
151 haxr2 = *((unsigned int *)APECS_IOC_HAXR2);
152 mb();
153 *((unsigned int *)APECS_IOC_HAXR2) = haxr2 | 1;
154 DBG(("conf_read: TYPE1 access\n"));
155 }
156
157 draina();
158 apecs_mcheck_expected = 1;
159 apecs_mcheck_taken = 0;
160 mb();
161
162 value = *((volatile unsigned int *)addr);
163 mb();
164 mb();
165 if (apecs_mcheck_taken) {
166 apecs_mcheck_taken = 0;
167 value = 0xffffffffU;
168 mb();
169 }
170 apecs_mcheck_expected = 0;
171 mb();
172
173
174
175
176
177
178 #if 1
179 draina();
180
181
182 stat0 = *((unsigned int *)APECS_IOC_DCSR);
183 DBG(("conf_read: APECS DCSR after read 0x%x\n", stat0));
184 if (stat0 & 0xffe0U) {
185
186 if (!(stat0 & 0x0800)) {
187 printk("apecs.c:conf_read: got stat0=%x\n", stat0);
188 }
189
190
191 *((volatile unsigned long *)APECS_IOC_DCSR) = stat0;
192 mb();
193 wrmces(0x7);
194 value = 0xffffffff;
195 }
196 #endif
197
198
199 if (type1) {
200 *((unsigned int *)APECS_IOC_HAXR2) = haxr2 & ~1;
201 mb();
202 }
203 restore_flags(flags);
204 #ifdef CONFIG_ALPHA_SRM
205
206 asm volatile ("# %0" :: "r"(s0));
207 asm volatile ("# %0" :: "r"(s1));
208 asm volatile ("# %0" :: "r"(s2));
209 asm volatile ("# %0" :: "r"(s3));
210 asm volatile ("# %0" :: "r"(s4));
211 asm volatile ("# %0" :: "r"(s5));
212 #endif
213 return value;
214 }
215
216
217 static void conf_write(unsigned long addr, unsigned int value, unsigned char type1)
218 {
219 unsigned long flags;
220 unsigned int stat0;
221 unsigned int haxr2 = 0;
222
223 save_flags(flags);
224 cli();
225
226
227 stat0 = *((volatile unsigned int *)APECS_IOC_DCSR);
228 *((volatile unsigned int *)APECS_IOC_DCSR) = stat0;
229 mb();
230
231
232 if (type1) {
233 haxr2 = *((unsigned int *)APECS_IOC_HAXR2);
234 mb();
235 *((unsigned int *)APECS_IOC_HAXR2) = haxr2 | 1;
236 }
237
238 draina();
239 apecs_mcheck_expected = 1;
240 mb();
241
242 *((volatile unsigned int *)addr) = value;
243 mb();
244 mb();
245 apecs_mcheck_expected = 0;
246 mb();
247
248
249
250
251
252
253 #if 1
254 draina();
255
256
257 stat0 = *((unsigned int *)APECS_IOC_DCSR);
258 if (stat0 & 0xffe0U) {
259
260 if (!(stat0 & 0x0800)) {
261 printk("apecs.c:conf_write: got stat0=%x\n", stat0);
262 }
263
264
265 *((volatile unsigned long *)APECS_IOC_DCSR) = stat0;
266 mb();
267 wrmces(0x7);
268 }
269 #endif
270
271
272 if (type1) {
273 *((unsigned int *)APECS_IOC_HAXR2) = haxr2 & ~1;
274 mb();
275 }
276 restore_flags(flags);
277 }
278
279
280 int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
281 unsigned char where, unsigned char *value)
282 {
283 unsigned long addr = APECS_CONF;
284 unsigned long pci_addr;
285 unsigned char type1;
286
287 *value = 0xff;
288
289 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
290 return PCIBIOS_SUCCESSFUL;
291 }
292
293 addr |= (pci_addr << 5) + 0x00;
294
295 *value = conf_read(addr, type1) >> ((where & 3) * 8);
296
297 return PCIBIOS_SUCCESSFUL;
298 }
299
300
301 int pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
302 unsigned char where, unsigned short *value)
303 {
304 unsigned long addr = APECS_CONF;
305 unsigned long pci_addr;
306 unsigned char type1;
307
308 *value = 0xffff;
309
310 if (where & 0x1) {
311 return PCIBIOS_BAD_REGISTER_NUMBER;
312 }
313
314 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
315 return PCIBIOS_SUCCESSFUL;
316 }
317
318 addr |= (pci_addr << 5) + 0x08;
319
320 *value = conf_read(addr, type1) >> ((where & 3) * 8);
321 return PCIBIOS_SUCCESSFUL;
322 }
323
324
325 int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
326 unsigned char where, unsigned int *value)
327 {
328 unsigned long addr = APECS_CONF;
329 unsigned long pci_addr;
330 unsigned char type1;
331
332 *value = 0xffffffff;
333 if (where & 0x3) {
334 return PCIBIOS_BAD_REGISTER_NUMBER;
335 }
336
337 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
338 return PCIBIOS_SUCCESSFUL;
339 }
340 addr |= (pci_addr << 5) + 0x18;
341 *value = conf_read(addr, type1);
342 return PCIBIOS_SUCCESSFUL;
343 }
344
345
346 int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
347 unsigned char where, unsigned char value)
348 {
349 unsigned long addr = APECS_CONF;
350 unsigned long pci_addr;
351 unsigned char type1;
352
353 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
354 return PCIBIOS_SUCCESSFUL;
355 }
356 addr |= (pci_addr << 5) + 0x00;
357 conf_write(addr, value << ((where & 3) * 8), type1);
358 return PCIBIOS_SUCCESSFUL;
359 }
360
361
362 int pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
363 unsigned char where, unsigned short value)
364 {
365 unsigned long addr = APECS_CONF;
366 unsigned long pci_addr;
367 unsigned char type1;
368
369 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
370 return PCIBIOS_SUCCESSFUL;
371 }
372 addr |= (pci_addr << 5) + 0x08;
373 conf_write(addr, value << ((where & 3) * 8), type1);
374 return PCIBIOS_SUCCESSFUL;
375 }
376
377
378 int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
379 unsigned char where, unsigned int value)
380 {
381 unsigned long addr = APECS_CONF;
382 unsigned long pci_addr;
383 unsigned char type1;
384
385 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
386 return PCIBIOS_SUCCESSFUL;
387 }
388 addr |= (pci_addr << 5) + 0x18;
389 conf_write(addr, value << ((where & 3) * 8), type1);
390 return PCIBIOS_SUCCESSFUL;
391 }
392
393
394 unsigned long apecs_init(unsigned long mem_start, unsigned long mem_end)
395 {
396
397 #ifdef CONFIG_ALPHA_XL
398
399
400
401
402
403
404
405
406
407
408
409
410
411 *(vuip)APECS_IOC_PB1R = 1U<<19 | (APECS_XL_DMA_WIN1_BASE & 0xfff00000U);
412 *(vuip)APECS_IOC_PM1R = (APECS_XL_DMA_WIN1_SIZE - 1) & 0xfff00000U;
413 *(vuip)APECS_IOC_TB1R = 0;
414
415 *(vuip)APECS_IOC_PB2R = 1U<<19 | (APECS_XL_DMA_WIN2_BASE & 0xfff00000U);
416 *(vuip)APECS_IOC_PM2R = (APECS_XL_DMA_WIN2_SIZE - 1) & 0xfff00000U;
417 *(vuip)APECS_IOC_TB2R = 0;
418
419 #else
420
421
422
423
424
425
426 *(vuip)APECS_IOC_PB2R = 0U;
427
428 *(vuip)APECS_IOC_PB1R = 1U<<19 | (APECS_DMA_WIN_BASE & 0xfff00000U);
429 *(vuip)APECS_IOC_PM1R = (APECS_DMA_WIN_SIZE - 1) & 0xfff00000U;
430 *(vuip)APECS_IOC_TB1R = 0;
431 #endif
432
433 #ifdef CONFIG_ALPHA_CABRIOLET
434
435
436
437
438
439 if (hwrpb->sys_type == ST_DEC_EB64P) {
440 hwrpb->sys_type = ST_DEC_EBPC64;
441 }
442 if (hwrpb->cycle_freq == 0) {
443 hwrpb->cycle_freq = 275000000;
444 }
445
446
447 {
448 unsigned long *l, sum;
449
450 sum = 0;
451 for (l = (unsigned long *) hwrpb; l < (unsigned long *) &hwrpb->chksum; ++l)
452 sum += *l;
453 hwrpb->chksum = sum;
454 }
455 #endif
456
457
458
459
460
461
462
463 {
464 #if 0
465 unsigned int haxr2 = *((unsigned int *)APECS_IOC_HAXR2); mb();
466 if (haxr2) printk("apecs_init: HAXR2 was 0x%x\n", haxr2);
467 #endif
468 *((unsigned int *)APECS_IOC_HAXR2) = 0; mb();
469 }
470
471
472 return mem_start;
473 }
474
475 int apecs_pci_clr_err(void)
476 {
477 apecs_jd = *((unsigned long *)APECS_IOC_DCSR);
478 if (apecs_jd & 0xffe0L) {
479 apecs_jd1 = *((unsigned long *)APECS_IOC_SEAR);
480 *((unsigned long *)APECS_IOC_DCSR) = apecs_jd | 0xffe1L;
481 apecs_jd = *((unsigned long *)APECS_IOC_DCSR);
482 mb();
483 }
484 *((unsigned long *)APECS_IOC_TBIA) = APECS_IOC_TBIA;
485 apecs_jd2 = *((unsigned long *)APECS_IOC_TBIA);
486 mb();
487 return 0;
488 }
489
490 void apecs_machine_check(unsigned long vector, unsigned long la_ptr,
491 struct pt_regs * regs)
492 {
493 struct el_common *mchk_header;
494 struct el_apecs_sysdata_mcheck *mchk_sysdata;
495
496 mchk_header = (struct el_common *)la_ptr;
497
498 mchk_sysdata =
499 (struct el_apecs_sysdata_mcheck *)(la_ptr + mchk_header->sys_offset);
500
501 DBG(("apecs_machine_check: vector=0x%lx la_ptr=0x%lx\n", vector, la_ptr));
502 DBG((" pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
503 regs->pc, mchk_header->size, mchk_header->proc_offset, mchk_header->sys_offset));
504 DBG(("apecs_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
505 apecs_mcheck_expected, mchk_sysdata->epic_dcsr, mchk_sysdata->epic_pear));
506 #ifdef DEBUG
507 {
508 unsigned long *ptr;
509 int i;
510
511 ptr = (unsigned long *)la_ptr;
512 for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
513 printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
514 }
515 }
516 #endif
517
518
519
520
521
522 if (apecs_mcheck_expected && (mchk_sysdata->epic_dcsr && 0x0c00UL)) {
523 apecs_mcheck_expected = 0;
524 apecs_mcheck_taken = 1;
525 mb();
526 mb();
527 apecs_pci_clr_err();
528 wrmces(0x7);
529 mb();
530 draina();
531 }
532 }
533
534 #endif