]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/alpha/pci/t2.c
merge fix for boot-time hang on centos' xen
[FreeBSD/FreeBSD.git] / sys / alpha / pci / t2.c
1 /*-
2  * Copyright (c) 2000 Andrew Gallatin & Doug Rabson
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * Portions of this file were obtained from Compaq intellectual
27  * property which was made available under the following copyright:
28  *
29  * *****************************************************************
30  * *                                                               *
31  * *    Copyright Compaq Computer Corporation, 2000                *
32  * *                                                               *
33  * *   Permission to use, copy, modify, distribute, and sell       *
34  * *   this software and its documentation for any purpose is      *
35  * *   hereby granted without fee, provided that the above         *
36  * *   copyright notice appear in all copies and that both         *
37  * *   that copyright notice and this permission notice appear     *
38  * *   in supporting documentation, and that the name of           *
39  * *   Compaq Computer Corporation not be used in advertising      *
40  * *   or publicity pertaining to distribution of the software     *
41  * *   without specific, written prior permission.  Compaq         *
42  * *   makes no representations about the suitability of this      *
43  * *   software for any purpose.  It is provided "AS IS"           *
44  * *   without express or implied warranty.                        *
45  * *                                                               *
46  * *****************************************************************
47  */
48
49 /*
50  * T2 CBUS to PCI bridge
51  */
52
53 #include <sys/cdefs.h>
54 __FBSDID("$FreeBSD$");
55
56 #define __RMAN_RESOURCE_VISIBLE
57 #include <sys/param.h>
58 #include <sys/systm.h>
59 #include <sys/kernel.h>
60 #include <sys/lock.h>
61 #include <sys/malloc.h>
62 #include <sys/module.h>
63 #include <sys/mutex.h>
64 #include <sys/bus.h>
65 #include <machine/bus.h>
66 #include <sys/proc.h>
67 #include <sys/rman.h>
68 #include <sys/interrupt.h>
69
70 #include <dev/pci/pcivar.h>
71 #include <alpha/pci/t2reg.h>
72 #include <alpha/pci/t2var.h>
73 #include <alpha/isa/isavar.h>
74
75 #include <machine/cpuconf.h>
76 #include <machine/intr.h>
77 #include <machine/intrcnt.h>
78 #include <machine/md_var.h>
79 #include <machine/resource.h>
80 #include <machine/sgmap.h>
81 #include <machine/swiz.h>
82
83 #include <vm/vm.h>
84 #include <vm/vm_page.h>
85
86 #define KV(pa)                  ALPHA_PHYS_TO_K0SEG(pa + sable_lynx_base)
87
88 vm_offset_t     sable_lynx_base = 0UL;
89
90 volatile t2_csr_t *t2_csr[2];
91 static int pci_int_type[2];
92
93 static devclass_t       t2_devclass;
94 static device_t         t2_0;           /* XXX only one for now */
95
96 struct t2_softc {
97         int             junk;
98 };
99
100 #define T2_SOFTC(dev)   (struct t2_softc*) device_get_softc(dev)
101
102 static alpha_chipset_read_hae_t t2_read_hae;
103 static alpha_chipset_write_hae_t t2_write_hae;
104
105 static alpha_chipset_t t2_chipset = {
106         t2_read_hae,
107         t2_write_hae,
108 };
109
110 static u_int32_t        t2_hae_mem[2];
111
112 #define REG1 (1UL << 24)
113
114 static u_int32_t
115 t2_set_hae_mem(void *arg, u_int32_t pa)
116 {
117         register_t s; 
118         u_int32_t msb;
119         int hose;
120
121         hose = (long)arg;
122
123         if(pa >= REG1){
124                 msb = pa & 0xf8000000;
125                 pa -= msb;
126                 msb >>= 27;     /* t2 puts high bits in the bottom of the register */
127                 s = intr_disable();
128                 if (msb != t2_hae_mem[hose]) {
129                         t2_hae_mem[hose] = msb;
130                         t2_csr[hose]->hae0_1 = t2_hae_mem[hose];
131                         alpha_mb();
132                         t2_hae_mem[hose] = t2_csr[hose]->hae0_1;
133                 }
134                 intr_restore(s);
135         }
136         return pa;
137 }
138
139 static u_int64_t
140 t2_read_hae(void)
141 {
142         return t2_hae_mem[0] << 27;
143 }
144
145 static void
146 t2_write_hae(u_int64_t hae)
147 {
148         u_int32_t pa = hae;
149         t2_set_hae_mem(0, pa);
150 }
151
152 static int t2_probe(device_t dev);
153 static int t2_attach(device_t dev);
154 static int t2_setup_intr(device_t dev, device_t child,
155                             struct resource *irq, int flags,
156                             void *intr, void *arg, void **cookiep);
157 static int t2_teardown_intr(device_t dev, device_t child,
158                             struct resource *irq, void *cookie);
159 static void
160 t2_dispatch_intr(void *frame, unsigned long vector);
161 static void
162 t2_machine_check(unsigned long mces, struct trapframe *framep, 
163                  unsigned long vector, unsigned long param);
164
165
166 static device_method_t t2_methods[] = {
167         /* Device interface */
168         DEVMETHOD(device_probe,                 t2_probe),
169         DEVMETHOD(device_attach,                t2_attach),
170
171         /* Bus interface */
172         DEVMETHOD(bus_setup_intr,               t2_setup_intr),
173         DEVMETHOD(bus_teardown_intr,            t2_teardown_intr),
174
175         { 0, 0 }
176 };
177
178 static driver_t t2_driver = {
179         "t2",
180         t2_methods,
181         sizeof(struct t2_softc),
182 };
183
184
185 #define T2_SGMAP_BASE           (8*1024*1024)
186 #define T2_SGMAP_SIZE           (8*1024*1024)
187
188 static void
189 t2_sgmap_invalidate(void)
190 {
191         u_int64_t val;
192
193         alpha_mb();
194         val = REGVAL64(T2_IOCSR);
195         val |= T2_IOCSRL_ITLB;
196         REGVAL64(T2_IOCSR) = val;
197         alpha_mb();
198         alpha_mb();
199         val = REGVAL64(T2_IOCSR);
200         val &= ~T2_IOCSRL_ITLB;
201         REGVAL64(T2_IOCSR) = val;
202         alpha_mb();
203         alpha_mb();
204 }
205
206 static void
207 t2_sgmap_map(void *arg, bus_addr_t ba, vm_offset_t pa)
208 {
209         u_int64_t *sgtable = arg;
210         int index = alpha_btop(ba - T2_SGMAP_BASE);
211
212         if (pa) {
213                 if (pa > (1L<<32))
214                         panic("t2_sgmap_map: can't map address 0x%lx", pa);
215                 sgtable[index] = ((pa >> 13) << 1) | 1;
216         } else {
217                 sgtable[index] = 0;
218         }
219         alpha_mb();
220         t2_sgmap_invalidate();
221 }
222
223
224 static void
225 t2_init_sgmap(int h)
226 {
227         void *sgtable;
228
229         /*
230          * First setup Window 2 to map 8Mb to 16Mb with an
231          * sgmap. Allocate the map aligned to a 32 boundary.
232          *
233          *  bits 31..20 of WBASE represent the pci start address
234          *  (in units of 1Mb), and bits 11..0 represent the pci
235          *  end address
236          */
237         t2_csr[h]->wbase2 = T2_WSIZE_8M|T2_WINDOW_ENABLE|T2_WINDOW_SG
238                              | ((T2_SGMAP_BASE >> 20) << 20)
239                              | ((T2_SGMAP_BASE + T2_SGMAP_SIZE) >> 20);
240         t2_csr[h]->wmask2 = T2_WMASK_8M;
241         alpha_mb();
242
243         sgtable = contigmalloc(8192, M_DEVBUF, M_NOWAIT,
244                                0, (1L<<34),
245                                32*1024, (1L<<34));
246         if (!sgtable)
247                 panic("t2_init_sgmap: can't allocate page table");
248
249         t2_csr[h]->tbase2 =
250             (pmap_kextract((vm_offset_t) sgtable) >> T2_TBASE_SHIFT);
251
252         chipset.sgmap = sgmap_map_create(T2_SGMAP_BASE,
253                                          T2_SGMAP_BASE + T2_SGMAP_SIZE,
254                                          t2_sgmap_map, sgtable);
255 }
256
257 static void
258 t2_csr_init(int h)
259 {
260         /* 
261          * initialize the DMA windows
262          */
263         t2_csr[h]->wbase1 = T2_WSIZE_1G|T2_WINDOW_ENABLE|T2_WINDOW_DIRECT|0x7ff;
264         t2_csr[h]->wmask1 = T2_WMASK_1G;
265         t2_csr[h]->tbase1 = 0x0;
266
267         t2_csr[h]->wbase2 = 0x0;
268
269         /* 
270          *  enable the PCI "Hole" for ISA devices which use memory in
271          *  the 512k - 1MB range
272          */
273         t2_csr[h]->hbase = 1 << 13;
274         t2_init_sgmap(0);
275
276         /* initialize the HAEs */
277         t2_csr[h]->hae0_1 = 0x0;
278         alpha_mb();
279         t2_csr[h]->hae0_2 = 0x0;
280         alpha_mb();
281         t2_csr[h]->hae0_3 = 0x0;
282         alpha_mb();
283
284 }
285
286 /*
287  * Perform basic chipset init/fixup.  Called by various early
288  * consumers to ensure that the system will work before the 
289  * bus methods are invoked.
290  *
291  */
292
293 void
294 t2_init()
295 {
296         static int initted = 0;
297         static struct swiz_space io_space, mem_space;
298
299         if (initted) return;
300         initted = 1;
301
302         swiz_init_space(&io_space, KV(T2_PCI_SIO));
303         swiz_init_space_hae(&mem_space, KV(T2_PCI_SPARSE),
304                             t2_set_hae_mem, 0);
305
306         busspace_isa_io = (struct alpha_busspace *) &io_space;
307         busspace_isa_mem = (struct alpha_busspace *) &mem_space;
308
309         chipset = t2_chipset;
310
311 }
312
313 static int
314 t2_probe(device_t dev)
315 {
316         int h, t2_num_hoses = 1;
317         device_t child;
318
319         if (t2_0)
320                 return ENXIO;
321
322         t2_0 = dev;
323         device_set_desc(dev, "T2 Core Logic chipset"); 
324         t2_csr[0] = (t2_csr_t *)
325             ALPHA_PHYS_TO_K0SEG(sable_lynx_base + PCI0_BASE);
326         t2_csr[1] = (t2_csr_t *)
327             ALPHA_PHYS_TO_K0SEG(sable_lynx_base + PCI1_BASE);
328
329         /* Look at the rev of the chip.  If the high bit is set in the
330          * rev field then we have either a T3 or a T4 chip, so use the
331          * new interrupt structure.  If it is clear, then we have a T2
332          * so use the old way */
333
334         platform.mcheck_handler = t2_machine_check;
335
336         if (((t2_csr[0]->iocsr) >> 35) & 1)
337                 pci_int_type[0] = 1;
338          else 
339                 pci_int_type[0] = 0;
340
341         device_printf(dev, "using interrupt type %d on pci bus 0\n", 
342             pci_int_type[0]);
343
344         if (!badaddr(__DEVOLATILE(void *, &t2_csr[1]->tlbbr), sizeof(long))) {
345                 pci_int_type[1] = 1; /* PCI1 always uses the new scheme */
346                 /* Clear any errors that the BADADDR probe may have caused */
347                 t2_csr[1]->cerr1 |= t2_csr[1]->cerr1;
348                 t2_csr[1]->pcierr1 |= t2_csr[1]->pcierr1;
349                 device_printf(dev, "found EXT_IO!!!!!\n");
350                 /* t2_num_hoses = 2; XXX not ready for this yet */
351         }
352
353         for (h = 0; h < t2_num_hoses; h++)
354                 t2_csr_init(h);
355
356         
357         child = device_add_child(dev, "pcib", 0);
358         device_set_ivars(child, 0);
359
360         return 0;
361 }
362
363 static int
364 t2_attach(device_t dev)
365 {
366         t2_init();
367
368         set_iointr(t2_dispatch_intr);
369         platform.isa_setup_intr = t2_setup_intr;
370         platform.isa_teardown_intr = t2_teardown_intr;
371
372         snprintf(chipset_type, sizeof(chipset_type), "t2");
373
374         bus_generic_attach(dev);
375
376         return 0;
377 }
378
379
380 /*
381  * magical mystery table partly obtained from Linux
382  * at least some of their values for PCI masks
383  * were incorrect, and I've filled in my own extrapolations
384  * XXX this needs more testers 
385  */
386
387 unsigned long t2_shadow_mask = -1L;
388 static const char irq_to_mask[40] = {
389         -1,  6, -1,  8, 15, 12,  7,  9,         /* ISA 0-7  */
390         -1, 16, 17, 18,  3, -1, 21, 22,         /* ISA 8-15 */
391         -1, -1, -1, -1, -1, -1, -1, -1,         /* ?? EISA XXX */
392         -1, -1, -1, -1, -1, -1, -1, -1,         /* ?? EISA XXX */
393          0,  1,  2,  3,  4,  5,  6,  7          /* PCI 0-7 XXX */
394 };
395
396
397 static void
398 t2_8259_disable_mask(int mask)
399 {
400         t2_shadow_mask |= (1UL << mask);
401
402         if (mask <= 7)
403                 outb(SLAVE0_ICU, t2_shadow_mask);
404         else if (mask <= 15)
405                 outb(SLAVE1_ICU, t2_shadow_mask >> 8);
406         else 
407                 outb(SLAVE2_ICU, t2_shadow_mask >> 16);
408 }
409
410 static void
411 t2_8259_enable_mask(int mask)
412 {
413         t2_shadow_mask &= ~(1UL << mask);
414
415         if (mask <= 7)
416                 outb(SLAVE0_ICU, t2_shadow_mask);
417         else if (mask <= 15)
418                 outb(SLAVE1_ICU, t2_shadow_mask >> 8);
419         else 
420                 outb(SLAVE2_ICU, t2_shadow_mask >> 16);
421 }
422
423
424 static void 
425 t2_eoi( int vector)
426 {
427         int irq, hose;
428
429         hose = (vector >= 0xC00);
430         irq = (vector - 0x800) >> 4;
431
432         if (pci_int_type[hose]) {
433
434                 /* New interrupt scheme.  Both PCI0 and PCI1 can use
435                  * the same handler.  Dispatching interrupts with the
436                  * IC IC chip is easy.  We simply write the vector
437                  * address  register (var) on the T3/T4 (offset
438                  * 0x480) with the IRQ  level (0 - 63) of what came in.  */
439                 t2_csr[hose]->var = (u_long) irq;
440                 alpha_mb();
441                 alpha_mb();
442         } else {
443                 switch (irq) {
444                 case 0 ... 7:
445                         outb(SLAVE0_ICU-1, (0xe0 | (irq)));
446                         outb(MASTER_ICU-1, (0xe0 | 1));
447                         break;
448                 case 8 ... 15:
449                         outb(SLAVE1_ICU-1, (0xe0 | (irq - 8)));
450                         outb(MASTER_ICU-1, (0xe0 | 3));
451                         break;
452                 case 16 ... 24:
453                         outb(SLAVE2_ICU-1, (0xe0 | (irq - 16)));
454                         outb(MASTER_ICU-1, (0xe0 | 4));
455                         break;
456                 }       
457         }
458 }
459
460 static void
461 t2_enable_vec(uintptr_t vector)
462 {
463         int irq, hose;
464         u_long IC_mask, scratch;
465
466         hose = (vector >= 0xC00);
467         irq = (vector - 0x800) >> 4;
468
469         mtx_lock_spin(&icu_lock);
470         if (pci_int_type[hose]) {
471
472                 /* Write the air register on the T3/T4 with the
473                  * address of the IC IC masks register (offset 0x40) */
474                 t2_csr[hose]->air = 0x40;
475                 alpha_mb();
476                 scratch = t2_csr[hose]->air;    
477                 alpha_mb();
478                 IC_mask = t2_csr[hose]->dir;
479                 IC_mask &= ~(1L << ( (u_long) irq));
480                 t2_csr[hose]->dir = IC_mask;    
481                 alpha_mb();
482                 alpha_mb();
483                 /*
484                  * EOI the interrupt we just enabled.
485                  */
486                 t2_eoi(vector);
487         } else {
488                 /* Old style 8259 (Gack!!!) interrupts */
489                 t2_8259_enable_mask(irq);
490         }
491         mtx_unlock_spin(&icu_lock);
492 }
493
494 static void
495 t2_disable_vec(uintptr_t vector)
496 {
497         int hose, irq;
498         u_long scratch, IC_mask;
499
500         hose = (vector >= 0xC00);
501         irq =  (vector - 0x800) >> 4;
502
503         mtx_lock_spin(&icu_lock);
504         if (pci_int_type[hose]) {
505
506                 /* Write the air register on the T3/T4 wioth the
507                  * address of the IC IC masks register (offset 0x40) */
508
509                 t2_csr[hose]->air = 0x40;
510                 alpha_mb();
511                 scratch = t2_csr[hose]->air;    
512                 alpha_mb();
513                 /*
514                  * Read the dir register to fetch the mask data, 'or' in the
515                  * new disable bit, and write the data back.
516                  */
517                 IC_mask = t2_csr[hose]->dir;
518                 IC_mask |= (1L << ( (u_long) irq));
519                 /* Set the disable bit */
520                 t2_csr[hose]->dir = IC_mask;    
521                 alpha_mb();
522                 alpha_mb();
523         } else {
524                 /* Old style 8259 (Gack!!!) interrupts */
525                 t2_8259_disable_mask(irq);
526         }
527         mtx_unlock_spin(&icu_lock);
528 }
529
530
531 static int
532 t2_setup_intr(device_t dev, device_t child,
533                struct resource *irq, int flags,
534                void *intr, void *arg, void **cookiep)
535 {
536         int error, vector, stdio_irq;
537         const char *name;
538         device_t bus, parent;
539
540         name = device_get_nameunit(dev);
541         stdio_irq = irq->r_start;
542         if (strncmp(name, "eisa", 4) == 0) {
543                 if ((stdio_irq != 6 ) && (stdio_irq != 3 )) {
544                         stdio_irq = 
545                             T2_EISA_IRQ_TO_STDIO_IRQ(stdio_irq);
546                 }
547         } else if ((strncmp(name, "isa", 3)) == 0) {
548                 stdio_irq = irq_to_mask[stdio_irq];
549         }
550
551         parent = dev;
552         do {
553                 bus = parent;
554                 parent = device_get_parent(bus);
555         } while (parent && strncmp("t2", device_get_nameunit(parent), 2));
556
557         if (parent && (device_get_unit(bus) != 0))
558                 vector = STDIO_PCI1_IRQ_TO_SCB_VECTOR(stdio_irq);
559         else    
560                 vector = STDIO_PCI0_IRQ_TO_SCB_VECTOR(stdio_irq);
561
562         error = rman_activate_resource(irq);
563         if (error)
564                 return error;
565
566         error = alpha_setup_intr(device_get_nameunit(child ? child : dev),
567                         vector, intr, arg, flags, cookiep,
568                         &intrcnt[irq->r_start], t2_disable_vec, t2_enable_vec);
569             
570         if (error)
571                 return error;
572
573         /* Enable interrupt */
574         t2_enable_vec(vector);
575         
576         if (bootverbose != 0) 
577                 device_printf(child, 
578                     "interrupting at T2 irq %d (stdio irq %d)\n",
579                       (int) irq->r_start, stdio_irq);
580         return 0;
581 }
582
583 static int
584 t2_teardown_intr(device_t dev, device_t child,
585                struct resource *irq, void *cookie)
586 {
587         int mask;
588         
589         mask = irq_to_mask[irq->r_start];
590
591         /* Disable interrupt */
592         
593         /* 
594          *  XXX this is totally broken! 
595          *  we don't have enough info to figure out where the interrupt 
596          *  came from if hose != 0 and pci_int_type[hose] != 0
597          *  We should probably carry around the vector someplace --
598          *  that would be enough to figure out the hose and the stdio irq
599          */
600
601         t2_shadow_mask |= (1UL << mask);
602
603         mtx_lock_spin(&icu_lock);
604         if (mask <= 7)
605                 outb(SLAVE0_ICU, t2_shadow_mask);
606         else if (mask <= 15)
607                 outb(SLAVE1_ICU, t2_shadow_mask >> 8);
608         else 
609                 outb(SLAVE2_ICU, t2_shadow_mask >> 16);
610         mtx_unlock_spin(&icu_lock);
611
612         alpha_teardown_intr(cookie);
613         return rman_deactivate_resource(irq);
614 }
615
616
617
618 static void
619 t2_dispatch_intr(void *frame, unsigned long vector)
620 {
621         alpha_dispatch_intr(frame, vector);
622         mtx_lock_spin(&icu_lock);
623         t2_eoi(vector);
624         mtx_unlock_spin(&icu_lock);
625 }
626
627 static void
628 t2_machine_check(unsigned long mces, struct trapframe *framep, 
629     unsigned long vector, unsigned long param)
630 {
631         int expected;
632
633         expected = mc_expected;
634         machine_check(mces, framep, vector, param);
635         /* for some reason the alpha_pal_wrmces() doesn't clear all
636            pending machine checks & we may take another */
637         mc_expected = expected;
638 }
639
640 DRIVER_MODULE(t2, root, t2_driver, t2_devclass, 0, 0);