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
- 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 return mem_start;
303 }
304
305
306
307
308
309
310
311
312
313 #define ESR_EAV (1UL<< 0)
314 #define ESR_CEE (1UL<< 1)
315 #define ESR_UEE (1UL<< 2)
316 #define ESR_NXM (1UL<<12)
317
318
319 void lca_machine_check (unsigned long vector, unsigned long la, struct pt_regs *regs)
320 {
321 const char * reason;
322 union el_lca el;
323 char buf[128];
324
325 printk("lca: machine check (la=0x%lx)\n", la);
326 el.c = (struct el_common *) la;
327
328
329
330
331
332 switch (el.s->reason) {
333 case MCHK_K_TPERR: reason = "tag parity error"; break;
334 case MCHK_K_TCPERR: reason = "tag something parity error"; break;
335 case MCHK_K_HERR: reason = "access to non-existent memory"; break;
336 case MCHK_K_ECC_C: reason = "correctable ECC error"; break;
337 case MCHK_K_ECC_NC: reason = "non-correctable ECC error"; break;
338 case MCHK_K_CACKSOFT: reason = "MCHK_K_CACKSOFT"; break;
339 case MCHK_K_BUGCHECK: reason = "illegal exception in PAL mode"; break;
340 case MCHK_K_OS_BUGCHECK: reason = "callsys in kernel mode"; break;
341 case MCHK_K_DCPERR: reason = "d-cache parity error"; break;
342 case MCHK_K_ICPERR: reason = "i-cache parity error"; break;
343 case MCHK_K_SIO_SERR: reason = "SIO SERR occurred on on PCI bus"; break;
344 case MCHK_K_SIO_IOCHK: reason = "SIO IOCHK occurred on ISA bus"; break;
345 case MCHK_K_DCSR: reason = "MCHK_K_DCSR"; break;
346 case MCHK_K_UNKNOWN:
347 default:
348 sprintf(buf, "reason for machine-check unknown (0x%lx)", el.s->reason);
349 reason = buf;
350 break;
351 }
352
353 wrmces(rdmces());
354
355 switch (el.c->size) {
356 case sizeof(struct el_lca_mcheck_short):
357 printk(" Reason: %s (short frame%s):\n",
358 reason, el.c->retry ? ", retryable" : "");
359 printk(" esr: %lx ear: %lx\n", el.s->esr, el.s->ear);
360 printk(" dc_stat: %lx ioc_stat0: %lx ioc_stat1: %lx\n",
361 el.s->dc_stat, el.s->ioc_stat0, el.s->ioc_stat1);
362 if (el.c->retry &&
363 (el.s->esr & (ESR_EAV|ESR_CEE|ESR_UEE|ESR_NXM)) == (ESR_EAV|ESR_CEE))
364 {
365 unsigned long addr, val;
366
367
368 wrmces(0x18);
369 addr = el.s->ear & ~ (0x7<<29 | 0x7);
370 addr += IDENT_ADDR;
371 printk(" correcting quadword at address %lx\n", addr);
372 val = *(volatile long *)addr;
373 *(volatile long *)addr = val;
374
375 wrmces(0x00);
376 }
377 break;
378
379 case sizeof(struct el_lca_mcheck_long):
380 printk(" Reason: %s (long frame%s):\n",
381 reason, el.c->retry ? ", retryable" : "");
382 printk(" reason: %lx exc_addr: %lx dc_stat: %lx\n",
383 el.l->pt[0], el.l->exc_addr, el.l->dc_stat);
384 printk(" esr: %lx ear: %lx car: %lx\n", el.l->esr, el.l->ear, el.l->car);
385 printk(" ioc_stat0: %lx ioc_stat1: %lx\n", el.l->ioc_stat0, el.l->ioc_stat1);
386 break;
387
388 default:
389 printk(" Unknown errorlog size %d\n", el.c->size);
390 }
391 }
392
393 #endif