2 * Copyright (c) 1998 Doug Rabson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
28 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
29 * All rights reserved.
31 * Author: Chris G. Demetriou
33 * Permission to use, copy, modify and distribute this software and
34 * its documentation is hereby granted, provided that both the copyright
35 * notice and this permission notice appear in all copies of the
36 * software, derivative works or modified versions, and any portions
37 * thereof, and that both notices appear in supporting documentation.
39 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
40 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
41 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
43 * Carnegie Mellon requests users of this software to return to
45 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
46 * School of Computer Science
47 * Carnegie Mellon University
48 * Pittsburgh PA 15213-3890
50 * any improvements or extensions that they make and grant Carnegie the
51 * rights to redistribute these changes.
54 * Additional Copyright (c) 1998 by Andrew Gallatin for Duke University
57 #include <sys/cdefs.h>
58 __FBSDID("$FreeBSD$");
60 #define __RMAN_RESOURCE_VISIBLE
61 #include <sys/param.h>
62 #include <sys/systm.h>
63 #include <sys/kernel.h>
65 #include <sys/malloc.h>
66 #include <sys/module.h>
67 #include <sys/mutex.h>
69 #include <machine/bus.h>
72 #include <sys/interrupt.h>
74 #include <alpha/pci/apecsreg.h>
75 #include <alpha/pci/apecsvar.h>
76 #include <alpha/isa/isavar.h>
78 #include <machine/cpuconf.h>
79 #include <machine/intr.h>
80 #include <machine/intrcnt.h>
81 #include <machine/md_var.h>
82 #include <machine/resource.h>
83 #include <machine/rpb.h>
84 #include <machine/sgmap.h>
85 #include <machine/swiz.h>
88 #include <vm/vm_page.h>
90 #define KV(pa) ALPHA_PHYS_TO_K0SEG(pa)
92 static devclass_t apecs_devclass;
93 static device_t apecs0; /* XXX only one for now */
96 vm_offset_t dmem_base; /* dense memory */
97 vm_offset_t smem_base; /* sparse memory */
98 vm_offset_t io_base; /* dense i/o */
99 vm_offset_t cfg0_base; /* dense pci0 config */
100 vm_offset_t cfg1_base; /* dense pci1 config */
103 #define APECS_SOFTC(dev) (struct apecs_softc*) device_get_softc(dev)
105 static alpha_chipset_read_hae_t apecs_read_hae;
106 static alpha_chipset_write_hae_t apecs_write_hae;
108 static alpha_chipset_t apecs_swiz_chipset = {
116 * XXX linux does 32-bit reads/writes via dense space. This doesn't
117 * appear to work for devices behind a ppb. I'm using sparse
118 * accesses & they appear to work just fine everywhere.
121 static u_int32_t apecs_hae_mem;
123 #define REG1 (1UL << 24)
125 apecs_set_hae_mem(void *arg, u_int32_t pa)
130 msb = pa & 0xf8000000;
133 if (msb != apecs_hae_mem) {
135 REGVAL(EPIC_HAXR1) = apecs_hae_mem;
137 apecs_hae_mem = REGVAL(EPIC_HAXR1);
147 return apecs_hae_mem & 0xf8000000;
151 apecs_write_hae(u_int64_t hae)
154 apecs_set_hae_mem(0, pa);
157 static int apecs_probe(device_t dev);
158 static int apecs_attach(device_t dev);
159 static int apecs_setup_intr(device_t dev, device_t child,
160 struct resource *irq, int flags,
161 driver_intr_t *intr, void *arg, void **cookiep);
162 static int apecs_teardown_intr(device_t dev, device_t child,
163 struct resource *irq, void *cookie);
165 static device_method_t apecs_methods[] = {
166 /* Device interface */
167 DEVMETHOD(device_probe, apecs_probe),
168 DEVMETHOD(device_attach, apecs_attach),
171 DEVMETHOD(bus_setup_intr, apecs_setup_intr),
172 DEVMETHOD(bus_teardown_intr, apecs_teardown_intr),
177 static driver_t apecs_driver = {
180 sizeof(struct apecs_softc),
183 #define APECS_SGMAP_BASE (8*1024*1024)
184 #define APECS_SGMAP_SIZE (8*1024*1024)
187 apecs_sgmap_invalidate(void)
190 REGVAL(EPIC_TBIA) = 0;
195 apecs_sgmap_map(void *arg, bus_addr_t ba, vm_offset_t pa)
197 u_int64_t *sgtable = arg;
198 int index = alpha_btop(ba - APECS_SGMAP_BASE);
202 panic("apecs_sgmap_map: can't map address 0x%lx", pa);
203 sgtable[index] = ((pa >> 13) << 1) | 1;
208 apecs_sgmap_invalidate();
212 apecs_init_sgmap(void)
217 * First setup Window 0 to map 8Mb to 16Mb with an
218 * sgmap. Allocate the map aligned to a 32 boundary.
220 REGVAL(EPIC_PCI_BASE_1) = APECS_SGMAP_BASE |
221 EPIC_PCI_BASE_SGEN | EPIC_PCI_BASE_WENB;
224 REGVAL(EPIC_PCI_MASK_1) = EPIC_PCI_MASK_8M;
227 sgtable = contigmalloc(8192, M_DEVBUF, M_NOWAIT,
231 panic("apecs_init_sgmap: can't allocate page table");
232 REGVAL(EPIC_TBASE_1) =
233 (pmap_kextract((vm_offset_t) sgtable) >> EPIC_TBASE_SHIFT);
235 chipset.sgmap = sgmap_map_create(APECS_SGMAP_BASE,
236 APECS_SGMAP_BASE + APECS_SGMAP_SIZE,
237 apecs_sgmap_map, sgtable);
243 static int initted = 0;
244 static struct swiz_space io_space, mem_space;
249 swiz_init_space(&io_space, KV(APECS_PCI_SIO));
250 swiz_init_space_hae(&mem_space, KV(APECS_PCI_SPARSE),
251 apecs_set_hae_mem, 0);
253 busspace_isa_io = (struct alpha_busspace *) &io_space;
254 busspace_isa_mem = (struct alpha_busspace *) &mem_space;
256 chipset = apecs_swiz_chipset;
258 if (platform.pci_intr_init)
259 platform.pci_intr_init();
264 apecs_probe(device_t dev)
270 memwidth = (REGVAL(COMANCHE_GCR) & COMANCHE_GCR_WIDEMEM) != 0 ? 128 : 64;
272 device_set_desc(dev, "DECchip 21071 Core Logic chipset");
274 device_set_desc(dev, "DECchip 21072 Core Logic chipset");
276 apecs_hae_mem = REGVAL(EPIC_HAXR1);
281 device_add_child(dev, "pcib", 0);
287 apecs_attach(device_t dev)
289 struct apecs_softc* sc = APECS_SOFTC(dev);
292 sc->dmem_base = APECS_PCI_DENSE;
293 sc->smem_base = APECS_PCI_SPARSE;
294 sc->io_base = APECS_PCI_SIO;
295 sc->cfg0_base = KV(APECS_PCI_CONF);
298 set_iointr(alpha_dispatch_intr);
300 snprintf(chipset_type, sizeof(chipset_type), "apecs");
302 chipset_ports = APECS_PCI_SIO;
303 chipset_memory = APECS_PCI_SPARSE;
304 chipset_dense = APECS_PCI_DENSE;
305 chipset_hae_mask = EPIC_HAXR1_EADDR;
307 bus_generic_attach(dev);
312 apecs_disable_intr(uintptr_t vector)
316 irq = (vector - 0x900) >> 4;
317 mtx_lock_spin(&icu_lock);
318 platform.pci_intr_disable(irq);
319 mtx_unlock_spin(&icu_lock);
323 apecs_enable_intr(uintptr_t vector)
327 irq = (vector - 0x900) >> 4;
328 mtx_lock_spin(&icu_lock);
329 platform.pci_intr_enable(irq);
330 mtx_unlock_spin(&icu_lock);
334 apecs_setup_intr(device_t dev, device_t child,
335 struct resource *irq, int flags,
336 driver_intr_t *intr, void *arg, void **cookiep)
341 * the avanti routes interrupts through the isa interrupt
342 * controller, so we need to special case it
344 if(hwrpb->rpb_type == ST_DEC_2100_A50)
345 return isa_setup_intr(dev, child, irq, flags,
348 error = rman_activate_resource(irq);
352 error = alpha_setup_intr(device_get_nameunit(child ? child : dev),
353 0x900 + (irq->r_start << 4), intr, arg, flags, cookiep,
354 &intrcnt[INTRCNT_EB64PLUS_IRQ + irq->r_start],
355 apecs_disable_intr, apecs_enable_intr);
359 /* Enable PCI interrupt */
360 mtx_lock_spin(&icu_lock);
361 platform.pci_intr_enable(irq->r_start);
362 mtx_unlock_spin(&icu_lock);
364 device_printf(child, "interrupting at APECS irq %d\n",
372 apecs_teardown_intr(device_t dev, device_t child,
373 struct resource *irq, void *cookie)
376 * the avanti routes interrupts through the isa interrupt
377 * controller, so we need to special case it
379 if(hwrpb->rpb_type == ST_DEC_2100_A50)
380 return isa_teardown_intr(dev, child, irq, cookie);
382 alpha_teardown_intr(cookie);
383 return rman_deactivate_resource(irq);
386 DRIVER_MODULE(apecs, root, apecs_driver, apecs_devclass, 0, 0);