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