1
2
3
4
5
6
7
8
9
10
11
12#define __EXTERN_INLINE
13#include <asm/io.h>
14#include <asm/core_t2.h>
15#undef __EXTERN_INLINE
16
17#include <linux/types.h>
18#include <linux/pci.h>
19#include <linux/sched.h>
20#include <linux/init.h>
21
22#include <asm/ptrace.h>
23#include <asm/delay.h>
24#include <asm/mce.h>
25
26#include "proto.h"
27#include "pci_impl.h"
28
29
30#define DEBUG_PRINT_INITIAL_SETTINGS 0
31
32
33#define DEBUG_PRINT_FINAL_SETTINGS 0
34
35
36
37
38
39
40
41
42
43
44
45
46#define T2_DIRECTMAP_2G 1
47
48#if T2_DIRECTMAP_2G
49# define T2_DIRECTMAP_START 0x80000000UL
50# define T2_DIRECTMAP_LENGTH 0x80000000UL
51#else
52# define T2_DIRECTMAP_START 0x40000000UL
53# define T2_DIRECTMAP_LENGTH 0x40000000UL
54#endif
55
56
57#define T2_ISA_SG_START 0x00800000UL
58#define T2_ISA_SG_LENGTH 0x00800000UL
59
60
61
62
63
64
65
66
67
68
69
70#define DEBUG_CONFIG 0
71
72#if DEBUG_CONFIG
73# define DBG(args) printk args
74#else
75# define DBG(args)
76#endif
77
78static volatile unsigned int t2_mcheck_any_expected;
79static volatile unsigned int t2_mcheck_last_taken;
80
81
82
83static struct
84{
85 struct {
86 unsigned long wbase;
87 unsigned long wmask;
88 unsigned long tbase;
89 } window[2];
90 unsigned long hae_1;
91 unsigned long hae_2;
92 unsigned long hae_3;
93 unsigned long hae_4;
94 unsigned long hbase;
95} t2_saved_config __attribute((common));
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139static int
140mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
141 unsigned long *pci_addr, unsigned char *type1)
142{
143 unsigned long addr;
144 u8 bus = pbus->number;
145
146 DBG(("mk_conf_addr(bus=%d, dfn=0x%x, where=0x%x,"
147 " addr=0x%lx, type1=0x%x)\n",
148 bus, device_fn, where, pci_addr, type1));
149
150 if (bus == 0) {
151 int device = device_fn >> 3;
152
153
154
155 if (device > 8) {
156 DBG(("mk_conf_addr: device (%d)>20, returning -1\n",
157 device));
158 return -1;
159 }
160
161 *type1 = 0;
162 addr = (0x0800L << device) | ((device_fn & 7) << 8) | (where);
163 } else {
164
165 *type1 = 1;
166 addr = (bus << 16) | (device_fn << 8) | (where);
167 }
168 *pci_addr = addr;
169 DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
170 return 0;
171}
172
173
174
175
176
177
178
179static unsigned int
180conf_read(unsigned long addr, unsigned char type1)
181{
182 unsigned int value, cpu, taken;
183 unsigned long t2_cfg = 0;
184
185 cpu = smp_processor_id();
186
187 DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
188
189
190 if (type1) {
191 t2_cfg = *(vulp)T2_HAE_3 & ~0xc0000000UL;
192 *(vulp)T2_HAE_3 = 0x40000000UL | t2_cfg;
193 mb();
194 }
195 mb();
196 draina();
197
198 mcheck_expected(cpu) = 1;
199 mcheck_taken(cpu) = 0;
200 t2_mcheck_any_expected |= (1 << cpu);
201 mb();
202
203
204 value = *(vuip)addr;
205 mb();
206 mb();
207
208
209
210
211
212 udelay(100);
213
214 if ((taken = mcheck_taken(cpu))) {
215 mcheck_taken(cpu) = 0;
216 t2_mcheck_last_taken |= (1 << cpu);
217 value = 0xffffffffU;
218 mb();
219 }
220 mcheck_expected(cpu) = 0;
221 t2_mcheck_any_expected = 0;
222 mb();
223
224
225 if (type1) {
226 *(vulp)T2_HAE_3 = t2_cfg;
227 mb();
228 }
229
230 return value;
231}
232
233static void
234conf_write(unsigned long addr, unsigned int value, unsigned char type1)
235{
236 unsigned int cpu, taken;
237 unsigned long t2_cfg = 0;
238
239 cpu = smp_processor_id();
240
241
242 if (type1) {
243 t2_cfg = *(vulp)T2_HAE_3 & ~0xc0000000UL;
244 *(vulp)T2_HAE_3 = t2_cfg | 0x40000000UL;
245 mb();
246 }
247 mb();
248 draina();
249
250 mcheck_expected(cpu) = 1;
251 mcheck_taken(cpu) = 0;
252 t2_mcheck_any_expected |= (1 << cpu);
253 mb();
254
255
256 *(vuip)addr = value;
257 mb();
258 mb();
259
260
261
262
263
264 udelay(100);
265
266 if ((taken = mcheck_taken(cpu))) {
267 mcheck_taken(cpu) = 0;
268 t2_mcheck_last_taken |= (1 << cpu);
269 mb();
270 }
271 mcheck_expected(cpu) = 0;
272 t2_mcheck_any_expected = 0;
273 mb();
274
275
276 if (type1) {
277 *(vulp)T2_HAE_3 = t2_cfg;
278 mb();
279 }
280}
281
282static int
283t2_read_config(struct pci_bus *bus, unsigned int devfn, int where,
284 int size, u32 *value)
285{
286 unsigned long addr, pci_addr;
287 unsigned char type1;
288 int shift;
289 long mask;
290
291 if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
292 return PCIBIOS_DEVICE_NOT_FOUND;
293
294 mask = (size - 1) * 8;
295 shift = (where & 3) * 8;
296 addr = (pci_addr << 5) + mask + T2_CONF;
297 *value = conf_read(addr, type1) >> (shift);
298 return PCIBIOS_SUCCESSFUL;
299}
300
301static int
302t2_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
303 u32 value)
304{
305 unsigned long addr, pci_addr;
306 unsigned char type1;
307 long mask;
308
309 if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
310 return PCIBIOS_DEVICE_NOT_FOUND;
311
312 mask = (size - 1) * 8;
313 addr = (pci_addr << 5) + mask + T2_CONF;
314 conf_write(addr, value << ((where & 3) * 8), type1);
315 return PCIBIOS_SUCCESSFUL;
316}
317
318struct pci_ops t2_pci_ops =
319{
320 .read = t2_read_config,
321 .write = t2_write_config,
322};
323
324static void __init
325t2_direct_map_window1(unsigned long base, unsigned long length)
326{
327 unsigned long temp;
328
329 __direct_map_base = base;
330 __direct_map_size = length;
331
332 temp = (base & 0xfff00000UL) | ((base + length - 1) >> 20);
333 *(vulp)T2_WBASE1 = temp | 0x80000UL;
334 temp = (length - 1) & 0xfff00000UL;
335 *(vulp)T2_WMASK1 = temp;
336 *(vulp)T2_TBASE1 = 0;
337
338#if DEBUG_PRINT_FINAL_SETTINGS
339 printk("%s: setting WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n",
340 __func__, *(vulp)T2_WBASE1, *(vulp)T2_WMASK1, *(vulp)T2_TBASE1);
341#endif
342}
343
344static void __init
345t2_sg_map_window2(struct pci_controller *hose,
346 unsigned long base,
347 unsigned long length)
348{
349 unsigned long temp;
350
351
352
353 hose->sg_isa = iommu_arena_new(hose, base, length, 0);
354 hose->sg_pci = NULL;
355
356 temp = (base & 0xfff00000UL) | ((base + length - 1) >> 20);
357 *(vulp)T2_WBASE2 = temp | 0xc0000UL;
358 temp = (length - 1) & 0xfff00000UL;
359 *(vulp)T2_WMASK2 = temp;
360 *(vulp)T2_TBASE2 = virt_to_phys(hose->sg_isa->ptes) >> 1;
361 mb();
362
363 t2_pci_tbi(hose, 0, -1);
364
365#if DEBUG_PRINT_FINAL_SETTINGS
366 printk("%s: setting WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n",
367 __func__, *(vulp)T2_WBASE2, *(vulp)T2_WMASK2, *(vulp)T2_TBASE2);
368#endif
369}
370
371static void __init
372t2_save_configuration(void)
373{
374#if DEBUG_PRINT_INITIAL_SETTINGS
375 printk("%s: HAE_1 was 0x%lx\n", __func__, srm_hae);
376 printk("%s: HAE_2 was 0x%lx\n", __func__, *(vulp)T2_HAE_2);
377 printk("%s: HAE_3 was 0x%lx\n", __func__, *(vulp)T2_HAE_3);
378 printk("%s: HAE_4 was 0x%lx\n", __func__, *(vulp)T2_HAE_4);
379 printk("%s: HBASE was 0x%lx\n", __func__, *(vulp)T2_HBASE);
380
381 printk("%s: WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n", __func__,
382 *(vulp)T2_WBASE1, *(vulp)T2_WMASK1, *(vulp)T2_TBASE1);
383 printk("%s: WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n", __func__,
384 *(vulp)T2_WBASE2, *(vulp)T2_WMASK2, *(vulp)T2_TBASE2);
385#endif
386
387
388
389
390 t2_saved_config.window[0].wbase = *(vulp)T2_WBASE1;
391 t2_saved_config.window[0].wmask = *(vulp)T2_WMASK1;
392 t2_saved_config.window[0].tbase = *(vulp)T2_TBASE1;
393 t2_saved_config.window[1].wbase = *(vulp)T2_WBASE2;
394 t2_saved_config.window[1].wmask = *(vulp)T2_WMASK2;
395 t2_saved_config.window[1].tbase = *(vulp)T2_TBASE2;
396
397 t2_saved_config.hae_1 = srm_hae;
398 t2_saved_config.hae_2 = *(vulp)T2_HAE_2;
399 t2_saved_config.hae_3 = *(vulp)T2_HAE_3;
400 t2_saved_config.hae_4 = *(vulp)T2_HAE_4;
401 t2_saved_config.hbase = *(vulp)T2_HBASE;
402}
403
404void __init
405t2_init_arch(void)
406{
407 struct pci_controller *hose;
408 struct resource *hae_mem;
409 unsigned long temp;
410 unsigned int i;
411
412 for (i = 0; i < NR_CPUS; i++) {
413 mcheck_expected(i) = 0;
414 mcheck_taken(i) = 0;
415 }
416 t2_mcheck_any_expected = 0;
417 t2_mcheck_last_taken = 0;
418
419
420 temp = *(vulp)T2_IOCSR;
421 if (!(temp & (0x1UL << 26))) {
422 printk("t2_init_arch: enabling SG TLB, IOCSR was 0x%lx\n",
423 temp);
424 *(vulp)T2_IOCSR = temp | (0x1UL << 26);
425 mb();
426 *(vulp)T2_IOCSR;
427 }
428
429 t2_save_configuration();
430
431
432
433
434 pci_isa_hose = hose = alloc_pci_controller();
435 hose->io_space = &ioport_resource;
436 hae_mem = alloc_resource();
437 hae_mem->start = 0;
438 hae_mem->end = T2_MEM_R1_MASK;
439 hae_mem->name = pci_hae0_name;
440 if (request_resource(&iomem_resource, hae_mem) < 0)
441 printk(KERN_ERR "Failed to request HAE_MEM\n");
442 hose->mem_space = hae_mem;
443 hose->index = 0;
444
445 hose->sparse_mem_base = T2_SPARSE_MEM - IDENT_ADDR;
446 hose->dense_mem_base = T2_DENSE_MEM - IDENT_ADDR;
447 hose->sparse_io_base = T2_IO - IDENT_ADDR;
448 hose->dense_io_base = 0;
449
450
451
452
453
454
455
456
457 t2_direct_map_window1(T2_DIRECTMAP_START, T2_DIRECTMAP_LENGTH);
458
459
460 t2_sg_map_window2(hose, T2_ISA_SG_START, T2_ISA_SG_LENGTH);
461
462 *(vulp)T2_HBASE = 0x0;
463
464
465 *(vulp)T2_HAE_1 = 0; mb();
466 *(vulp)T2_HAE_2 = 0; mb();
467 *(vulp)T2_HAE_3 = 0; mb();
468
469
470
471
472
473
474
475
476
477
478 *(vulp)T2_HAE_4 = 0; mb();
479}
480
481void
482t2_kill_arch(int mode)
483{
484
485
486
487 *(vulp)T2_WBASE1 = t2_saved_config.window[0].wbase;
488 *(vulp)T2_WMASK1 = t2_saved_config.window[0].wmask;
489 *(vulp)T2_TBASE1 = t2_saved_config.window[0].tbase;
490 *(vulp)T2_WBASE2 = t2_saved_config.window[1].wbase;
491 *(vulp)T2_WMASK2 = t2_saved_config.window[1].wmask;
492 *(vulp)T2_TBASE2 = t2_saved_config.window[1].tbase;
493 mb();
494
495 *(vulp)T2_HAE_1 = srm_hae;
496 *(vulp)T2_HAE_2 = t2_saved_config.hae_2;
497 *(vulp)T2_HAE_3 = t2_saved_config.hae_3;
498 *(vulp)T2_HAE_4 = t2_saved_config.hae_4;
499 *(vulp)T2_HBASE = t2_saved_config.hbase;
500 mb();
501 *(vulp)T2_HBASE;
502}
503
504void
505t2_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
506{
507 unsigned long t2_iocsr;
508
509 t2_iocsr = *(vulp)T2_IOCSR;
510
511
512 *(vulp)T2_IOCSR = t2_iocsr | (0x1UL << 28);
513 mb();
514 *(vulp)T2_IOCSR;
515
516
517 *(vulp)T2_IOCSR = t2_iocsr & ~(0x1UL << 28);
518 mb();
519 *(vulp)T2_IOCSR;
520}
521
522#define SIC_SEIC (1UL << 33)
523
524static void
525t2_clear_errors(int cpu)
526{
527 struct sable_cpu_csr *cpu_regs;
528
529 cpu_regs = (struct sable_cpu_csr *)T2_CPUn_BASE(cpu);
530
531 cpu_regs->sic &= ~SIC_SEIC;
532
533
534 cpu_regs->bcce |= cpu_regs->bcce;
535 cpu_regs->cbe |= cpu_regs->cbe;
536 cpu_regs->bcue |= cpu_regs->bcue;
537 cpu_regs->dter |= cpu_regs->dter;
538
539 *(vulp)T2_CERR1 |= *(vulp)T2_CERR1;
540 *(vulp)T2_PERR1 |= *(vulp)T2_PERR1;
541
542 mb();
543 mb();
544}
545
546
547
548
549
550
551
552
553
554
555void
556t2_machine_check(unsigned long vector, unsigned long la_ptr)
557{
558 int cpu = smp_processor_id();
559#ifdef CONFIG_VERBOSE_MCHECK
560 struct el_common *mchk_header = (struct el_common *)la_ptr;
561#endif
562
563
564 mb();
565 mb();
566 draina();
567 t2_clear_errors(cpu);
568
569
570
571 wrmces(0x7);
572 mb();
573
574
575 if (!mcheck_expected(cpu) && t2_mcheck_any_expected) {
576
577
578
579
580
581
582#ifdef CONFIG_VERBOSE_MCHECK
583 if (alpha_verbose_mcheck > 1) {
584 printk("t2_machine_check(cpu%d): any_expected 0x%x -"
585 " (assumed) spurious -"
586 " code 0x%x\n", cpu, t2_mcheck_any_expected,
587 (unsigned int)mchk_header->code);
588 }
589#endif
590 return;
591 }
592
593 if (!mcheck_expected(cpu) && !t2_mcheck_any_expected) {
594 if (t2_mcheck_last_taken & (1 << cpu)) {
595#ifdef CONFIG_VERBOSE_MCHECK
596 if (alpha_verbose_mcheck > 1) {
597 printk("t2_machine_check(cpu%d): last_taken 0x%x - "
598 "unexpected mcheck - code 0x%x\n",
599 cpu, t2_mcheck_last_taken,
600 (unsigned int)mchk_header->code);
601 }
602#endif
603 t2_mcheck_last_taken = 0;
604 mb();
605 return;
606 } else {
607 t2_mcheck_last_taken = 0;
608 mb();
609 }
610 }
611
612#ifdef CONFIG_VERBOSE_MCHECK
613 if (alpha_verbose_mcheck > 1) {
614 printk("%s t2_mcheck(cpu%d): last_taken 0x%x - "
615 "any_expected 0x%x - code 0x%x\n",
616 (mcheck_expected(cpu) ? "EX" : "UN"), cpu,
617 t2_mcheck_last_taken, t2_mcheck_any_expected,
618 (unsigned int)mchk_header->code);
619 }
620#endif
621
622 process_mcheck_info(vector, la_ptr, "T2", mcheck_expected(cpu));
623}
624