diff --git a/sys/alpha/mcbus/mcbus.c b/sys/alpha/mcbus/mcbus.c new file mode 100644 index 000000000000..4f8e4636737f --- /dev/null +++ b/sys/alpha/mcbus/mcbus.c @@ -0,0 +1,287 @@ +/* $FreeBSD$ */ +/* + * Copyright (c) 2000 by Matthew Jacob + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Autoconfiguration and support routines for the main backplane bus + * for Rawhide (Alpha 4100) systems. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +struct mcbus_device *mcbus_primary_cpu = NULL; + +#define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr))) +#define NO_MCPCIA_AT(mid, gid) \ + (badaddr((void *)KV(MCPCIA_BRIDGE_ADDR(gid, mid)), sizeof (u_int32_t))) + +struct mcbus_softc { + device_t mcbus_dev; + driver_intr_t * sub_intr; + u_int8_t mcbus_types[MCBUS_MID_MAX]; +}; + +static void mcbus_add_child(struct mcbus_softc *, struct mcbus_device *); +static void mcbus_intr(void *, u_long); + +static struct mcbus_softc * mcbus0_softc = NULL; +static devclass_t mcbus_devclass; + +/* + * Device methods + */ +static int mcbus_probe(device_t); +static int mcbus_print_child(device_t, device_t); +static int mcbus_read_ivar(device_t, device_t, int, u_long *); +static int mcbus_setup_intr(device_t, device_t, struct resource *, int, + driver_intr_t *, void *, void **); +static int +mcbus_teardown_intr(device_t, device_t, struct resource *, void *); + +static device_method_t mcbus_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, mcbus_probe), + DEVMETHOD(device_attach, bus_generic_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + + /* Bus interface */ + DEVMETHOD(bus_print_child, mcbus_print_child), + DEVMETHOD(bus_read_ivar, mcbus_read_ivar), + DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), + DEVMETHOD(bus_setup_intr, mcbus_setup_intr), + DEVMETHOD(bus_teardown_intr, mcbus_teardown_intr), + + { 0, 0 } +}; + +static driver_t mcbus_driver = { + "mcbus", mcbus_methods, sizeof (struct mcbus_softc), +}; + +/* + * Tru64 UNIX (formerly Digital UNIX (formerly DEC OSF/1)) probes for MCPCIAs + * in the following order: + * + * 5, 4, 7, 6 + * + * This is so that the built-in CD-ROM on the internal 53c810 is always + * dka500. We probe them in the same order, for consistency. + */ +static const int mcbus_mcpcia_probe_order[] = { 5, 4, 7, 6 }; + +/* + * At 'probe' time, we add all the devices which we know about to the + * bus. The generic attach routine will probe and attach them if they + * are alive. + */ +static int +mcbus_probe(device_t dev) +{ + struct mcbus_softc *sc = device_get_softc(dev); + struct mcbus_device *mdev; + int i, mid, gid; + + device_set_desc(dev, "MCBUS Backplane Bus"); + + /* + * XXX A note about GIDs... + * XXX If we ever support more than one MCBUS, we'll + * XXX have to probe for them, and map them to unit + * XXX numbers. + */ + + sc->mcbus_dev = dev; + mcbus0_softc = sc; + set_iointr(mcbus_intr); + gid = MCBUS_GID_FROM_INSTANCE(0); + + mcbus0_softc->mcbus_types[0] = MCBUS_TYPE_RES; + for (mid = 1; mid <= MCBUS_MID_MAX; mid++) { + mcbus0_softc->mcbus_types[mid] = MCBUS_TYPE_UNK; + } + + /* + * First, add 'memory' children to probe. + */ + mdev = (struct mcbus_device *) + malloc(sizeof (struct mcbus_device), M_DEVBUF, M_NOWAIT); + if (!mdev) { + printf("mcbus_probe: unable to malloc softc for memory dev\n"); + return (ENOMEM); + } + mdev->ma_gid = gid; + mdev->ma_mid = 1; + mdev->ma_order = MCPCIA_PER_MCBUS; + mdev->ma_type = MCBUS_TYPE_MEM; + mcbus0_softc->mcbus_types[1] = MCBUS_TYPE_MEM; + mcbus_add_child(sc, mdev); + + /* + * Now add I/O (MCPCIA) modules to probe (but only if they're there). + */ + for (i = 0; i < MCPCIA_PER_MCBUS; ++i) { + mid = mcbus_mcpcia_probe_order[i]; + + if (NO_MCPCIA_AT(mid, gid)) { + continue; + } + mdev = (struct mcbus_device *) + malloc(sizeof (struct mcbus_device), M_DEVBUF, M_NOWAIT); + if (!mdev) { + printf("mcbus_probe: unable to malloc for MCPCIA\n"); + continue; + } + mdev->ma_gid = gid; + mdev->ma_mid = mid; + mdev->ma_order = i; + mdev->ma_type = MCBUS_TYPE_PCI; + mcbus0_softc->mcbus_types[1] = MCBUS_TYPE_PCI; + mcbus_add_child(sc, mdev); + } + + /* + * XXX: ToDo Add CPU nodes. + */ + + return (0); +} + +static int +mcbus_print_child(device_t dev, device_t child) +{ + struct mcbus_device *mdev = DEVTOMCBUS(child); + int retval = 0; + + retval += bus_print_child_header(dev, child); + retval += printf(" at %s gid %d mid %d\n", + device_get_nameunit(dev), mdev->ma_gid, mdev->ma_mid); + return (retval); +} + +static int +mcbus_read_ivar(device_t dev, device_t child, int index, u_long *result) +{ + struct mcbus_device *mdev = DEVTOMCBUS(child); + + switch (index) { + case MCBUS_IVAR_MID: + *result = mdev->ma_mid; + break; + + case MCBUS_IVAR_GID: + *result = mdev->ma_gid; + break; + + case MCBUS_IVAR_TYPE: + *result = mdev->ma_type; + break; + + } + return (ENOENT); +} + +static int +mcbus_setup_intr(device_t dev, device_t child, struct resource *r, int f, + driver_intr_t *intr, void *a, void **ac) +{ + if (strncmp(device_get_name(child), "mcpcia", 6) == 0) { + if (mcbus0_softc->sub_intr == NULL) + mcbus0_softc->sub_intr = intr; + return (0); + } else { + return (ENXIO); + } +} + +static int +mcbus_teardown_intr(device_t dev, device_t child, struct resource *i, void *c) +{ + if (strncmp(device_get_name(child), "mcpcia", 6) == 0) { + mcbus0_softc->sub_intr = NULL; + return (0); + } else { + return (ENXIO); + } +} + +static void +mcbus_intr(void *frame, u_long vector) +{ + if (vector && mcbus0_softc->sub_intr) + (*mcbus0_softc->sub_intr)((void *)vector); +} + +static void +mcbus_add_child(struct mcbus_softc *mcbus, struct mcbus_device *mdev) +{ + static int mcpciaproto, memproto, cpuproto; + device_t cd; + int un; + char *dn, *ds; + + switch (mdev->ma_type) { + case MCBUS_TYPE_PCI: + dn = "mcpcia"; + ds = "MCPCIA PCI Bus Bridge"; + un = mcpciaproto++; + break; + case MCBUS_TYPE_MEM: + dn = "mcmem"; + un = memproto++; + ds = "MCBUS Memory Module"; + break; + case MCBUS_TYPE_CPU: + dn = "mccpu"; + un = cpuproto++; + ds = "MCBUS Processor Module"; + break; + default: + printf("mcbus_add_child: unknown MCBUS type 0x%x\n", + mdev->ma_type); + return; + } + + cd = device_add_child_ordered(mcbus->mcbus_dev, mdev->ma_type, dn, un); + if (cd == NULL) { + return; + } + device_set_ivars(cd, mdev); + device_set_desc(cd, ds); +} +DRIVER_MODULE(mcbus, root, mcbus_driver, mcbus_devclass, 0, 0); diff --git a/sys/alpha/mcbus/mcbusreg.h b/sys/alpha/mcbus/mcbusreg.h new file mode 100644 index 000000000000..555a9a44145b --- /dev/null +++ b/sys/alpha/mcbus/mcbusreg.h @@ -0,0 +1,81 @@ +/* $FreeBSD$ */ + +/* + * Copyright (c) 1998, 2000 by Matthew Jacob + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * 'Register' definitions for the MCBUS main + * system bus found on AlphaServer 4100 systems. + */ + +/* + * Information gathered from:" + * + * "Rawhide System Programmer's Manual, revision 1.4". + */ + +/* + * There are 7 possible MC bus modules (architecture says 10, but + * the address map details say otherwise), 1 though 7. + * Their uses are defined as follows: + * + * MID Module + * ---- ------ + * 1 Memory + * 2 CPU + * 3 CPU + * 4 CPU, PCI + * 5 CPU, PCI + * 6 CPU, PCI + * 7 CPU, PCI + * + */ +#define MCBUS_MID_MAX 7 + +/* + * For this architecture, bit 39 of a 40 bit address controls whether + * you access I/O or Memory space. Further, there *could* be multiple + * MC busses (but only one specified for now). + */ + +#define MCBUS_IOSPACE 0x0000008000000000L +#define MCBUS_GID_MASK 0x0000007000000000L +#define MCBUS_GID_SHIFT 36 +#define MCBUS_MID_MASK 0x0000000E00000000L +#define MCBUS_MID_SHIFT 33 + +#define MAX_MC_BUS 8 + +/* + * This is something of a layering violation, but it makes probing cleaner. + */ +#define MCPCIA_PER_MCBUS 4 +/* the MCPCIA bridge CSR addresses, offset zero, is a good thing to probe for */ +#define MCPCIA_BRIDGE_ADDR(gid, mid) \ + (MCBUS_IOSPACE | 0x1E0000000LL | \ + (((unsigned long) gid) << MCBUS_GID_SHIFT) | \ + (((unsigned long) mid) << MCBUS_MID_SHIFT)) diff --git a/sys/alpha/mcbus/mcbusvar.h b/sys/alpha/mcbus/mcbusvar.h new file mode 100644 index 000000000000..09245bbbf481 --- /dev/null +++ b/sys/alpha/mcbus/mcbusvar.h @@ -0,0 +1,73 @@ +/* $FreeBSD$ */ +/* + * Copyright (c) 2000 by Matthew Jacob + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Definitions for the MCBUS System Bus found on + * AlphaServer 4100 systems. + */ + +enum mcbus_device_instvars { + MCBUS_IVAR_MID, + MCBUS_IVAR_GID, + MCBUS_IVAR_TYPE, +}; + +#define MCBUS_ACCESSOR(A, B, T) \ + \ +static __inline T mcbus_get_ ## A(device_t dev) \ +{ \ + u_long v; \ + BUS_READ_IVAR(device_get_parent(dev), dev, MCBUS_IVAR_ ## B, &v); \ + return v; \ +} + +MCBUS_ACCESSOR(mid, MID, u_int8_t) +MCBUS_ACCESSOR(gid, GID, u_int8_t) +MCBUS_ACCESSOR(type, TYPE, u_int8_t) + +/* + * The structure used to attach devices to the MCBUS + */ +struct mcbus_device { + u_int8_t ma_gid; /* GID of MCBUS (MCBUS #) */ + u_int8_t ma_mid; /* Module ID on MCBUS */ + u_int8_t ma_type; /* Module "type" */ + u_int8_t ma_order; /* order of attachment */ +}; +#define MCBUS_GID_FROM_INSTANCE(unit) (7 - unit) + +/* + * "types" + */ +#define MCBUS_TYPE_RES 0 +#define MCBUS_TYPE_UNK 1 +#define MCBUS_TYPE_MEM 2 +#define MCBUS_TYPE_CPU 3 +#define MCBUS_TYPE_PCI 4 + +#define DEVTOMCBUS(dev) ((struct mcbus_device *) device_get_ivars(dev)) diff --git a/sys/alpha/mcbus/mcmem.c b/sys/alpha/mcbus/mcmem.c new file mode 100644 index 000000000000..aa023a22b6a1 --- /dev/null +++ b/sys/alpha/mcbus/mcmem.c @@ -0,0 +1,84 @@ +/* $FreeBSD$ */ + +/* + * Copyright (c) 2000 by Matthew Jacob + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Dummy Node for MCBUS Memory Modules + * found on AlphaServer 4100 systems. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +/* + * Device methods + */ +static int mcbusmem_probe(device_t); + +static device_method_t mcbusmem_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, mcbusmem_probe), + DEVMETHOD(device_attach, bus_generic_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + + /* Bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_read_ivar, bus_generic_read_ivar), + DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + + { 0, 0 } +}; + +static devclass_t mcbusmem_devclass; +static driver_t mcbusmem_driver = { + "mcbusmem", mcbusmem_methods, 1 +}; + +static int +mcbusmem_probe(device_t dev) +{ + struct mcbus_device *mdev = DEVTOMCBUS(dev); + if (mdev->ma_type != MCBUS_TYPE_MEM) { + return (-1); + } + return (0); +} + +DRIVER_MODULE(mcbusmem, mcbus, mcbusmem_driver, mcbusmem_devclass, 0, 0); diff --git a/sys/alpha/mcbus/mcpcia.c b/sys/alpha/mcbus/mcpcia.c new file mode 100644 index 000000000000..a4b11d520661 --- /dev/null +++ b/sys/alpha/mcbus/mcpcia.c @@ -0,0 +1,781 @@ +/* $FreeBSD$ */ +/* + * Copyright (c) 2000 Matthew Jacob + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +#include +#include + +#include +#include +#include +#include + +static devclass_t mcpcia_devclass; + +/* We're only allowing for one MCBUS right now */ +static device_t mcpcias[MCPCIA_PER_MCBUS]; + +#define KV(pa) ((void *)ALPHA_PHYS_TO_K0SEG(pa)) + +struct mcpcia_softc { + struct mcpcia_softc *next; + device_t dev; /* backpointer */ + u_int64_t sysbase; /* shorthand */ + vm_offset_t dmem_base; /* dense memory */ + vm_offset_t smem_base; /* sparse memory */ + vm_offset_t io_base; /* sparse i/o */ + int mcpcia_inst; /* our mcpcia instance # */ +}; +static struct mcpcia_softc *mcpcia_eisa = NULL; + +static int mcpcia_probe(device_t dev); +static int mcpcia_attach(device_t dev); + +static int mcpcia_setup_intr(device_t, device_t, struct resource *, int, + driver_intr_t *, void *, void **); +static int +mcpcia_teardown_intr(device_t, device_t, struct resource *, void *); +static driver_intr_t mcpcia_intr; + +static device_method_t mcpcia_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, mcpcia_probe), + DEVMETHOD(device_attach, mcpcia_attach), + + /* Bus interface */ + DEVMETHOD(bus_setup_intr, mcpcia_setup_intr), + DEVMETHOD(bus_teardown_intr, mcpcia_teardown_intr), + DEVMETHOD(bus_alloc_resource, pci_alloc_resource), + DEVMETHOD(bus_release_resource, pci_release_resource), + DEVMETHOD(bus_activate_resource, pci_activate_resource), + DEVMETHOD(bus_deactivate_resource, pci_deactivate_resource), + + { 0, 0 } +}; +static driver_t mcpcia_driver = { + "mcpcia", mcpcia_methods, sizeof (struct mcpcia_softc) +}; + +/* + * SGMAP window for ISA: 8M at 8M + */ +#define MCPCIA_ISA_SG_MAPPED_BASE (8*1024*1024) +#define MCPCIA_ISA_SG_MAPPED_SIZE (8*1024*1024) + +/* + * Direct-mapped window: 2G at 2G + */ +#define MCPCIA_DIRECT_MAPPED_BASE (2UL*1024UL*1024UL*1024UL) +#define MCPCIA_DIRECT_MAPPED_SIZE (2UL*1024UL*1024UL*1024UL) + +/* + * SGMAP window for PCI: 1G at 1G + */ +#define MCPCIA_PCI_SG_MAPPED_BASE (1UL*1024UL*1024UL*1024UL) +#define MCPCIA_PCI_SG_MAPPED_SIZE (1UL*1024UL*1024UL*1024UL) + +#define MCPCIA_SGTLB_INVALIDATE(sc) \ +do { \ + alpha_mb(); \ + REGVAL(MCPCIA_SG_TBIA(sc)) = 0xdeadbeef; \ + alpha_mb(); \ +} while (0) + +static void mcpcia_dma_init(struct mcpcia_softc *); +static void mcpcia_sgmap_map(void *, vm_offset_t, vm_offset_t); + +#define MCPCIA_SOFTC(dev) (struct mcpcia_softc *) device_get_softc(dev) + +static struct mcpcia_softc *mcpcia_root; + +static alpha_chipset_inb_t mcpcia_inb; +static alpha_chipset_inw_t mcpcia_inw; +static alpha_chipset_inl_t mcpcia_inl; +static alpha_chipset_outb_t mcpcia_outb; +static alpha_chipset_outw_t mcpcia_outw; +static alpha_chipset_outl_t mcpcia_outl; +static alpha_chipset_readb_t mcpcia_readb; +static alpha_chipset_readw_t mcpcia_readw; +static alpha_chipset_readl_t mcpcia_readl; +static alpha_chipset_writeb_t mcpcia_writeb; +static alpha_chipset_writew_t mcpcia_writew; +static alpha_chipset_writel_t mcpcia_writel; +static alpha_chipset_maxdevs_t mcpcia_maxdevs; +static alpha_chipset_cfgreadb_t mcpcia_cfgreadb; +static alpha_chipset_cfgreadw_t mcpcia_cfgreadw; +static alpha_chipset_cfgreadl_t mcpcia_cfgreadl; +static alpha_chipset_cfgwriteb_t mcpcia_cfgwriteb; +static alpha_chipset_cfgwritew_t mcpcia_cfgwritew; +static alpha_chipset_cfgwritel_t mcpcia_cfgwritel; + +static alpha_chipset_t mcpcia_chipset = { + mcpcia_inb, + mcpcia_inw, + mcpcia_inl, + mcpcia_outb, + mcpcia_outw, + mcpcia_outl, + mcpcia_readb, + mcpcia_readw, + mcpcia_readl, + mcpcia_writeb, + mcpcia_writew, + mcpcia_writel, + mcpcia_maxdevs, + mcpcia_cfgreadb, + mcpcia_cfgreadw, + mcpcia_cfgreadl, + mcpcia_cfgwriteb, + mcpcia_cfgwritew, + mcpcia_cfgwritel, +}; + +#define MCPCIA_NMBR(port) ((port >> 30) & 0x3) +#define MCPCIA_INST(port) mcpcias[MCPCIA_NMBR(port)] +#define MCPCIA_ADDR(port) (port & 0x3fffffff) + +static u_int8_t +mcpcia_inb(u_int32_t port) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(port)); + if (port < (1 << 16)) { + if (mcpcia_eisa == NULL) { + return (0xff); + } + return SPARSE_READ_BYTE(mcpcia_eisa->io_base, port); + } + return SPARSE_READ_BYTE(sc->io_base, MCPCIA_ADDR(port)); +} + +static u_int16_t +mcpcia_inw(u_int32_t port) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(port)); + if (port < (1 << 16)) { + if (mcpcia_eisa == NULL) { + return (0xffff); + } + return SPARSE_READ_WORD(mcpcia_eisa->io_base, port); + } + return SPARSE_READ_WORD(sc->io_base, MCPCIA_ADDR(port)); +} + +static u_int32_t +mcpcia_inl(u_int32_t port) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(port)); + return SPARSE_READ_LONG(sc->io_base, MCPCIA_ADDR(port)); +} + +static void +mcpcia_outb(u_int32_t port, u_int8_t data) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(port)); + if (port < (1 << 16)) { + if (mcpcia_eisa) + SPARSE_WRITE_BYTE(mcpcia_eisa->io_base, port, data); + } else { + SPARSE_WRITE_BYTE(sc->io_base, MCPCIA_ADDR(port), data); + } + alpha_mb(); +} + +static void +mcpcia_outw(u_int32_t port, u_int16_t data) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(port)); + if (port < (1 << 16)) { + if (mcpcia_eisa) + SPARSE_WRITE_WORD(mcpcia_eisa->io_base, port, data); + } else { + SPARSE_WRITE_WORD(sc->io_base, MCPCIA_ADDR(port), data); + } + alpha_mb(); +} + +static void +mcpcia_outl(u_int32_t port, u_int32_t data) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(port)); + SPARSE_WRITE_LONG(sc->io_base, MCPCIA_ADDR(port), data); + alpha_mb(); +} + +static u_int8_t +mcpcia_readb(u_int32_t pa) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(pa)); + return SPARSE_READ_BYTE(sc->smem_base, MCPCIA_ADDR(pa)); +} + +static u_int16_t +mcpcia_readw(u_int32_t pa) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(pa)); + return SPARSE_READ_WORD(sc->smem_base, MCPCIA_ADDR(pa)); +} + +static u_int32_t +mcpcia_readl(u_int32_t pa) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(pa)); + return SPARSE_READ_LONG(sc->smem_base, MCPCIA_ADDR(pa)); +} + +static void +mcpcia_writeb(u_int32_t pa, u_int8_t data) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(pa)); + SPARSE_WRITE_BYTE(sc->smem_base, MCPCIA_ADDR(pa), data); + alpha_mb(); +} + +static void +mcpcia_writew(u_int32_t pa, u_int16_t data) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(pa)); + SPARSE_WRITE_WORD(sc->smem_base, MCPCIA_ADDR(pa), data); + alpha_mb(); +} + +static void +mcpcia_writel(u_int32_t pa, u_int32_t data) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(pa)); + SPARSE_WRITE_LONG(sc->smem_base, MCPCIA_ADDR(pa), data); + alpha_mb(); +} + +static int +mcpcia_maxdevs(u_int b) +{ + return (MCPCIA_MAXDEV); +} + +static u_int32_t mcpcia_cfgread(u_int, u_int, u_int, u_int, u_int, int); +static void mcpcia_cfgwrite(u_int, u_int, u_int, u_int, u_int, int, u_int32_t); + +static u_int32_t +mcpcia_cfgread(u_int bh, u_int bus, u_int slot, u_int func, u_int off, int sz) +{ + device_t dev; + struct mcpcia_softc *sc; + u_int32_t *dp, data, rvp; + u_int64_t paddr; + int secondary = 0; + + rvp = data = ~0; + if (bh > 3) + return (data); + dev = mcpcias[bh]; + if (dev == (device_t) 0) { + return (data); + } + sc = MCPCIA_SOFTC(dev); + + /* + * There's nothing in slot 0 on a primary bus. + * + * XXX: How do we generate knowledge of secondary bus accesses? + */ + if (secondary == 0 && (slot < 1 || slot >= MCPCIA_MAXDEV)) + return (data); + + paddr = secondary << 21; + paddr |= slot << 16; + paddr |= func << 13; + paddr |= ((sz - 1) << 3); + paddr |= ((unsigned long) ((off >> 2) << 7)); + paddr |= MCPCIA_PCI_CONF; + paddr |= sc->sysbase; + dp = (u_int32_t *)KV(paddr); + +#if 0 +printf("CFGREAD MID %d %d.%d.%d sz %d off %d -> paddr 0x%x", +mcbus_get_mid(dev), secondary, slot, func, sz, off, paddr); +#endif + if (badaddr(dp, sizeof (*dp)) == 0) { + data = *dp; + } + if (secondary) { + } + if (data != ~0) { + if (sz == 1) { + rvp = SPARSE_BYTE_EXTRACT(off, data); + } else if (sz == 2) { + rvp = SPARSE_WORD_EXTRACT(off, data); + } else { + rvp = data; + } + } else { + rvp = data; + } + +#if 0 +printf(" data 0x%x -> 0x%x\n", data, rvp); +#endif + return (rvp); +} + +static void +mcpcia_cfgwrite(u_int bh, u_int bus, u_int slot, u_int func, u_int off, + int sz, u_int32_t data) +{ + device_t dev; + struct mcpcia_softc *sc; + u_int32_t *dp; + u_int64_t paddr; + int secondary = 0; + + if (bh > 3) + return; + dev = mcpcias[bh]; + if (dev == (device_t) 0) { + return; + } + sc = MCPCIA_SOFTC(dev); + + /* + * There's nothing in slot 0 on a primary bus. + * + * XXX: How do we generate knowledge of secondary bus accesses? + */ + if (secondary == 0 && (slot < 1 || slot >= MCPCIA_MAXDEV)) + return; + + paddr = secondary << 21; + paddr |= slot << 16; + paddr |= func << 13; + paddr |= ((sz - 1) << 3); + paddr |= ((unsigned long) ((off >> 2) << 7)); + paddr |= MCPCIA_PCI_CONF; + paddr |= sc->sysbase; + dp = (u_int32_t *)KV(paddr); + + if (badaddr(dp, sizeof (*dp)) == 0) { + u_int32_t new_data; + if (sz == 1) { + new_data = SPARSE_BYTE_INSERT(off, data); + } else if (sz == 2) { + new_data = SPARSE_WORD_INSERT(off, data); + } else { + new_data = data; + } + +#if 0 +printf("CFGWRITE MID%d %d.%d.%d sz %d off %d paddr %lx, data %x new_data %x\n", +mcbus_get_mid(dev), secondary, slot, func, sz, off, paddr, data, new_data); +#endif + + *dp = new_data; + } + if (secondary) { + } +} + +static u_int8_t +mcpcia_cfgreadb(u_int h, u_int b, u_int s, u_int f, u_int r) +{ + return (u_int8_t) mcpcia_cfgread(h, b, s, f, r, 1); +} + +static u_int16_t +mcpcia_cfgreadw(u_int h, u_int b, u_int s, u_int f, u_int r) +{ + return (u_int16_t) mcpcia_cfgread(h, b, s, f, r, 2); +} + +static u_int32_t +mcpcia_cfgreadl(u_int h, u_int b, u_int s, u_int f, u_int r) +{ + return mcpcia_cfgread(h, b, s, f, r, 4); +} + +static void +mcpcia_cfgwriteb(u_int h, u_int b, u_int s, u_int f, u_int r, u_int8_t data) +{ + mcpcia_cfgwrite(h, b, s, f, r, 1, (u_int32_t) data); +} + +static void +mcpcia_cfgwritew(u_int h, u_int b, u_int s, u_int f, u_int r, u_int16_t data) +{ + mcpcia_cfgwrite(h, b, s, f, r, 2, (u_int32_t) data); +} + +static void +mcpcia_cfgwritel(u_int h, u_int b, u_int s, u_int f, u_int r, u_int32_t data) +{ + mcpcia_cfgwrite(h, b, s, f, r, 4, (u_int32_t) data); +} + +static int +mcpcia_probe(device_t dev) +{ + device_t child; + int unit; + struct mcpcia_softc *xc, *sc = MCPCIA_SOFTC(dev); + + unit = device_get_unit(dev); + if (mcpcias[unit]) { + printf("%s: already attached\n", device_get_nameunit(dev)); + return EEXIST; + } + sc->mcpcia_inst = unit; + if ((xc = mcpcia_root) == NULL) { + mcpcia_root = sc; + } else { + while (xc->next) + xc = xc->next; + xc->next = sc; + } + sc->dev = mcpcias[unit] = dev; + /* PROBE ? */ + device_set_desc(dev, "MCPCIA PCI Adapter"); + if (unit == 0) { + pci_init_resources(); + } + child = device_add_child(dev, "pcib", unit); + device_set_ivars(child, &sc->mcpcia_inst); + return (0); +} + +static int +mcpcia_attach(device_t dev) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(dev); + device_t p = device_get_parent(dev); + vm_offset_t regs; + u_int32_t ctl; + int mid, gid, rval; + void *intr; + + chipset = mcpcia_chipset; + mid = mcbus_get_mid(dev); + gid = mcbus_get_gid(dev); + + sc->sysbase = MCBUS_IOSPACE | + (((u_int64_t) gid) << MCBUS_GID_SHIFT) | \ + (((u_int64_t) mid) << MCBUS_MID_SHIFT); + regs = (vm_offset_t) KV(sc->sysbase); + sc->dmem_base = regs + MCPCIA_PCI_DENSE; + sc->smem_base = regs + MCPCIA_PCI_SPARSE; + sc->io_base = regs + MCPCIA_PCI_IOSPACE; + + /* + * Disable interrupts and clear errors prior to probing + */ + REGVAL(MCPCIA_INT_MASK0(sc)) = 0; + REGVAL(MCPCIA_INT_MASK1(sc)) = 0; + REGVAL(MCPCIA_CAP_ERR(sc)) = 0xFFFFFFFF; + alpha_mb(); + + + /* + * Say who we are + */ + ctl = REGVAL(MCPCIA_PCI_REV(sc)); + printf("%s: Horse Revision %d, %s Handed Saddle Revision %d," + " CAP Revision %d\n", device_get_nameunit(dev), HORSE_REV(ctl), + (SADDLE_TYPE(ctl) & 1)? "Right": "Left", SADDLE_REV(ctl), + CAP_REV(ctl)); + + /* + * See if we're the fella with the EISA bus... + */ + + if (EISA_PRESENT(REGVAL(MCPCIA_PCI_REV(sc)))) { + mcpcia_eisa = sc; + } + + /* + * Set up DMA stuff here. + */ + + mcpcia_dma_init(sc); + + /* + * Register our interrupt service requirements with out parent. + */ + rval = + BUS_SETUP_INTR(p, dev, NULL, INTR_TYPE_MISC, mcpcia_intr, 0, &intr); + if (rval == 0) { + bus_generic_attach(dev); + } + return (rval); +} + +static void mcpcia_enable_intr(struct mcpcia_softc *, int); +static void mcpcia_disable_intr(struct mcpcia_softc *, int); + +void +mcpcia_enable_intr(struct mcpcia_softc *sc, int irq) +{ + alpha_mb(); + REGVAL(MCPCIA_INT_MASK0(sc)) |= (1 << irq); + alpha_mb(); +} + +void +mcpcia_disable_intr(struct mcpcia_softc *sc, int irq) +{ + alpha_mb(); + REGVAL(MCPCIA_INT_MASK0(sc)) &= ~(1 << irq); + alpha_mb(); +} + +static int +mcpcia_setup_intr(device_t dev, device_t child, struct resource *ir, int flags, + driver_intr_t *intr, void *arg, void **cp) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(dev); + int slot, mid, gid, birq, irq, error, intpin, h; + + intpin = pci_get_intpin(child); + if (intpin == 0) { + /* No IRQ used */ + return (0); + } + if (intpin < 1 || intpin > 4) { + /* Bad IRQ */ + return (ENXIO); + } + + slot = pci_get_slot(child); + mid = mcbus_get_mid(dev); + gid = mcbus_get_gid(dev); + + if (mid == 5 && slot == 1) { + irq = 16; /* MID 5, slot 1, is the internal NCR 53c810 */ + } else if (slot >= 2 && slot <= 5) { + irq = (slot - 2) * 4; + } else { + device_printf(child, "wierd slot number (%d); can't make irq\n", + slot); + return (ENXIO); + } + error = rman_activate_resource(ir); + if (error) + return error; + + /* + * We now construct a vector as the hardware would, unless + * this is the internal NCR 53c810 interrupt. + */ + if (irq == 16) { + h = MCPCIA_VEC_NCR; + } else { + h = MCPCIA_VEC_PCI + ((mid - 4) * MCPCIA_VECWIDTH_PER_MCPCIA) + + (slot * MCPCIA_VECWIDTH_PER_SLOT) + + ((intpin - 1) * MCPCIA_VECWIDTH_PER_INTPIN); + } + birq = irq + INTRCNT_KN300_IRQ; + error = alpha_setup_intr(h, intr, arg, cp, &intrcnt[birq]); + if (error) + return error; + mcpcia_enable_intr(sc, irq); + device_printf(child, "interrupting at IRQ 0x%x INT%c (vec 0x%x)\n", + irq, intpin - 1 + 'A' , h); + return (0); +} + +static int +mcpcia_teardown_intr(device_t dev, device_t child, struct resource *i, void *c) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(dev); + int slot, mid, irq; + + slot = pci_get_slot(child); + mid = mcbus_get_mid(dev); + + if (mid == 5 && slot == 1) { + irq = 16; + } else if (slot >= 2 && slot <= 5) { + irq = (slot - 2) * 4; + } else { + return (ENXIO); + } + mcpcia_disable_intr(sc, irq); + alpha_teardown_intr(c); + return (rman_deactivate_resource(i)); +} + +static void +mcpcia_sgmap_map(void *arg, vm_offset_t ba, vm_offset_t pa) +{ + u_int64_t *sgtable = arg; + int index = alpha_btop(ba - MCPCIA_ISA_SG_MAPPED_BASE); + + if (pa) { + if (pa > (1L<<32)) + panic("mcpcia_sgmap_map: can't map address 0x%lx", pa); + sgtable[index] = ((pa >> 13) << 1) | 1; + } else { + sgtable[index] = 0; + } + alpha_mb(); + MCPCIA_SGTLB_INVALIDATE(mcpcia_eisa); +} + +static void +mcpcia_dma_init(struct mcpcia_softc *sc) +{ + + /* + * Disable all windows first. + */ + + REGVAL(MCPCIA_W0_BASE(sc)) = 0; + REGVAL(MCPCIA_W1_BASE(sc)) = 0; + REGVAL(MCPCIA_W2_BASE(sc)) = 0; + REGVAL(MCPCIA_W3_BASE(sc)) = 0; + REGVAL(MCPCIA_T0_BASE(sc)) = 0; + REGVAL(MCPCIA_T1_BASE(sc)) = 0; + REGVAL(MCPCIA_T2_BASE(sc)) = 0; + REGVAL(MCPCIA_T3_BASE(sc)) = 0; + alpha_mb(); + + /* + * Set up window 0 as an 8MB SGMAP-mapped window starting at 8MB. + * Do this only for the EISA carrying MCPCIA. Partly because + * there's only one chipset sgmap thingie. + */ + + if (sc == mcpcia_eisa) { + void *sgtable; + REGVAL(MCPCIA_W0_MASK(sc)) = MCPCIA_WMASK_8M; + + sgtable = contigmalloc(8192, M_DEVBUF, + M_NOWAIT, 0, 1L<<34, 32<<10, 1L<<34); + + if (sgtable == NULL) { + panic("mcpcia_dma_init: cannot allocate sgmap"); + /* NOTREACHED */ + } + REGVAL(MCPCIA_T0_BASE(sc)) = + pmap_kextract((vm_offset_t)sgtable) >> MCPCIA_TBASEX_SHIFT; + + alpha_mb(); + REGVAL(MCPCIA_W0_BASE(sc)) = MCPCIA_WBASE_EN | + MCPCIA_WBASE_SG | MCPCIA_ISA_SG_MAPPED_BASE; + alpha_mb(); + MCPCIA_SGTLB_INVALIDATE(sc); + chipset.sgmap = sgmap_map_create(MCPCIA_ISA_SG_MAPPED_BASE, + MCPCIA_ISA_SG_MAPPED_BASE + MCPCIA_ISA_SG_MAPPED_SIZE - 1, + mcpcia_sgmap_map, sgtable); + } + + /* + * Set up window 1 as a 2 GB Direct-mapped window starting at 2GB. + */ + + REGVAL(MCPCIA_W1_MASK(sc)) = MCPCIA_WMASK_2G; + REGVAL(MCPCIA_T1_BASE(sc)) = 0; + alpha_mb(); + REGVAL(MCPCIA_W1_BASE(sc)) = + MCPCIA_DIRECT_MAPPED_BASE | MCPCIA_WBASE_EN; + alpha_mb(); + + /* + * When we get around to redoing the 'chipset' stuff to have more + * than one sgmap handler... + */ + +#if 0 + /* + * Set up window 2 as a 1G SGMAP-mapped window starting at 1G. + */ + + REGVAL(MCPCIA_W2_MASK(sc)) = MCPCIA_WMASK_1G; + REGVAL(MCPCIA_T2_BASE(sc)) = + ccp->cc_pci_sgmap.aps_ptpa >> MCPCIA_TBASEX_SHIFT; + alpha_mb(); + REGVAL(MCPCIA_W2_BASE(sc)) = + MCPCIA_WBASE_EN | MCPCIA_WBASE_SG | MCPCIA_PCI_SG_MAPPED_BASE; + alpha_mb(); +#endif + + /* XXX XXX BEGIN XXX XXX */ + { /* XXX */ + alpha_XXX_dmamap_or = MCPCIA_DIRECT_MAPPED_BASE;/* XXX */ + } /* XXX */ + /* XXX XXX END XXX XXX */ +} + +/* + */ + +static void +mcpcia_intr(void *arg) +{ + unsigned long vec = (unsigned long) arg; + + if (vec >= MCPCIA_VEC_EISA && vec < MCPCIA_VEC_PCI) { +#if NSIO > 0 + sio_iointr(framep, vec); + return; +#else + panic("mcpcia_intr: (E)ISA interrupt support not configured " + "for vector 0x%lx", vec); +#endif + } + + /* + * Check for I2C interrupts. These are technically within + * the PCI vector range, but no PCI device should ever map + * to them. + */ + if (vec == MCPCIA_I2C_CVEC) { + printf("i2c: controller interrupt\n"); + return; + } + if (vec == MCPCIA_I2C_BVEC) { + printf("i2c: bus interrupt\n"); + return; + } + + alpha_dispatch_intr(NULL, vec); +} +DRIVER_MODULE(mcpcia, mcbus, mcpcia_driver, mcpcia_devclass, 0, 0); diff --git a/sys/alpha/mcbus/mcpciareg.h b/sys/alpha/mcbus/mcpciareg.h new file mode 100644 index 000000000000..be96586379d4 --- /dev/null +++ b/sys/alpha/mcbus/mcpciareg.h @@ -0,0 +1,438 @@ +/* $FreeBSD$ */ + +/* + * Copyright (c) 2000 by Matthew Jacob + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Taken from: + * + * ``RAWHIDE Systems Programmer's Manual, Revision 1.4'' + */ + +#define REGVAL(r) (*(volatile int32_t *)ALPHA_PHYS_TO_K0SEG(r)) + +/* + * There are 4 possible PCI busses per MCBUS. + * + * (from mcpcia.h, Digital Unix 4.0E): + * + * I/O Space Per PCI Node (8GBytes per) + * ------------------------------------ + * (8+x)8 0000 0000 - (8+x)9 FFFF FFFF - I/O Space for PCI0 + * (8+x)A 0000 0000 - (8+x)B FFFF FFFF - I/O Space for PCI1 + * (8+x)C 0000 0000 - (8+x)D FFFF FFFF - I/O Space for PCI2 + * (8+x)E 0000 0000 - (8+x)F FFFF FFFF - I/O Space for PCI3 + * + * CPU to PCI Address Mapping: + * --------------------------- + * + * +---+-------+-------+--+--+--+--+--+--+---------------+----------+-----+ + * | 1 | GID | MID | | | | | | | Byte Aligned | Byte Len | Zero| + * | | | | | | | | | | I/O Address | Field | | + * +---+-------+-------+--+--+--+--+--+--+---------------+----------+-----+ + * 39 38 36 35 33 32 31 30 29 28 27 26 5 4 3 2 0 + * + * <39> - I/O Select (Always 1 for direct I/O access) + * + * <38-36> - Global Bus slot # (MCBUS #) + * GID slot #0->7 (MCBUS #0->7) + * + * <35-33> - MCBUS Slot # + * MCBUS slot 0->7 + * + * <32-27> - PCI Address Space + * 0.xxxxx = Sparse Memory Space ( 4GB on MCBUS; 128MB on PCI) + * 1.0xxxx = Dense Memory Space ( 2GB on MCBUS; 2GB on PCI) + * 1.10xxx = Sparse IO Space ( 1GB on MCBUS; 32MB on PCI) + * 1.110xx = Sparse Config Space (512MB on MCBUS; 16MB on PCI) + * 1.1110x = PCI Bridge CSR Space (256MB on MCBUS) -- Sparse-mapped! + * 1.11110 = Interrupt Acknowledge (128MB on MCBUS) + * 1.11111 = Unused (128MB on MCBUS) + * + * ------------------------------------------------------------ + * Cpu to PCI Address Mapping for MCBUS-PCIy Bridge on MCBUS x: + * ------------------------------------------------------------ + * + * CPU Address Range PCI Address Range PCI Address Space + * ------------------------ --------------------- ------------------------ + * (8+x)(8+y*2).0000.0000 0000.0000 - 00FF.FFFF PCIy Sparse Memory Space + * - (8+x)(8+y*2).1FFF.FFFF (fixed, lower 16MB) + * + * (8+x)(8+y*2).2000.0000 0100.0000 - 07FF.FFFF PCIy Sparse Memory Space + * - (8+x)(8+y*2).FFFF.FFFF (variable, offset = 0) + * + * (8+x)(9+y*2).0000.0000 0000.0000 - 7FFF.FFFF PCIy Dense Memory Space + * - (8+x)(9+y*2).7FFF.FFFF or 8000.0000 - FFFF.FFFF if HAE_DENSE_MEM = 1 + * + * (8+x)(9+y*2).8000.0000 0000.0000 - 0000.FFFF PCIy Sparse IO Space + * - (8+x)(9+y*2).801F.FFFF (fixed, lower 64K) + * + * (8+x)(9+y*2).8020.0000 0001.0000 - 01FF.FFFF PCIy Sparse IO Space + * - (8+x)(9+y*2).BFFF.FFFF (variable, offset = 0) + * + * (8+x)(9+y*2).C000.0000 0000.0000 - 0FFF.FFFF PCIy Config Space (16MB) + * - (8+x)(9+y*2).DFFF.FFFF + * + * (8+x)(9+y*2).E000.0000 N/A PCIy-Bridge CSR Space + * (8MB) + * - (8+x)(9+y*2).EFFF.FFFF + * + * (8+x)(9+y*2).F000.0000 N/A Unused + * - (8+x)(9+y*2).F000.3EFF + * + * (8+x)(9+y*2).F000.3F00, N/A PCIy Interrupt ACK0 + * (8+x)(9+y*2).F000.3F40 PCIy INteruppt ACK1 + * + * (8+x)(9+y*2).F000.3F80 N/A Unused + * - (8+x)(9+y*2).FFFF.FFFF + * + */ + +/* + * MC-PCI Bus Bridge CSRs + * + * Address Map Overview: + * + * Offset Selected Space + * ---------------- ------------------------------------------------- + * 0x00000000 General config, control, diag, error logging regs. + * 0x00001000 PCI Error Status + * 0x00001300 PCI Scatter/Gather Regs. + * 0x00001800 Scatter/Gather TLB Regs. + * 0x00004000 MDPA Error Status & Diagnostic Control + * 0x00008000 MDPB Error Status & Diagnostic Control + * 0x000E0000 - Flash Rom Space -- + * 0x000FFFFF offset address into PCI Dense Mem Space + * 0x10003F00 Interrupt Acknowledge + * + */ + + +/* + * Address Space Cookies + */ + +#define MCPCIA_PCI_SPARSE 0x000000000LL +#define MCPCIA_PCI_DENSE 0x100000000LL +#define MCPCIA_PCI_IOSPACE 0x180000000LL +#define MCPCIA_PCI_CONF 0x1C0000000LL +#define MCPCIA_PCI_BRIDGE 0x1E0000000LL +#define MCPCIA_PCI_IACK 0x1F0000000LL + +/* + * MCPCIA Bus Bridge Registers + * + * These are offsets that don't include GBUS, MID, or address space offsets. + */ + +#define _MCPCIA_PCI_REV 0x000000000 /* PCI Revision Register (R) */ +#define _MCPCIA_WHOAMI 0x000000040 /* PCI Who Am I (R) */ +#define _MCPCIA_PCI_LAT 0x000000080 /* PCI Latency Timer (RW) */ +#define _MCPCIA_CAP_CTRL 0x000000100 /* PCI Bridge Control (RW) */ +#define _MCPCIA_HAE_MEM 0x000000400 /* PCI HAE Sparse Memory (RW) */ +#define _MCPCIA_HAE_IO 0x000000440 /* PCI HAE Sparse I/O (RW) */ +#define _MCPCIA_IACK_SC 0x000000480 /* PCI Special Cycle Ack */ +#define _MCPCIA_HAE_DENSE 0x0000004C0 /* PCI HAE Dense Memory (RW) */ + +#define _MCPCIA_INT_CTL 0x000000500 /* PCI Interrupt Control */ +#define _MCPCIA_INT_REQ 0x000000540 /* PCI Interrupt Request */ +#define _MCPCIA_INT_TARG 0x000000580 /* PCI Int Tgt Devices */ +#define _MCPCIA_INT_ADR 0x0000005C0 /* PCI Int Tgt Address */ +#define _MCPCIA_INT_ADR_EXT 0x000000600 /* PCI Int Tgt Addr Ext */ +#define _MCPCIA_INT_MASK0 0x000000640 /* PCI Int Mask 0 */ +#define _MCPCIA_INT_MASK1 0x000000680 /* PCI Int Mask 1 */ + +#define _MCPCIA_INT_ACK0 0x100003F00 /* PCI Int Ack 0 */ +#define _MCPCIA_INT_ACK1 0x100003F40 /* PCI Int Ack 1 */ + +#define _MCPCIA_PERF_MON 0x000000300 /* PCI Perf Monitor */ +#define _MCPCIA_PERF_CONT 0x000000340 /* PCI Perf Monitor Control */ + +#define _MCPCIA_CAP_DIAG 0x000000700 /* MC-PCI Diagnostic Control */ +#define _MCPCIA_SCRATCH0 0x000000740 /* Diag General */ +#define _MCPCIA_SCRATCH1 0x000000780 /* Diag General */ +#define _MCPCIA_TOM 0x0000007C0 /* Top Of Memory */ +#define _MCPCIA_MC_ERR0 0x000000800 /* MC Err Info 0 */ +#define _MCPCIA_MC_ERR1 0x000000840 /* MC Err Info 1 */ +#define _MCPCIA_CAP_ERR 0x000000880 /* CAP Error Register */ + +#define _MCPCIA_PCI_ERR1 0x000001040 /* PCI Error Status */ + +#define _MCPCIA_MDPA_STAT 0x000004000 /* MDPA Status */ +#define _MCPCIA_MDPA_SYN 0x000004040 /* MDPA Syndrome */ +#define _MCPCIA_MDPA_DIAG 0x000004080 /* Diag Check MDPA */ + +#define _MCPCIA_MDPB_STAT 0x000008000 /* MDPB Status */ +#define _MCPCIA_MDPB_SYN 0x000008040 /* MDPB Syndrome */ +#define _MCPCIA_MDPB_DIAG 0x000008080 /* Diag Check MDPB */ + +#define _MCPCIA_SG_TBIA 0x000001300 /* Scatter/Gather TBIA */ +#define _MCPCIA_HBASE 0x000001340 /* PC "Hole" Compatibility */ +#define _MCPCIA_W0_BASE 0x000001400 /* Window Base 0 */ +#define _MCPCIA_W0_MASK 0x000001440 /* Window Mask 0 */ +#define _MCPCIA_T0_BASE 0x000001480 /* Translated Base 0 */ +#define _MCPCIA_W1_BASE 0x000001500 /* Window Base 1 */ +#define _MCPCIA_W1_MASK 0x000001540 /* Window Mask 1 */ +#define _MCPCIA_T1_BASE 0x000001580 /* Translated Base 1 */ +#define _MCPCIA_W2_BASE 0x000001600 /* Window Base 2 */ +#define _MCPCIA_W2_MASK 0x000001640 /* Window Mask 2 */ +#define _MCPCIA_T2_BASE 0x000001680 /* Translated Base 2 */ +#define _MCPCIA_W3_BASE 0x000001700 /* Window Base 3 */ +#define _MCPCIA_W3_MASK 0x000001740 /* Window Mask 3 */ +#define _MCPCIA_T3_BASE 0x000001780 /* Translated Base 3 */ +#define _MCPCIA_W_DAC 0x0000017C0 /* Window DAC Base */ + + +/* + * Handier defines- uses precalculated offset in softc. + */ +#define _SYBRIDGE(ccp) ((ccp)->sysbase | MCPCIA_PCI_BRIDGE) + +#define MCPCIA_PCI_REV(ccp) (_SYBRIDGE(ccp) | _MCPCIA_PCI_REV) +#define MCPCIA_WHOAMI(ccp) (_SYBRIDGE(ccp) | _MCPCIA_WHOAMI) +#define MCPCIA_PCI_LAT(ccp) (_SYBRIDGE(ccp) | _MCPCIA_PCI_LAT) +#define MCPCIA_CAP_CTRL(ccp) (_SYBRIDGE(ccp) | _MCPCIA_CAP_CTRL) +#define MCPCIA_HAE_MEM(ccp) (_SYBRIDGE(ccp) | _MCPCIA_HAE_MEM) +#define MCPCIA_HAE_IO(ccp) (_SYBRIDGE(ccp) | _MCPCIA_HAE_IO) +#define MCPCIA_IACK_SC(ccp) (_SYBRIDGE(ccp) | _MCPCIA_IACK_SC) +#define MCPCIA_HAE_DENSE(ccp) (_SYBRIDGE(ccp) | _MCPCIA_HAE_DENSE) +#define MCPCIA_INT_CTL(ccp) (_SYBRIDGE(ccp) | _MCPCIA_INT_CTL) +#define MCPCIA_INT_REQ(ccp) (_SYBRIDGE(ccp) | _MCPCIA_INT_REQ) +#define MCPCIA_INT_TARG(ccp) (_SYBRIDGE(ccp) | _MCPCIA_INT_TARG) +#define MCPCIA_INT_ADR(ccp) (_SYBRIDGE(ccp) | _MCPCIA_INT_ADR) +#define MCPCIA_INT_ADR_EXT(ccp) (_SYBRIDGE(ccp) | _MCPCIA_INT_ADR_EXT) +#define MCPCIA_INT_MASK0(ccp) (_SYBRIDGE(ccp) | _MCPCIA_INT_MASK0) +#define MCPCIA_INT_MASK1(ccp) (_SYBRIDGE(ccp) | _MCPCIA_INT_MASK1) +#define MCPCIA_INT_ACK0(ccp) (_SYBRIDGE(ccp) | _MCPCIA_INT_ACK0) +#define MCPCIA_INT_ACK1(ccp) (_SYBRIDGE(ccp) | _MCPCIA_INT_ACK1) +#define MCPCIA_PERF_MON(ccp) (_SYBRIDGE(ccp) | _MCPCIA_PERF_MON) +#define MCPCIA_PERF_CONT(ccp) (_SYBRIDGE(ccp) | _MCPCIA_PERF_CONT) +#define MCPCIA_CAP_DIAG(ccp) (_SYBRIDGE(ccp) | _MCPCIA_CAP_DIAG) +#define MCPCIA_SCRATCH0(ccp) (_SYBRIDGE(ccp) | _MCPCIA_SCRATCH0) +#define MCPCIA_SCRATCH1(ccp) (_SYBRIDGE(ccp) | _MCPCIA_SCRATCH1) +#define MCPCIA_TOM(ccp) (_SYBRIDGE(ccp) | _MCPCIA_TOM) +#define MCPCIA_MC_ERR0(ccp) (_SYBRIDGE(ccp) | _MCPCIA_MC_ERR0) +#define MCPCIA_MC_ERR1(ccp) (_SYBRIDGE(ccp) | _MCPCIA_MC_ERR1) +#define MCPCIA_CAP_ERR(ccp) (_SYBRIDGE(ccp) | _MCPCIA_CAP_ERR) +#define MCPCIA_PCI_ERR1(ccp) (_SYBRIDGE(ccp) | _MCPCIA_PCI_ERR1) +#define MCPCIA_MDPA_STAT(ccp) (_SYBRIDGE(ccp) | _MCPCIA_MDPA_STAT) +#define MCPCIA_MDPA_SYN(ccp) (_SYBRIDGE(ccp) | _MCPCIA_MDPA_SYN) +#define MCPCIA_MDPA_DIAG(ccp) (_SYBRIDGE(ccp) | _MCPCIA_MDPA_DIAG) +#define MCPCIA_MDPB_STAT(ccp) (_SYBRIDGE(ccp) | _MCPCIA_MDPB_STAT) +#define MCPCIA_MDPB_SYN(ccp) (_SYBRIDGE(ccp) | _MCPCIA_MDPB_SYN) +#define MCPCIA_MDPB_DIAG(ccp) (_SYBRIDGE(ccp) | _MCPCIA_MDPB_DIAG) +#define MCPCIA_SG_TBIA(ccp) (_SYBRIDGE(ccp) | _MCPCIA_SG_TBIA) +#define MCPCIA_HBASE(ccp) (_SYBRIDGE(ccp) | _MCPCIA_HBASE) +#define MCPCIA_W0_BASE(ccp) (_SYBRIDGE(ccp) | _MCPCIA_W0_BASE) +#define MCPCIA_W0_MASK(ccp) (_SYBRIDGE(ccp) | _MCPCIA_W0_MASK) +#define MCPCIA_T0_BASE(ccp) (_SYBRIDGE(ccp) | _MCPCIA_T0_BASE) +#define MCPCIA_W1_BASE(ccp) (_SYBRIDGE(ccp) | _MCPCIA_W1_BASE) +#define MCPCIA_W1_MASK(ccp) (_SYBRIDGE(ccp) | _MCPCIA_W1_MASK) +#define MCPCIA_T1_BASE(ccp) (_SYBRIDGE(ccp) | _MCPCIA_T1_BASE) +#define MCPCIA_W2_BASE(ccp) (_SYBRIDGE(ccp) | _MCPCIA_W2_BASE) +#define MCPCIA_W2_MASK(ccp) (_SYBRIDGE(ccp) | _MCPCIA_W2_MASK) +#define MCPCIA_T2_BASE(ccp) (_SYBRIDGE(ccp) | _MCPCIA_T2_BASE) +#define MCPCIA_W3_BASE(ccp) (_SYBRIDGE(ccp) | _MCPCIA_W3_BASE) +#define MCPCIA_W3_MASK(ccp) (_SYBRIDGE(ccp) | _MCPCIA_W3_MASK) +#define MCPCIA_T3_BASE(ccp) (_SYBRIDGE(ccp) | _MCPCIA_T3_BASE) +#define MCPCIA_W_DAC(ccp) (_SYBRIDGE(ccp) | _MCPCIA_W_DAC) + +/* + * This is here for what error handling will get as a collected subpacket. + */ + +struct mcpcia_iodsnap { + u_int64_t base_addr; + u_int32_t whami; + u_int32_t rsvd0; + u_int32_t pci_rev; + u_int32_t cap_ctrl; + u_int32_t hae_mem; + u_int32_t hae_io; + u_int32_t int_ctl; + u_int32_t int_reg; + u_int32_t int_mask0; + u_int32_t int_mask1; + u_int32_t mc_err0; + u_int32_t mc_err1; + u_int32_t cap_err; + u_int32_t sys_env; + u_int32_t pci_err1; + u_int32_t mdpa_stat; + u_int32_t mdpa_syn; + u_int32_t mdpb_stat; + u_int32_t mdpb_syn; + u_int32_t rsvd2; + u_int32_t rsvd3; + u_int32_t rsvd4; +}; + +/* + * PCI_REV Register definitions + */ +#define CAP_REV(reg) ((reg) & 0xf) +#define HORSE_REV(reg) (((reg) >> 4) & 0xf) +#define SADDLE_REV(reg) (((reg) >> 8) & 0xf) +#define SADDLE_TYPE(reg) (((reg) >> 12) & 0x3) +#define EISA_PRESENT(reg) ((reg) & (1 << 15)) +#define IS_MCPCIA_MAGIC(reg) (((reg) & 0xffff0000) == 0x6000000) + + +/* + * WHOAMI Register definitions + * + * The Device ID is an echo of the MID of the CPU reading this register- + * cheezy way to figure out who you are (ask someone else!). + */ +#define MCBUS_CPU_MID(x) ((x) & 0x7) +#define MCBUS_CPU_INFO(x) (((x) >> 6) & 0xff) +#define CPU_Fill_Err 0x80 +#define CPU_DTAG_Perr 0x40 +#define CPU_RevMask 0x38 +#define CPU_RevShift 3 +#define CPU_BCacheMask 0x3 +#define CPU_BCache_0MB 0 +#define CPU_BCache_1MB 1 +#define CPU_BCache_2MB 2 +#define CPU_BCache_4MB 3 + +/* + * PCI Latency Register Definitions + */ +#define PCI_LAT_SHIFT 8 /* it's in the 2nd byte. */ + +/* + * CAP Control Register Defintions + */ +#define CAP_LED_ON 0x00000001 /* Selftest LED passed */ +#define CAP_EV56_BW_EN 0x00000002 /* BW Enables (EV56, EV6 only) */ +#define CAP_DLY_RD_EN 0x00000010 /* PCI Delayed Reads Enabled */ +#define CAP_MEM_EN 0x00000020 /* Respond to PCI transactions */ +#define CAP_REQ64_EN 0x00000040 /* Request 64 bit data transactions */ +#define CAP_ACK64_EN 0x00000080 /* Respond to 64 bit data "" */ +#define CAP_ADR_PAR_EN 0x00000100 /* Check PCI address Parity */ +#define CAP_MC_CA_PAR 0x00000200 /* Check MC bus CMD/Address Parity */ +#define CAP_MC_NXM_EN 0x00000400 /* Check for MC NXM */ +#define CAP_BUS_MON 0x00000800 /* Check for PCI errs (as bystander) */ +/* bits 19:16 control number of pending write transactions */ +#define SHORT 0 +#define MED 1 +#define LONG 2 +#define CAP_MEMRD_PREFETCH_SHIFT 20 +#define CAP_MEMRDLN_PREFETCH_SHIFT 22 +#define CAP_MEMRDMULT_PREFETCH_SHIFT 24 +#define CAP_PARTIAL_WRITE (1 << 26) + +#define CAP_ARB_BPRI 0x00000000 /* Bridge Priority Arb */ +#define CAP_ARB_RROBIN 0x40000000 /* "" Round Robin */ +#define CAP_ARB_RROBIN1 0x80000000 /* "" Round Robin #1 */ + +/* + * Diagnostic Register Bits + */ +/* CAP_DIAG register */ +#define CAP_DIAG_PCIRESET 0x1 /* + * WriteOnly. Assert 1 for 100usec min., + * then write zero. NOTE: deadlocks + * exist in h/w if anything but this + * register is accessed while reset + * is asserted. + */ +#define CAP_DIAG_MC_ADRPE (1<<30) /* Invert MC Bus Address/Parity */ +#define CAP_DIAG_PCI_ADRPE (1<<31) /* Force bad PCI parity (low 32) */ + +/* MDPA_DIAG or MDPB_DIAG registers */ +#define MDPX_ECC_ENA (1<<28) /* Enable ECC on MC Bus (default 1) */ +#define MDPX_PAR_ENA (1<<29) /* Enable Parity on PCI (default 0) */ +#define MDPX_DIAG_FPE_PCI (1<<30) /* Force PCI parity error */ +#define MDPX_DIAG_USE_CHK (1<<31) /* + * When set, DMA write cycles use the + * value in the low 8 bits of this + * register (MDPA or MDPB) as ECC + * sent onto main memory. + */ + +/* + * Interrupt Specific bits... + * + * Mostly we don't have to mess with any of the interrupt specific registers + * as the SRM has set most of this pretty complex stuff up for us. + * + * However, to enable specific interrupts, we need to set some bits + * in imask0 if we want to have them vectored to PALcode for appropriate + * dispatch. + */ + +/* + * bits 0-15 correspond to 4 slots (time 4 buspins) for each PCI bus. + * bit 16 is the NCR810 onboard SCSI interrupt. + * bits 19-20 are reserved. + */ + +#define MCPCIA_I2C_CTRL_INTR (1<<17) +#define MCPCIA_I2C_CTRL_BUS_ERR (1<<18) + +#define MCPCIA_8259_NMI_INTR (1<<21) +#define MCPCIA_SOFT_ERR_INTR (1<<22) +#define MCPCIA_HARD_ERR_INTR (1<<23) + +#ifdef YET +#define MCPCIA_GEN_IENABL \ + (MCPCIA_I2C_CTRL_BUS_ERR|MCPCIA_SOFT_ERR_INTR|MCPCIA_HARD_ERR_INTR) +#else +#define MCPCIA_GEN_IENABL \ + (MCPCIA_SOFT_ERR_INTR|MCPCIA_HARD_ERR_INTR) +#endif + +/* + * DMA Address Specific bits... + */ + +#define MCPCIA_WBASE_EN 0x1 +#define MCPCIA_WBASE_SG 0x2 +#define MCPCIA_WBASE_DAC 0x8 +#define MCPCIA_WBASE_BSHIFT 20 + +#define MCPCIA_WMASK_1M 0x00000000 +#define MCPCIA_WMASK_2M 0x00100000 +#define MCPCIA_WMASK_4M 0x00300000 +#define MCPCIA_WMASK_8M 0x00700000 +#define MCPCIA_WMASK_16M 0x00f00000 +#define MCPCIA_WMASK_32M 0x01f00000 +#define MCPCIA_WMASK_64M 0x03f00000 +#define MCPCIA_WMASK_128M 0x07f00000 +#define MCPCIA_WMASK_256M 0x0ff00000 +#define MCPCIA_WMASK_512M 0x1ff00000 +#define MCPCIA_WMASK_1G 0x3ff00000 +#define MCPCIA_WMASK_2G 0x7ff00000 +#define MCPCIA_WMASK_4G 0xfff00000 + +/* + * The WBASEX register contains bits 39:10 of a physical address + * shifted to bits 31:2 of this 32 bit register. Namely, shifted + * right by 8 bits. + */ +#define MCPCIA_TBASEX_SHIFT 8 diff --git a/sys/alpha/mcbus/mcpciavar.h b/sys/alpha/mcbus/mcpciavar.h new file mode 100644 index 000000000000..4bcca77a9fa2 --- /dev/null +++ b/sys/alpha/mcbus/mcpciavar.h @@ -0,0 +1,58 @@ +/* $FreeBSD$ */ + +/* + * Copyright (c) 1998, 2000 by Matthew Jacob + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * There are four PCI slots per MCPCIA PCI bus here, but some are 'hidden'- + * none seems to be higher than 6 though. + */ +#define MCPCIA_MAXDEV 6 +#define MCPCIA_MAXSLOT 8 + +/* + * Interrupt Stuff for MCPCIA systems. + * + * EISA interrupts (at vector 0x800) have to be shared interrupts- + * and that can be easily managed. All the PCI interrupts are deterministic + * in that they start at vector 0x900, 0x40 per PCI slot, 0x200 per + * MCPCIA, 4 MCPCIAs per GCBUS.... + */ +#define MCPCIA_EISA_KEYB_IRQ 1 +#define MCPCIA_EISA_MOUSE_IRQ 12 +#define MCPCIA_VEC_EISA 0x800 +#define MCPCIA_VEC_PCI 0x900 +#define MCPCIA_VEC_NCR 0xB40 + +#define MCPCIA_VECWIDTH_PER_MCPCIA 0x200 +#define MCPCIA_VECWIDTH_PER_SLOT 0x40 +#define MCPCIA_VECWIDTH_PER_INTPIN 0x10 + +/* + * Special Vectors + */ +#define MCPCIA_I2C_CVEC 0xA90 +#define MCPCIA_I2C_BVEC 0xAA0