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