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
- alcor_init
- ALCOR_pci_clr_err
- alcor_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 #include <linux/sched.h>
14
15 #include <asm/system.h>
16 #include <asm/io.h>
17 #include <asm/hwrpb.h>
18 #include <asm/ptrace.h>
19 #include <asm/mmu_context.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_ALCOR
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 ALCOR_mcheck_expected = 0;
40 static volatile unsigned int ALCOR_mcheck_taken = 0;
41 static unsigned long ALCOR_jd, ALCOR_jd1, ALCOR_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 cia_cfg = 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 *)ALCOR_IOC_CIA_ERR);
130 *((volatile unsigned int *)ALCOR_IOC_CIA_ERR) = stat0;
131 mb();
132 DBG(("conf_read: ALCOR CIA ERR was 0x%x\n", stat0));
133
134 if (type1) {
135 cia_cfg = *((unsigned int *)ALCOR_IOC_CFG);
136 mb();
137 *((unsigned int *)ALCOR_IOC_CFG) = cia_cfg | 1;
138 DBG(("conf_read: TYPE1 access\n"));
139 }
140
141 draina();
142 ALCOR_mcheck_expected = 1;
143 ALCOR_mcheck_taken = 0;
144 mb();
145
146 value = *((volatile unsigned int *)addr);
147 mb();
148 mb();
149 if (ALCOR_mcheck_taken) {
150 ALCOR_mcheck_taken = 0;
151 value = 0xffffffffU;
152 mb();
153 }
154 ALCOR_mcheck_expected = 0;
155 mb();
156
157
158
159
160
161
162 #if 1
163 draina();
164
165
166 stat0 = *((unsigned int *)ALCOR_IOC_CIA_ERR);
167 DBG(("conf_read: ALCOR CIA ERR after read 0x%x\n", stat0));
168 if (stat0 & 0x8280U) {
169
170 if (!(stat0 & 0x0080)) {
171 printk("ALCOR.c:conf_read: got stat0=%x\n", stat0);
172 }
173
174
175 *((volatile unsigned long *)ALCOR_IOC_CIA_ERR) = stat0;
176 mb();
177 wrmces(0x7);
178 value = 0xffffffff;
179 }
180 #endif
181
182
183 if (type1) {
184 *((unsigned int *)ALCOR_IOC_CFG) = cia_cfg & ~1;
185 mb();
186 }
187
188 DBG(("conf_read(): finished\n"));
189
190 restore_flags(flags);
191 return value;
192 }
193
194
195 static void conf_write(unsigned long addr, unsigned int value, unsigned char type1)
196 {
197 unsigned long flags;
198 unsigned int stat0;
199 unsigned int cia_cfg = 0;
200
201 save_flags(flags);
202 cli();
203
204
205 stat0 = *((volatile unsigned int *)ALCOR_IOC_CIA_ERR);
206 *((volatile unsigned int *)ALCOR_IOC_CIA_ERR) = stat0;
207 mb();
208 DBG(("conf_write: ALCOR CIA ERR was 0x%x\n", stat0));
209
210 if (type1) {
211 cia_cfg = *((unsigned int *)ALCOR_IOC_CFG);
212 mb();
213 *((unsigned int *)ALCOR_IOC_CFG) = cia_cfg | 1;
214 DBG(("conf_read: TYPE1 access\n"));
215 }
216
217 draina();
218 ALCOR_mcheck_expected = 1;
219 mb();
220
221 *((volatile unsigned int *)addr) = value;
222 mb();
223 mb();
224 ALCOR_mcheck_expected = 0;
225 mb();
226
227
228
229
230
231
232 #if 1
233 draina();
234
235
236 stat0 = *((unsigned int *)ALCOR_IOC_CIA_ERR);
237 DBG(("conf_write: ALCOR CIA ERR after write 0x%x\n", stat0));
238 if (stat0 & 0x8280U) {
239
240 if (!(stat0 & 0x0080)) {
241 printk("ALCOR.c:conf_read: got stat0=%x\n", stat0);
242 }
243
244
245 *((volatile unsigned long *)ALCOR_IOC_CIA_ERR) = stat0;
246 mb();
247 wrmces(0x7);
248 value = 0xffffffff;
249 }
250 #endif
251
252
253 if (type1) {
254 *((unsigned int *)ALCOR_IOC_CFG) = cia_cfg & ~1;
255 mb();
256 }
257
258 DBG(("conf_write(): finished\n"));
259 restore_flags(flags);
260 }
261
262
263 int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
264 unsigned char where, unsigned char *value)
265 {
266 unsigned long addr = ALCOR_CONF;
267 unsigned long pci_addr;
268 unsigned char type1;
269
270 *value = 0xff;
271
272 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
273 return PCIBIOS_SUCCESSFUL;
274 }
275
276 addr |= (pci_addr << 5) + 0x00;
277
278 *value = conf_read(addr, type1) >> ((where & 3) * 8);
279
280 return PCIBIOS_SUCCESSFUL;
281 }
282
283
284 int pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
285 unsigned char where, unsigned short *value)
286 {
287 unsigned long addr = ALCOR_CONF;
288 unsigned long pci_addr;
289 unsigned char type1;
290
291 *value = 0xffff;
292
293 if (where & 0x1) {
294 return PCIBIOS_BAD_REGISTER_NUMBER;
295 }
296
297 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
298 return PCIBIOS_SUCCESSFUL;
299 }
300
301 addr |= (pci_addr << 5) + 0x08;
302
303 *value = conf_read(addr, type1) >> ((where & 3) * 8);
304 return PCIBIOS_SUCCESSFUL;
305 }
306
307
308 int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
309 unsigned char where, unsigned int *value)
310 {
311 unsigned long addr = ALCOR_CONF;
312 unsigned long pci_addr;
313 unsigned char type1;
314
315 *value = 0xffffffff;
316 if (where & 0x3) {
317 return PCIBIOS_BAD_REGISTER_NUMBER;
318 }
319
320 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
321 return PCIBIOS_SUCCESSFUL;
322 }
323 addr |= (pci_addr << 5) + 0x18;
324 *value = conf_read(addr, type1);
325 return PCIBIOS_SUCCESSFUL;
326 }
327
328
329 int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
330 unsigned char where, unsigned char value)
331 {
332 unsigned long addr = ALCOR_CONF;
333 unsigned long pci_addr;
334 unsigned char type1;
335
336 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
337 return PCIBIOS_SUCCESSFUL;
338 }
339 addr |= (pci_addr << 5) + 0x00;
340 conf_write(addr, value << ((where & 3) * 8), type1);
341 return PCIBIOS_SUCCESSFUL;
342 }
343
344
345 int pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
346 unsigned char where, unsigned short value)
347 {
348 unsigned long addr = ALCOR_CONF;
349 unsigned long pci_addr;
350 unsigned char type1;
351
352 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
353 return PCIBIOS_SUCCESSFUL;
354 }
355 addr |= (pci_addr << 5) + 0x08;
356 conf_write(addr, value << ((where & 3) * 8), type1);
357 return PCIBIOS_SUCCESSFUL;
358 }
359
360
361 int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
362 unsigned char where, unsigned int value)
363 {
364 unsigned long addr = ALCOR_CONF;
365 unsigned long pci_addr;
366 unsigned char type1;
367
368 if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
369 return PCIBIOS_SUCCESSFUL;
370 }
371 addr |= (pci_addr << 5) + 0x18;
372 conf_write(addr, value << ((where & 3) * 8), type1);
373 return PCIBIOS_SUCCESSFUL;
374 }
375
376
377 unsigned long alcor_init(unsigned long mem_start, unsigned long mem_end)
378 {
379 unsigned int cia_err ;
380
381
382
383
384 cia_err = *(vuip)ALCOR_IOC_CIA_ERR ;
385 cia_err |= (0x1 << 7) ;
386 *(vuip)ALCOR_IOC_CIA_ERR = cia_err ;
387 mb() ;
388
389
390
391
392
393
394
395
396 *(vuip)ALCOR_IOC_PCI_W0_BASE = 1U | (ALCOR_DMA_WIN_BASE & 0xfff00000U);
397 *(vuip)ALCOR_IOC_PCI_W0_MASK = (ALCOR_DMA_WIN_SIZE - 1) & 0xfff00000U;
398 *(vuip)ALCOR_IOC_PCI_T0_BASE = 0;
399
400 *(vuip)ALCOR_IOC_PCI_W1_BASE = 0x0 ;
401 *(vuip)ALCOR_IOC_PCI_W2_BASE = 0x0 ;
402 *(vuip)ALCOR_IOC_PCI_W3_BASE = 0x0 ;
403
404
405
406
407 if (hwrpb->max_asn != MAX_ASN) {
408 printk("alcor_init: max ASN from HWRPB is bad (0x%lx)\n",
409 hwrpb->max_asn);
410 hwrpb->max_asn = MAX_ASN;
411 }
412
413 return mem_start;
414 }
415
416 int ALCOR_pci_clr_err(void)
417 {
418 ALCOR_jd = *((unsigned int *)ALCOR_IOC_CIA_ERR);
419 DBG(("ALCOR_pci_clr_err: ALCOR CIA ERR after read 0x%x\n", ALCOR_jd));
420 *((unsigned long *)ALCOR_IOC_CIA_ERR) = 0x0080;
421 mb();
422 return 0;
423 }
424
425 void alcor_machine_check(unsigned long vector, unsigned long la_ptr,
426 struct pt_regs * regs)
427 {
428 #if 1
429 printk("ALCOR machine check\n") ;
430 #else
431 struct el_common *mchk_header;
432 struct el_ALCOR_sysdata_mcheck *mchk_sysdata;
433
434 mchk_header = (struct el_common *)la_ptr;
435
436 mchk_sysdata =
437 (struct el_ALCOR_sysdata_mcheck *)(la_ptr + mchk_header->sys_offset);
438
439 DBG(("ALCOR_machine_check: vector=0x%lx la_ptr=0x%lx\n", vector, la_ptr));
440 DBG((" pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
441 regs->pc, mchk_header->size, mchk_header->proc_offset, mchk_header->sys_offset));
442 DBG(("ALCOR_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
443 ALCOR_mcheck_expected, mchk_sysdata->epic_dcsr, mchk_sysdata->epic_pear));
444 #ifdef DEBUG
445 {
446 unsigned long *ptr;
447 int i;
448
449 ptr = (unsigned long *)la_ptr;
450 for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
451 printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
452 }
453 }
454 #endif
455
456
457
458
459 if (ALCOR_mcheck_expected && (mchk_sysdata->epic_dcsr && 0x0c00UL)) {
460 ALCOR_mcheck_expected = 0;
461 ALCOR_mcheck_taken = 1;
462 mb();
463 mb();
464 ALCOR_pci_clr_err();
465 wrmces(0x7);
466 mb();
467 draina();
468 }
469 #endif
470 }
471
472 #endif