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_AVANTI
124 register long s0 asm ("9");
125 register long s1 asm ("10");
126 register long s2 asm ("11");
127 register long s3 asm ("12");
128 register long s4 asm ("13");
129 register long s5 asm ("14");
130 asm volatile ("# %0" : "r="(s0));
131 asm volatile ("# %0" : "r="(s1));
132 asm volatile ("# %0" : "r="(s2));
133 asm volatile ("# %0" : "r="(s3));
134 asm volatile ("# %0" : "r="(s4));
135 asm volatile ("# %0" : "r="(s5));
136 #endif
137
138 save_flags(flags);
139 cli();
140
141 DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
142
143
144 stat0 = *((volatile unsigned int *)APECS_IOC_DCSR);
145 *((volatile unsigned int *)APECS_IOC_DCSR) = stat0;
146 mb();
147 DBG(("conf_read: APECS DCSR was 0x%x\n", stat0));
148
149 if (type1) {
150 haxr2 = *((unsigned int *)APECS_IOC_HAXR2);
151 mb();
152 *((unsigned int *)APECS_IOC_HAXR2) = haxr2 | 1;
153 DBG(("conf_read: TYPE1 access\n"));
154 }
155
156 draina();
157 apecs_mcheck_expected = 1;
158 apecs_mcheck_taken = 0;
159 mb();
160
161 value = *((volatile unsigned int *)addr);
162 mb();
163 mb();
164 if (apecs_mcheck_taken) {
165 apecs_mcheck_taken = 0;
166 value = 0xffffffffU;
167 mb();
168 }
169 apecs_mcheck_expected = 0;
170 mb();
171
172
173
174
175
176
177 #if 1
178 draina();
179
180
181 stat0 = *((unsigned int *)APECS_IOC_DCSR);
182 DBG(("conf_read: APECS DCSR after read 0x%x\n", stat0));
183 if (stat0 & 0xffe0U) {
184
185 if (!(stat0 & 0x0800)) {
186 printk("apecs.c:conf_read: got stat0=%x\n", stat0);
187 }
188
189
190 *((volatile unsigned long *)APECS_IOC_DCSR) = stat0;
191 mb();
192 wrmces(0x7);
193 value = 0xffffffff;
194 }
195 #endif
196
197
198 if (type1) {
199 *((unsigned int *)APECS_IOC_HAXR2) = haxr2 & ~1;
200 mb();
201 }
202 restore_flags(flags);
203 #ifdef CONFIG_ALPHA_AVANTI
204 asm volatile ("# %0" :: "r"(s0));
205 asm volatile ("# %0" :: "r"(s1));
206 asm volatile ("# %0" :: "r"(s2));
207 asm volatile ("# %0" :: "r"(s3));
208 asm volatile ("# %0" :: "r"(s4));
209 asm volatile ("# %0" :: "r"(s5));
210 #endif
211 return value;
212 }
213
214
215 static void conf_write(unsigned long addr, unsigned int value, unsigned char type1)
216 {
217 unsigned long flags;
218 unsigned int stat0;
219 unsigned int haxr2 = 0;
220
221 save_flags(flags);
222 cli();
223
224
225 stat0 = *((volatile unsigned int *)APECS_IOC_DCSR);
226 *((volatile unsigned int *)APECS_IOC_DCSR) = stat0;
227 mb();
228
229
230 if (type1) {
231 haxr2 = *((unsigned int *)APECS_IOC_HAXR2);
232 mb();
233 *((unsigned int *)APECS_IOC_HAXR2) = haxr2 | 1;
234 }
235
236 draina();
237 apecs_mcheck_expected = 1;
238 mb();
239
240 *((volatile unsigned int *)addr) = value;
241 mb();
242 mb();
243 apecs_mcheck_expected = 0;
244 mb();
245
246
247
248
249
250
251 #if 1
252 draina();
253
254
255 stat0 = *((unsigned int *)APECS_IOC_DCSR);
256 if (stat0 & 0xffe0U) {
257
258 if (!(stat0 & 0x0800)) {
259 printk("apecs.c:conf_write: got stat0=%x\n", stat0);
260 }
261
262
263 *((volatile unsigned long *)APECS_IOC_DCSR) = stat0;
264 mb();
265 wrmces(0x7);
266 }
267 #endif
268
269
270 if (type1) {
271 *((unsigned int *)APECS_IOC_HAXR2) = haxr2 & ~1;
272 mb();
273 }
274 restore_flags(flags);
275 }
276
277
278 int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
279 unsigned char where, unsigned char *value)
280 {
281 unsigned long addr = APECS_CONF;
282 unsigned long pci_addr;
283 unsigned char type1;
284
285 *value = 0xff;
286
287 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
288 return PCIBIOS_SUCCESSFUL;
289 }
290
291 addr |= (pci_addr << 5) + 0x00;
292
293 *value = conf_read(addr, type1) >> ((where & 3) * 8);
294
295 return PCIBIOS_SUCCESSFUL;
296 }
297
298
299 int pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
300 unsigned char where, unsigned short *value)
301 {
302 unsigned long addr = APECS_CONF;
303 unsigned long pci_addr;
304 unsigned char type1;
305
306 *value = 0xffff;
307
308 if (where & 0x1) {
309 return PCIBIOS_BAD_REGISTER_NUMBER;
310 }
311
312 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
313 return PCIBIOS_SUCCESSFUL;
314 }
315
316 addr |= (pci_addr << 5) + 0x08;
317
318 *value = conf_read(addr, type1) >> ((where & 3) * 8);
319 return PCIBIOS_SUCCESSFUL;
320 }
321
322
323 int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
324 unsigned char where, unsigned int *value)
325 {
326 unsigned long addr = APECS_CONF;
327 unsigned long pci_addr;
328 unsigned char type1;
329
330 *value = 0xffffffff;
331 if (where & 0x3) {
332 return PCIBIOS_BAD_REGISTER_NUMBER;
333 }
334
335 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
336 return PCIBIOS_SUCCESSFUL;
337 }
338 addr |= (pci_addr << 5) + 0x18;
339 *value = conf_read(addr, type1);
340 return PCIBIOS_SUCCESSFUL;
341 }
342
343
344 int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
345 unsigned char where, unsigned char value)
346 {
347 unsigned long addr = APECS_CONF;
348 unsigned long pci_addr;
349 unsigned char type1;
350
351 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
352 return PCIBIOS_SUCCESSFUL;
353 }
354 addr |= (pci_addr << 5) + 0x00;
355 conf_write(addr, value << ((where & 3) * 8), type1);
356 return PCIBIOS_SUCCESSFUL;
357 }
358
359
360 int pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
361 unsigned char where, unsigned short value)
362 {
363 unsigned long addr = APECS_CONF;
364 unsigned long pci_addr;
365 unsigned char type1;
366
367 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
368 return PCIBIOS_SUCCESSFUL;
369 }
370 addr |= (pci_addr << 5) + 0x08;
371 conf_write(addr, value << ((where & 3) * 8), type1);
372 return PCIBIOS_SUCCESSFUL;
373 }
374
375
376 int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
377 unsigned char where, unsigned int value)
378 {
379 unsigned long addr = APECS_CONF;
380 unsigned long pci_addr;
381 unsigned char type1;
382
383 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
384 return PCIBIOS_SUCCESSFUL;
385 }
386 addr |= (pci_addr << 5) + 0x18;
387 conf_write(addr, value << ((where & 3) * 8), type1);
388 return PCIBIOS_SUCCESSFUL;
389 }
390
391
392 unsigned long apecs_init(unsigned long mem_start, unsigned long mem_end)
393 {
394
395
396
397
398
399
400 *(vuip)APECS_IOC_PB2R = 0U;
401
402 *(vuip)APECS_IOC_PB1R = 1U<<19 | (APECS_DMA_WIN_BASE & 0xfff00000U);
403 *(vuip)APECS_IOC_PM1R = (APECS_DMA_WIN_SIZE - 1) & 0xfff00000U;
404 *(vuip)APECS_IOC_TB1R = 0;
405
406 #ifdef CONFIG_ALPHA_CABRIOLET
407
408
409
410
411
412 if (hwrpb->sys_type == ST_DEC_EB64P) {
413 hwrpb->sys_type = ST_DEC_EBPC64;
414 }
415 if (hwrpb->cycle_freq == 0) {
416 hwrpb->cycle_freq = 275000000;
417 }
418
419
420 {
421 unsigned long *l, sum;
422
423 sum = 0;
424 for (l = (unsigned long *) hwrpb; l < (unsigned long *) &hwrpb->chksum; ++l)
425 sum += *l;
426 hwrpb->chksum = sum;
427 }
428 #endif
429 return mem_start;
430 }
431
432 int apecs_pci_clr_err(void)
433 {
434 apecs_jd = *((unsigned long *)APECS_IOC_DCSR);
435 if (apecs_jd & 0xffe0L) {
436 apecs_jd1 = *((unsigned long *)APECS_IOC_SEAR);
437 *((unsigned long *)APECS_IOC_DCSR) = apecs_jd | 0xffe1L;
438 apecs_jd = *((unsigned long *)APECS_IOC_DCSR);
439 mb();
440 }
441 *((unsigned long *)APECS_IOC_TBIA) = APECS_IOC_TBIA;
442 apecs_jd2 = *((unsigned long *)APECS_IOC_TBIA);
443 mb();
444 return 0;
445 }
446
447 void apecs_machine_check(unsigned long vector, unsigned long la_ptr,
448 struct pt_regs * regs)
449 {
450 struct el_common *mchk_header;
451 struct el_apecs_sysdata_mcheck *mchk_sysdata;
452
453 mchk_header = (struct el_common *)la_ptr;
454
455 mchk_sysdata =
456 (struct el_apecs_sysdata_mcheck *)(la_ptr + mchk_header->sys_offset);
457
458 DBG(("apecs_machine_check: vector=0x%lx la_ptr=0x%lx\n", vector, la_ptr));
459 DBG((" pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
460 regs->pc, mchk_header->size, mchk_header->proc_offset, mchk_header->sys_offset));
461 DBG(("apecs_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
462 apecs_mcheck_expected, mchk_sysdata->epic_dcsr, mchk_sysdata->epic_pear));
463 #ifdef DEBUG
464 {
465 unsigned long *ptr;
466 int i;
467
468 ptr = (unsigned long *)la_ptr;
469 for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
470 printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
471 }
472 }
473 #endif
474
475
476
477
478
479 if (apecs_mcheck_expected && (mchk_sysdata->epic_dcsr && 0x0c00UL)) {
480 apecs_mcheck_expected = 0;
481 apecs_mcheck_taken = 1;
482 mb();
483 mb();
484 apecs_pci_clr_err();
485 wrmces(0x7);
486 mb();
487 draina();
488 }
489 }
490
491 #endif