summaryrefslogtreecommitdiff
path: root/sys/arch/vax/mbus
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/vax/mbus')
-rw-r--r--sys/arch/vax/mbus/dz_fwio.c215
-rw-r--r--sys/arch/vax/mbus/files.mbus29
-rw-r--r--sys/arch/vax/mbus/fwio.c111
-rw-r--r--sys/arch/vax/mbus/fwioreg.h45
-rw-r--r--sys/arch/vax/mbus/fwiovar.h28
-rw-r--r--sys/arch/vax/mbus/if_le_fwio.c272
-rw-r--r--sys/arch/vax/mbus/mbus.c441
-rw-r--r--sys/arch/vax/mbus/mbusreg.h251
-rw-r--r--sys/arch/vax/mbus/mbusvar.h33
-rw-r--r--sys/arch/vax/mbus/sii_fwio.c163
-rw-r--r--sys/arch/vax/mbus/uba_mbus.c174
11 files changed, 1762 insertions, 0 deletions
diff --git a/sys/arch/vax/mbus/dz_fwio.c b/sys/arch/vax/mbus/dz_fwio.c
new file mode 100644
index 00000000000..678d833bac0
--- /dev/null
+++ b/sys/arch/vax/mbus/dz_fwio.c
@@ -0,0 +1,215 @@
+/* $OpenBSD: dz_fwio.c,v 1.1 2008/08/18 23:19:25 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 1998 Ludd, University of Lule}, Sweden.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+
+#include <machine/bus.h>
+
+#include <vax/mbus/mbusreg.h>
+#include <vax/mbus/mbusvar.h>
+#include <vax/mbus/fwioreg.h>
+#include <vax/mbus/fwiovar.h>
+
+#include <vax/qbus/dzreg.h>
+#include <vax/qbus/dzvar.h>
+
+#include <vax/dec/dzkbdvar.h>
+
+#include <sys/tty.h>
+#include <dev/cons.h>
+
+#include "dzkbd.h"
+#include "dzms.h"
+
+int dz_fwio_match(struct device *, void *, void *);
+void dz_fwio_attach(struct device *, struct device *, void *);
+
+struct cfattach dz_fwio_ca = {
+ sizeof(struct dz_softc), dz_fwio_match, dz_fwio_attach
+};
+
+extern struct cfdriver dz_cd;
+
+int dz_fwio_intr(void *);
+
+#define DZ_FWIO_CSR 0
+#define DZ_FWIO_RBUF 4
+#define DZ_FWIO_DTR 9
+#define DZ_FWIO_BREAK 13
+#define DZ_FWIO_TBUF 12
+#define DZ_FWIO_TCR 8
+#define DZ_FWIO_DCD 13
+#define DZ_FWIO_RING 13
+
+int
+dz_fwio_match(struct device *parent, void *vcf, void *aux)
+{
+ struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;
+
+ return strcmp(faa->faa_dev, dz_cd.cd_name) == 0 ? 1 : 0;
+}
+
+void
+dz_fwio_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;
+ struct dz_softc *sc = (struct dz_softc *)self;
+ paddr_t basepa;
+#if NDZKBD > 0 || NDZMS > 0
+ struct dzkm_attach_args daa;
+ extern struct consdev wsdisplay_cons;
+#endif
+ extern vaddr_t dz_console_regs;
+ vaddr_t dz_regs;
+ unsigned int vec;
+ int console;
+ int serial_console;
+
+ vec = faa->faa_vecbase + FBIC_DEVIRQ2 * 4;
+ printf(" vec %d: ", vec);
+
+ /*
+ * Map registers.
+ */
+
+ if (dz_console_regs != 0 && faa->faa_mid == mbus_ioslot) {
+ dz_regs = dz_console_regs;
+ console = 1;
+ serial_console = 1; /* XXX forced for now */
+ if (serial_console)
+ printf("console, ");
+ } else {
+ basepa = faa->faa_base + FWIO_DZ_REG_OFFSET;
+ dz_regs = vax_map_physmem(basepa, 1);
+ console = 0;
+ }
+
+ /*
+ * XXX - This is evil and ugly, but...
+ * due to the nature of how bus_space_* works on VAX, this will
+ * be perfectly good until everything is converted.
+ */
+ sc->sc_ioh = dz_regs;
+
+ sc->sc_dr.dr_csr = DZ_FWIO_CSR;
+ sc->sc_dr.dr_rbuf = DZ_FWIO_RBUF;
+ sc->sc_dr.dr_tbuf = DZ_FWIO_TBUF;
+ sc->sc_dr.dr_tcr = DZ_FWIO_TCR;
+ sc->sc_dr.dr_dtr = DZ_FWIO_DTR;
+ sc->sc_dr.dr_break = DZ_FWIO_BREAK;
+ sc->sc_dr.dr_dcd = DZ_FWIO_DCD;
+ sc->sc_dr.dr_ring = DZ_FWIO_RING;
+
+ sc->sc_type = DZ_DZV;
+
+ /* no modem ctrl bits except on line 2 */
+ sc->sc_dsr = (1 << 0) | (1 << 1) | (1 << 3);
+
+ printf("4 lines");
+
+ /*
+ * Complete attachment.
+ */
+
+ dzattach(sc);
+
+ /*
+ * Register interrupt handler.
+ */
+
+ if (mbus_intr_establish(vec, IPL_TTY, dz_fwio_intr, sc,
+ self->dv_xname) != 0) {
+ printf("\n%s: can't establish interrupt\n", self->dv_xname);
+ return;
+ }
+
+ /*
+ * Attach input devices, if any.
+ */
+
+#if NDZKBD > 0
+ daa.daa_line = 0;
+ DZ_WRITE_WORD(sc, dr_rbuf, DZ_LPR_RX_ENABLE | (DZ_LPR_B4800 << 8) |
+ DZ_LPR_8_BIT_CHAR | daa.daa_line);
+ daa.daa_flags =
+ (console && cn_tab == &wsdisplay_cons ? DZKBD_CONSOLE : 0);
+ config_found(self, &daa, dz_print);
+#endif
+#if NDZMS > 0
+ daa.daa_line = 1;
+ DZ_WRITE_WORD(sc, dr_rbuf, DZ_LPR_RX_ENABLE | (DZ_LPR_B4800 << 8) |
+ DZ_LPR_8_BIT_CHAR | DZ_LPR_PARENB | DZ_LPR_OPAR | daa.daa_line);
+ daa.daa_flags = 0;
+ config_found(self, &daa, dz_print);
+#endif
+}
+
+int
+dz_fwio_intr(void *v)
+{
+ struct dz_softc *sc = (struct dz_softc *)v;
+
+ /*
+ * FBIC expects edge interrupts, while the dz does level
+ * interrupts. To avoid missing interrupts while servicing,
+ * we disable further device interrupts while servicing.
+ */
+ DZ_WRITE_WORD(sc, dr_csr,
+ DZ_READ_WORD(sc, dr_csr) & ~(DZ_CSR_RXIE | DZ_CSR_TXIE));
+
+ dzrint(sc);
+ dzxint(sc);
+
+ DZ_WRITE_WORD(sc, dr_csr,
+ DZ_READ_WORD(sc, dr_csr) | (DZ_CSR_RXIE | DZ_CSR_TXIE));
+
+ return 1;
+}
diff --git a/sys/arch/vax/mbus/files.mbus b/sys/arch/vax/mbus/files.mbus
new file mode 100644
index 00000000000..8b692910545
--- /dev/null
+++ b/sys/arch/vax/mbus/files.mbus
@@ -0,0 +1,29 @@
+# $OpenBSD: files.mbus,v 1.1 2008/08/18 23:19:25 miod Exp $
+
+# VAXstation 3[58][24]0 internal bus
+device mbus { [mid = -1] }
+attach mbus at mainbus
+file arch/vax/mbus/mbus.c mbus
+
+# L2003 Firefox Workstation I/O Module
+device fwio {}
+attach fwio at mbus
+file arch/vax/mbus/fwio.c fwio
+
+attach dz at fwio with dz_fwio: dzcons
+file arch/vax/mbus/dz_fwio.c dz_fwio
+
+attach le at fwio with le_fwio
+file arch/vax/mbus/if_le_fwio.c le_fwio
+
+attach sii at fwio with sii_fwio
+file arch/vax/mbus/sii_fwio.c sii_fwio
+
+# L2008 CQBIC
+attach uba at mbus with uba_mbus
+file arch/vax/mbus/uba_mbus.c uba_mbus
+
+# L2001 or L2010 CPU
+# L2004 LEGSS video
+# (with L2005 8-plane output module and optional L2006 16-plane module)
+# L2007 memory
diff --git a/sys/arch/vax/mbus/fwio.c b/sys/arch/vax/mbus/fwio.c
new file mode 100644
index 00000000000..32d62fc7542
--- /dev/null
+++ b/sys/arch/vax/mbus/fwio.c
@@ -0,0 +1,111 @@
+/* $OpenBSD: fwio.c,v 1.1 2008/08/18 23:19:25 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Firefox Workstation I/O Module
+ *
+ * This M-bus board sports:
+ * - a System Support Chip implementing the (off cpu) clocks.
+ * - a SII controller, in SCSI mode, with 128KB static memory.
+ * - a LANCE Ethernet controller, with 128KB static memory.
+ * - a DZQ11-compatible DC7085 4 lines serial controller.
+ */
+
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+#include <machine/nexus.h>
+
+#include <vax/mbus/mbusreg.h>
+#include <vax/mbus/mbusvar.h>
+#include <vax/mbus/fwioreg.h>
+#include <vax/mbus/fwiovar.h>
+
+struct fwio_softc {
+ struct device sc_dev;
+ int sc_loc[1]; /* locators override */
+};
+
+void fwio_attach(struct device *, struct device *, void *);
+int fwio_match(struct device *, void *, void *);
+
+struct cfdriver fwio_cd = {
+ NULL, "fwio", DV_DULL
+};
+
+const struct cfattach fwio_ca = {
+ sizeof(struct fwio_softc), fwio_match, fwio_attach
+};
+
+int fwio_print(void *, const char *);
+
+int
+fwio_match(struct device *parent, void *vcf, void *aux)
+{
+ struct mbus_attach_args *maa = (struct mbus_attach_args *)aux;
+
+ if (maa->maa_class == CLASS_IO && maa->maa_interface == INTERFACE_FBIC)
+ return 1;
+
+ return 0;
+}
+
+void
+fwio_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct mbus_attach_args *maa = (struct mbus_attach_args *)aux;
+ struct fwio_softc *sc = (struct fwio_softc *)self;
+ struct fwio_attach_args faa;
+
+ printf("\n");
+
+ /*
+ * Save our mid in locators. booted_sd() in autoconf.c depends
+ * on this to find the correct boot device.
+ */
+ sc->sc_loc[0] = maa->maa_mid;
+ self->dv_cfdata->cf_loc = sc->sc_loc;
+
+ faa.faa_mid = maa->maa_mid;
+ faa.faa_base = MBUS_SLOT_BASE(maa->maa_mid);
+ faa.faa_vecbase = maa->maa_vecbase;
+
+ faa.faa_dev = "dz";
+ (void)config_found(self, &faa, fwio_print);
+
+ faa.faa_dev = "le";
+ (void)config_found(self, &faa, fwio_print);
+
+ faa.faa_dev = "sii";
+ (void)config_found(self, &faa, fwio_print);
+}
+
+int
+fwio_print(void *aux, const char *pnp)
+{
+ struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;
+
+ if (pnp != NULL)
+ printf("%s at %s", faa->faa_dev, pnp);
+
+ return (UNCONF);
+}
diff --git a/sys/arch/vax/mbus/fwioreg.h b/sys/arch/vax/mbus/fwioreg.h
new file mode 100644
index 00000000000..81b4a6986d7
--- /dev/null
+++ b/sys/arch/vax/mbus/fwioreg.h
@@ -0,0 +1,45 @@
+/* $OpenBSD: fwioreg.h,v 1.1 2008/08/18 23:19:25 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Firefox Workstation I/O Module registers and memory layout
+ */
+
+#define FWIO_SSC_REMAP_ADDR 0x21400000
+
+#define FWIO_SII_REG_OFFSET 0x000000
+#define FWIO_LANCE_REG_OFFSET 0x200000
+#define FWIO_SII_BUF_OFFSET 0x400000
+#define FWIO_SII_BUF_SIZE 0x020000
+#define FWIO_DZ_REG_OFFSET 0x600000
+#define FWIO_IOCSR_OFFSET 0x800000
+#define FWIO_ESAR_OFFSET 0x800000
+#define FWIO_LANCE_BUF_OFFSET 0xa00000
+#define FWIO_LANCE_BUF_SIZE 0x020000
+
+/*
+ * IOCSR bits
+ */
+
+#define FWIO_IOCSR_CNSL 0x80000000 /* break on line 3 asserts MHALT */
+#define FWIO_IOCSR_MRUN 0x40000000 /* assert MRUN */
+#define FWIO_IOCSR_CLKIEN 0x20000000 /* drive MCLKI */
+#define FWIO_IOCSR_RSTWS 0x10000000 /* reset workstation */
+
+#define FWIO_ESAR_MASK 0x00ff0000
+#define FWIO_ESAR_SHIFT 16
diff --git a/sys/arch/vax/mbus/fwiovar.h b/sys/arch/vax/mbus/fwiovar.h
new file mode 100644
index 00000000000..05f5e4a26af
--- /dev/null
+++ b/sys/arch/vax/mbus/fwiovar.h
@@ -0,0 +1,28 @@
+/* $OpenBSD: fwiovar.h,v 1.1 2008/08/18 23:19:25 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Firefox Workstation I/O Module subdevice attachment glue
+ */
+
+struct fwio_attach_args {
+ const char *faa_dev;
+ unsigned int faa_mid;
+ paddr_t faa_base;
+ unsigned int faa_vecbase;
+};
diff --git a/sys/arch/vax/mbus/if_le_fwio.c b/sys/arch/vax/mbus/if_le_fwio.c
new file mode 100644
index 00000000000..8a0011535f5
--- /dev/null
+++ b/sys/arch/vax/mbus/if_le_fwio.c
@@ -0,0 +1,272 @@
+/* $OpenBSD: if_le_fwio.c,v 1.1 2008/08/18 23:19:25 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
+ * Simulation Facility, NASA Ames Research Center.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell and Rick Macklem.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)if_le.c 8.2 (Berkeley) 11/16/93
+ */
+
+#include "bpfilter.h"
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#if INET
+#include <netinet/in.h>
+#endif
+#include <netinet/if_ether.h>
+
+#include <vax/mbus/mbusreg.h>
+#include <vax/mbus/mbusvar.h>
+#include <vax/mbus/fwioreg.h>
+#include <vax/mbus/fwiovar.h>
+
+#include <dev/ic/am7990reg.h>
+#include <dev/ic/am7990var.h>
+
+struct le_fwio_softc {
+ struct am7990_softc sc_am7990;
+ volatile uint16_t *sc_rap;
+ volatile uint16_t *sc_rdp;
+};
+
+int le_fwio_match(struct device *, void *, void *);
+void le_fwio_attach(struct device *, struct device *, void *);
+
+struct cfattach le_fwio_ca = {
+ sizeof(struct le_fwio_softc), le_fwio_match, le_fwio_attach
+};
+
+int le_fwio_intr(void *);
+uint16_t le_fwio_rdcsr(struct am7990_softc *, uint16_t);
+void le_fwio_wrcsr(struct am7990_softc *, uint16_t, uint16_t);
+void le_fwio_wrcsr_interrupt(struct am7990_softc *, uint16_t, uint16_t);
+
+int
+le_fwio_match(struct device *parent, void *vcf, void *aux)
+{
+ struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;
+
+ return strcmp(faa->faa_dev, le_cd.cd_name) == 0 ? 1 : 0;
+}
+
+void
+le_fwio_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;
+ struct le_fwio_softc *sc = (struct le_fwio_softc *)self;
+ unsigned int vec;
+ uint32_t *esar;
+ int i;
+
+ vec = faa->faa_vecbase + FBIC_DEVIRQ1 * 4;
+ printf(" vec %d", vec);
+
+ /*
+ * Map registers.
+ */
+
+ sc->sc_rdp = (volatile uint16_t *)
+ vax_map_physmem(faa->faa_base + FWIO_LANCE_REG_OFFSET, 1);
+ sc->sc_rap = sc->sc_rdp + 2;
+
+ /*
+ * Register access functions.
+ */
+
+ sc->sc_am7990.sc_rdcsr = le_fwio_rdcsr;
+ sc->sc_am7990.sc_wrcsr = le_fwio_wrcsr;
+
+ /*
+ * Map buffers.
+ */
+
+ sc->sc_am7990.sc_mem =
+ (void *)uvm_km_valloc(kernel_map, FWIO_LANCE_BUF_SIZE);
+ if (sc->sc_am7990.sc_mem == NULL) {
+ vax_unmap_physmem(faa->faa_base + FWIO_LANCE_REG_OFFSET, 1);
+ printf(": can't map buffers\n");
+ return;
+ }
+
+ ioaccess((vaddr_t)sc->sc_am7990.sc_mem, faa->faa_base +
+ FWIO_LANCE_BUF_OFFSET, FWIO_LANCE_BUF_SIZE >> VAX_PGSHIFT);
+
+ sc->sc_am7990.sc_addr = FWIO_LANCE_BUF_OFFSET;
+ sc->sc_am7990.sc_memsize = FWIO_LANCE_BUF_SIZE;
+ sc->sc_am7990.sc_conf3 = 0;
+
+ sc->sc_am7990.sc_copytodesc = am7990_copytobuf_contig;
+ sc->sc_am7990.sc_copyfromdesc = am7990_copyfrombuf_contig;
+ sc->sc_am7990.sc_copytobuf = am7990_copytobuf_contig;
+ sc->sc_am7990.sc_copyfrombuf = am7990_copyfrombuf_contig;
+ sc->sc_am7990.sc_zerobuf = am7990_zerobuf_contig;
+
+ /*
+ * Get the Ethernet address from the Station Address ROM.
+ */
+
+ esar = (uint32_t *)vax_map_physmem(faa->faa_base + FWIO_ESAR_OFFSET, 1);
+ for (i = 0; i < 6; i++)
+ sc->sc_am7990.sc_arpcom.ac_enaddr[i] =
+ (esar[i] & FWIO_ESAR_MASK) >> FWIO_ESAR_SHIFT;
+ vax_unmap_physmem((vaddr_t)esar, 1);
+ bcopy(self->dv_xname, sc->sc_am7990.sc_arpcom.ac_if.if_xname, IFNAMSIZ);
+
+ /*
+ * Register interrupt handler.
+ */
+
+ if (mbus_intr_establish(vec, IPL_NET, le_fwio_intr, sc,
+ self->dv_xname) != 0) {
+ vax_unmap_physmem(faa->faa_base + FWIO_LANCE_REG_OFFSET, 1);
+ uvm_km_free(kernel_map, (vaddr_t)sc->sc_am7990.sc_mem,
+ FWIO_LANCE_BUF_SIZE);
+ printf(": can't establish interrupt\n");
+ return;
+ }
+
+ /*
+ * Complete attachment.
+ */
+
+ am7990_config(&sc->sc_am7990);
+}
+
+int
+le_fwio_intr(void *v)
+{
+ struct le_fwio_softc *lsc = (struct le_fwio_softc *)v;
+ int rc;
+
+ /*
+ * FBIC expects edge interrupts, while the LANCE does level
+ * interrupts. To avoid missing interrupts while servicing,
+ * we disable further device interrupts while servicing.
+ *
+ * However, am7990_intr() will flip the interrupt enable bit
+ * itself; we override wrcsr with a specific version during
+ * servicing, so as not to reenable interrupts accidentally...
+ */
+ lsc->sc_am7990.sc_wrcsr = le_fwio_wrcsr_interrupt;
+
+ rc = am7990_intr(v);
+
+ lsc->sc_am7990.sc_wrcsr = le_fwio_wrcsr;
+ /*
+ * ...but we should not forget to reenable interrupts at this point!
+ */
+ le_fwio_wrcsr(&lsc->sc_am7990, LE_CSR0, LE_C0_INEA |
+ le_fwio_rdcsr(&lsc->sc_am7990, LE_CSR0));
+
+ return rc;
+}
+
+uint16_t
+le_fwio_rdcsr(struct am7990_softc *sc, uint16_t port)
+{
+ struct le_fwio_softc *lsc = (struct le_fwio_softc *)sc;
+
+ *lsc->sc_rap = port;
+ return *lsc->sc_rdp;
+}
+
+void
+le_fwio_wrcsr(struct am7990_softc *sc, uint16_t port, uint16_t val)
+{
+ struct le_fwio_softc *lsc = (struct le_fwio_softc *)sc;
+
+ *lsc->sc_rap = port;
+ *lsc->sc_rdp = val;
+}
+
+void
+le_fwio_wrcsr_interrupt(struct am7990_softc *sc, uint16_t port, uint16_t val)
+{
+ if (port == LE_CSR0)
+ val &= ~LE_C0_INEA;
+
+ le_fwio_wrcsr(sc, port, val);
+}
diff --git a/sys/arch/vax/mbus/mbus.c b/sys/arch/vax/mbus/mbus.c
new file mode 100644
index 00000000000..a9fc92145fb
--- /dev/null
+++ b/sys/arch/vax/mbus/mbus.c
@@ -0,0 +1,441 @@
+/* $OpenBSD: mbus.c,v 1.1 2008/08/18 23:19:25 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+#include <machine/nexus.h>
+#include <machine/scb.h>
+
+#include <vax/mbus/mbusreg.h>
+#include <vax/mbus/mbusvar.h>
+
+#define PR_CPUID 14
+
+/*
+ * FBIC interrupt handlers
+ */
+struct fbic_irq {
+ int (*fi_fn)(void *);
+ void *fi_arg;
+ struct evcount fi_cnt;
+ int fi_ipl;
+};
+
+/*
+ * Generic information for each slot.
+ *
+ * This information is maintained at the mbus level, rather than
+ * enforcing each child driver to provide it. This allows proper
+ * M-bus configuration on slots where no driver attaches.
+ */
+
+struct fbic {
+ paddr_t base;
+ vaddr_t regs;
+ int vecbase;
+ struct fbic_irq *firq[FBIC_DEVIRQMAX];
+};
+
+struct mbus_slot {
+ uint8_t ms_interface; /* MODTYPE interface */
+ uint8_t ms_class; /* MODTYPE class */
+
+ unsigned int ms_nfbic;
+ struct fbic ms_fbic[2];
+};
+
+struct mbus_softc {
+ struct device sc_dev;
+ struct mbus_slot *sc_slots[MBUS_SLOT_MAX];
+};
+
+void mbus_attach(struct device *, struct device *, void *);
+int mbus_match(struct device *, void *, void *);
+
+struct cfdriver mbus_cd = {
+ NULL, "mbus", DV_DULL
+};
+
+const struct cfattach mbus_ca = {
+ sizeof(struct mbus_softc), mbus_match, mbus_attach
+};
+
+void mbus_initialize_cpu(struct mbus_slot *, unsigned int, int);
+void mbus_initialize_device(struct mbus_slot *, unsigned int, uint8_t);
+void mbus_intr_dispatch(void *);
+int mbus_print(void *, const char *);
+int mbus_submatch(struct device *, void *, void *);
+
+unsigned int mbus_ioslot = (unsigned int)-1;
+
+int
+mbus_match(struct device *parent, void *vcf, void *aux)
+{
+ struct mainbus_attach_args *maa = (struct mainbus_attach_args *)aux;
+
+ return maa->maa_bustype == VAX_MBUS ? 1 : 0;
+}
+
+void
+mbus_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct mbus_softc *sc = (struct mbus_softc *)self;
+ struct mbus_slot *ms;
+ unsigned int mid;
+ struct mbus_attach_args maa;
+ paddr_t pa;
+ vaddr_t fbic;
+ uint32_t modtype;
+ uint8_t class, interface;
+
+ printf("\n");
+
+ /*
+ * Walk the bus and probe slots.
+ * We will also record information about all occupied slots,
+ * and keep a permanent mapping of their FBIC, as we will end
+ * up needing to play with them often...
+ */
+
+ for (mid = 0; mid < MBUS_SLOT_MAX; mid++) {
+
+ /*
+ * Map main (and often, only) FBIC.
+ */
+
+ pa = MBUS_SLOT_BASE(mid);
+ fbic = vax_map_physmem(pa + FBIC_BASE, 1);
+ if (fbic == NULL)
+ panic("unable to map slot %d registers", mid);
+
+ if (badaddr((caddr_t)(fbic + FBIC_MODTYPE), 4) != 0)
+ modtype = 0;
+ else
+ modtype = *(uint32_t *)(fbic + FBIC_MODTYPE);
+
+ if (modtype == 0 || modtype == 0xffffffff) {
+ vax_unmap_physmem(fbic, 1);
+ continue;
+ }
+
+ /*
+ * The slot is populated. Write things down.
+ */
+
+ ms = (struct mbus_slot *)malloc(sizeof(*ms),
+ M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (ms == NULL)
+ panic("not enough memory to probe M-bus");
+
+ sc->sc_slots[mid] = ms;
+ ms->ms_nfbic = 1; /* only one so far! */
+ ms->ms_fbic[0].base = pa + FBIC_BASE;
+ ms->ms_fbic[0].regs = fbic;
+
+ class = (modtype & MODTYPE_CLASS_MASK) >> MODTYPE_CLASS_SHIFT;
+ interface = (modtype & MODTYPE_INTERFACE_MASK) >>
+ MODTYPE_INTERFACE_SHIFT;
+
+ ms->ms_interface = interface;
+ ms->ms_class = class;
+
+ /*
+ * If there are two FBICs on this board, map the second one.
+ */
+
+ if (class == CLASS_CPU) {
+ /* the FBIC we mapped is in fact the second one... */
+ ms->ms_fbic[1].base = ms->ms_fbic[0].base;
+ ms->ms_fbic[1].regs = ms->ms_fbic[0].regs;
+ ms->ms_nfbic = 2;
+ fbic = vax_map_physmem(pa + FBIC_CPUA_BASE, 1);
+ if (fbic == NULL)
+ panic("unable to map slot %d registers", mid);
+ ms->ms_fbic[0].base = pa + FBIC_CPUA_BASE;
+ ms->ms_fbic[0].regs = fbic;
+ }
+
+ /*
+ * Perform a minimal sane initialization.
+ */
+
+ if (class == CLASS_CPU) {
+ mbus_initialize_cpu(ms, mid, 0);
+ mbus_initialize_cpu(ms, mid, 1);
+ } else
+ mbus_initialize_device(ms, mid, interface);
+
+ /*
+ * Attach subdevices if possible.
+ */
+
+ maa.maa_mid = mid;
+ maa.maa_class = class;
+ maa.maa_subclass = (modtype & MODTYPE_SUBCLASS_MASK) >>
+ MODTYPE_SUBCLASS_SHIFT;
+ maa.maa_interface = interface;
+ maa.maa_revision = (modtype & MODTYPE_REVISION_MASK) >>
+ MODTYPE_REVISION_SHIFT;
+ maa.maa_addr = pa;
+ maa.maa_vecbase = ms->ms_fbic[0].vecbase;
+
+ (void)config_found_sm(self, &maa, mbus_print, mbus_submatch);
+ }
+}
+
+int
+mbus_print(void *aux, const char *pnp)
+{
+ struct mbus_attach_args *maa = (struct mbus_attach_args *)aux;
+ int rc = UNCONF;
+ const char *descr;
+
+ switch (maa->maa_class) {
+ case CLASS_BA:
+ descr = "Bus Adaptor";
+ break;
+ case CLASS_GRAPHICS:
+ descr = "Graphics";
+ break;
+ case CLASS_IO:
+ descr = "I/O Module";
+ break;
+ case CLASS_CPU:
+ descr = "cpu";
+ break;
+ case CLASS_MEMORY:
+ descr = maa->maa_interface == INTERFACE_FMDC ?
+ "ECC memory" : "Memory";
+ break;
+ default:
+ rc = UNSUPP;
+ break;
+ }
+
+ if (maa->maa_interface != INTERFACE_FBIC) {
+ if (maa->maa_class != CLASS_MEMORY ||
+ (maa->maa_interface != INTERFACE_FMCM &&
+ maa->maa_interface != INTERFACE_FMDC))
+ rc = UNSUPP;
+ }
+
+ if (pnp != NULL) {
+ if (rc == UNSUPP) {
+ printf("logic board class %02x:%02x interface %u.%u ",
+ maa->maa_class, maa->maa_subclass,
+ maa->maa_interface, maa->maa_revision);
+ if (descr != NULL)
+ printf("(%s)", descr);
+ } else
+ printf("%s", descr);
+ printf(" at %s", pnp);
+ }
+ printf(" mid %u", maa->maa_mid);
+
+ return (rc);
+}
+
+int
+mbus_submatch(struct device *parent, void *vcf, void *aux)
+{
+ struct mbus_attach_args *maa = (struct mbus_attach_args *)aux;
+ struct cfdata *cf = (struct cfdata *)vcf;
+
+ /*
+ * If attachment specifies the mid, it has to match.
+ */
+ if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != maa->maa_mid)
+ return 0;
+
+ return (*cf->cf_attach->ca_match)(parent, vcf, aux);
+}
+
+/*
+ * CPU board initialization.
+ */
+
+void
+mbus_initialize_cpu(struct mbus_slot *ms, unsigned int mid, int cpu)
+{
+ struct fbic *fbic = &ms->ms_fbic[cpu];
+ uint32_t fbicsr;
+ int cpuid;
+
+ cpuid = (mid << CPUID_MID_SHIFT) |
+ (cpu != 0 ? CPUID_PROC_1 : CPUID_PROC_0);
+
+ /*
+ * Clear error log
+ */
+ *(uint32_t *)(fbic->regs + FBIC_BUSCSR) = BUSCSR_RESET;
+
+ /*
+ * Set (IPI) interrupt vectors base, but do not enable them yet.
+ */
+ fbic->vecbase = MBUS_VECTOR_BASE(mid, cpu);
+ *(uint32_t *)(fbic->regs + FBIC_IPDVINT) = 0 /* IPDVINT_IPUNIT */ |
+ (fbic->vecbase & IPDVINT_VECTOR_MASK);
+
+ /*
+ * Enable all interrupt sources if on the boot processor,
+ * disable them otherwise (this does not affect IPIs).
+ */
+ fbicsr = *(uint32_t *)(fbic->regs + FBIC_BUSCSR);
+ if (cpuid == mfpr(PR_CPUID))
+ fbicsr |= FBICSR_IRQEN_MASK;
+ else
+ fbicsr &= ~FBICSR_IRQEN_MASK;
+
+ /*
+ * Route interrupts from the M-bus to the CVAX.
+ */
+ fbicsr &= ~FBICSR_IRQC2M_MASK;
+
+ /*
+ * Allow the CPU to be halted.
+ */
+ fbicsr |= FBICSR_HALTEN;
+
+ *(uint32_t *)(fbic->regs + FBIC_BUSCSR) = fbicsr;
+}
+
+/*
+ * Device board initialization.
+ */
+
+void
+mbus_initialize_device(struct mbus_slot *ms, unsigned int mid,
+ uint8_t interface)
+{
+ struct fbic *fbic = ms->ms_fbic;
+ uint32_t fbicsr;
+
+ /*
+ * Clear error log if applicable
+ */
+ if (interface == INTERFACE_FBIC || interface == INTERFACE_FMDC)
+ *(uint32_t *)(fbic->regs + FBIC_BUSCSR) = BUSCSR_RESET;
+
+ if (interface == INTERFACE_FBIC) {
+ /*
+ * Set interrupt vector base.
+ */
+ fbic->vecbase = MBUS_VECTOR_BASE(mid, 0);
+ *(uint32_t *)(fbic->regs + FBIC_IPDVINT) = IPDVINT_DEVICE |
+ (fbic->vecbase & IPDVINT_VECTOR_MASK);
+
+ /*
+ * Disable all interrupt sources, and route them
+ * from the devices to the M-bus.
+ */
+ fbicsr = *(uint32_t *)(fbic->regs + FBIC_BUSCSR);
+ fbicsr &= ~FBICSR_IRQEN_MASK;
+ fbicsr |= FBICSR_IRQC2M_MASK;
+ *(uint32_t *)(fbic->regs + FBIC_BUSCSR) = fbicsr;
+ }
+}
+
+/*
+ * Interrupt handling.
+ */
+
+int
+mbus_intr_establish(unsigned int vec, int ipl, int (*fn)(void *), void *arg,
+ const char *name)
+{
+ struct mbus_softc *sc;
+ struct mbus_slot *ms;
+ struct fbic *fbic;
+ struct fbic_irq *fi;
+ uint32_t fbicsr;
+ unsigned int mid, fbicirq;
+
+ mid = MBUS_VECTOR_TO_MID(vec);
+
+#ifdef DIAGNOSTIC
+ if (mid >= MBUS_SLOT_MAX)
+ return EINVAL;
+ if (mbus_cd.cd_ndevs == 0)
+ return ENXIO;
+#endif
+ sc = (struct mbus_softc *)mbus_cd.cd_devs[0];
+#ifdef DIAGNOSTIC
+ if (sc == NULL)
+ return ENXIO;
+#endif
+ ms = sc->sc_slots[mid];
+#ifdef DIAGNOSTIC
+ if (ms == NULL)
+ return ENXIO;
+#endif
+ fi = (struct fbic_irq *)malloc(sizeof *fi, M_DEVBUF, M_NOWAIT);
+ if (fi == NULL)
+ return ENOMEM;
+
+ /*
+ * This interface is intended to be used for device interrupts
+ * only, so there is no need to handle dual-FBIC slots.
+ */
+ fbic = &ms->ms_fbic[0 /* MBUS_VECTOR_TO_FBIC(vec) */];
+
+ fi->fi_fn = fn;
+ fi->fi_arg = arg;
+ fi->fi_ipl = ipl;
+ evcount_attach(&fi->fi_cnt, name, &fi->fi_ipl, &evcount_intr);
+
+ fbicirq = MBUS_VECTOR_TO_IRQ(vec);
+ fbic->firq[fbicirq] = fi;
+ scb_vecalloc(vec, mbus_intr_dispatch, fi, SCB_ISTACK, &fi->fi_cnt);
+
+ /*
+ * Enable device interrupt in the module FBIC. Proper direction
+ * has been setup in mbus_slot_initialize().
+ */
+
+ fbicsr = *(uint32_t *)(fbic->regs + FBIC_BUSCSR);
+ fbicsr |= fbicirq << FBICSR_IRQEN_SHIFT;
+ *(uint32_t *)(fbic + FBIC_BUSCSR) = fbicsr;
+
+ return 0;
+}
+
+/*
+ * Interrupt dispatcher.
+ */
+
+void
+mbus_intr_dispatch(void *v)
+{
+ struct fbic_irq *fi = (struct fbic_irq *)v;
+ int s;
+
+ /*
+ * FBIC interrupts are at fixed levels. In case the level is
+ * below the level the driver expects the interrupt at, we need
+ * to raise spl to be safe (e.g. for sii).
+ */
+ s = _splraise(fi->fi_ipl);
+ (void)(*fi->fi_fn)(fi->fi_arg);
+ splx(s);
+}
diff --git a/sys/arch/vax/mbus/mbusreg.h b/sys/arch/vax/mbus/mbusreg.h
new file mode 100644
index 00000000000..cea06e6041e
--- /dev/null
+++ b/sys/arch/vax/mbus/mbusreg.h
@@ -0,0 +1,251 @@
+/* $OpenBSD: mbusreg.h,v 1.1 2008/08/18 23:19:25 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * M-bus
+ *
+ * The M-bus connects up to 8 slots, of 32MB memory space each.
+ *
+ * All these modules contain a ``Firefox Bus Interface Chip'' (FBIC),
+ * which provides common registers at the end of each slot address space,
+ * allowing modules to recognize and configure each other.
+ */
+
+#define MBUS_SLOT_MAX 8
+
+/*
+ * Addressing
+ *
+ * The M-bus provides a 32-bit address space.
+ *
+ * The low half (bit 31 clear) is the physical memory space (and being on
+ * vax, really stops at 512MB).
+ * The high half is the I/O space, where each slot has a 32MB window.
+ * In addition to its window, there are two 128MB areas, allowing a given
+ * module to provide functionnality regardless of its actual position on
+ * the bus.
+ *
+ * From the host CPU, the M-bus I/O space is remapped in the vax I/O space.
+ *
+ * The address map is thus:
+ * M-bus address CPU address Length
+ * 0000.0000 0000.0000 2000.0000 memory space
+ * 8000.0000 2000.0000 0800.0000 global I/O
+ * 8800.0000 2800.0000 0800.0000 local I/O
+ * 9000.0000 3000.0000 0200.0000 slot 0 I/O
+ * 9200.0000 3200.0000 0200.0000 slot 1 I/O
+ * 9400.0000 3400.0000 0200.0000 slot 2 I/O
+ * 9600.0000 3600.0000 0200.0000 slot 3 I/O
+ * 9800.0000 3800.0000 0200.0000 slot 4 I/O
+ * 9a00.0000 3a00.0000 0200.0000 slot 5 I/O
+ * 9c00.0000 3c00.0000 0200.0000 slot 6 I/O
+ * 9e00.0000 3e00.0000 0200.0000 slot 7 I/O
+ */
+
+/* base address of a slot, as seen from the cpu */
+#define MBUS_SLOT_BASE(s) (0x30000000 + ((s) << 25))
+
+/* convert I/O space addresses (assumed to be in their correct range) */
+#define HOST_TO_MBUS(pa) ((pa) ^ 0xa0000000)
+#define MBUS_TO_HOST(pa) ((pa) ^ 0xa0000000)
+
+/*
+ * Common FBIC slot registers
+ */
+
+/* FBIC or compatible registers occupy the last page (running down)... */
+#define FBIC_BASE 0x1fffe00
+/* ...but dual-CPU modules have two of them. */
+#define FBIC_CPUA_BASE 0x0fffe00
+#define FBIC_CPUB_BASE 0x1fffe00
+
+/* module identification */
+#define FBIC_MODTYPE 0x1fc
+/* M-bus error status */
+#define FBIC_BUSCSR 0x1f8
+/* M-bus error control signal log */
+#define FBIC_BUSCTL 0x1f4
+/* M-bus error address signal log */
+#define FBIC_BUSADR 0x1f0
+/* M-bus error data signal log */
+#define FBIC_BUSDAT 0x1ec
+/* FBIC control and status */
+#define FBIC_CSR 0x1e8
+/* I/O space range decode */
+#define FBIC_RANGE 0x1e4
+/* Interprocessor and device interrupt */
+#define FBIC_IPDVINT 0x1e0
+/* Unique software ID */
+#define FBIC_WHAMI 0x1dc
+/* Unique hardware ID */
+#define FBIC_CPUID 0x1d8
+/* Interlock 1 address */
+#define FBIC_IADR1 0x1d4
+/* Interlock 2 address */
+#define FBIC_IADR2 0x1d0
+/* Console scratch register */
+#define FBIC_SAVGPR 0x1c4
+
+/*
+ * Module identification
+ */
+#define MODTYPE_CLASS_MASK 0x000000ff
+#define MODTYPE_CLASS_SHIFT 0
+#define CLASS_BA 0x01
+#define CLASS_GRAPHICS 0x02
+#define CLASS_IO 0x04
+#define CLASS_CPU 0x08
+#define CLASS_MEMORY 0x10
+#define MODTYPE_SUBCLASS_MASK 0x0000ff00
+#define MODTYPE_SUBCLASS_SHIFT 8
+#define MODTYPE_INTERFACE_MASK 0x00ff0000
+#define MODTYPE_INTERFACE_SHIFT 16
+#define INTERFACE_FBIC 0x01
+#define INTERFACE_FMDC 0x02 /* ECC memory */
+#define INTERFACE_FMCM 0xfe /* 8MB board */
+#define MODTYPE_REVISION_MASK 0xff000000
+#define MODTYPE_REVISION_SHIFT 24
+
+/*
+ * M-bus error status and error logging
+ * Conditions are active low
+ */
+#define BUSCSR_FRZN 0x80000000 /* logging frozen */
+#define BUSCSR_ARB 0x40000000 /* arbitration error */
+#define BUSCSR_ICMD 0x20000000 /* invalid MCMD encoding */
+#define BUSCSR_IDAT 0x10000000 /* invalid data supplied */
+#define BUSCSR_MTPE 0x08000000 /* tag parity error */
+#define BUSCSR_MDPE 0x04000000 /* MDAL parity error */
+#define BUSCSR_MSPE 0x02000000 /* MSTATUS parity error */
+#define BUSCSR_MCPE 0x01000000 /* MCMD parity error */
+#define BUSCSR_ILCK 0x00800000 /* interlock violation */
+#define BUSCSR_MTO 0x00400000 /* slave timeout */
+#define BUSCSR_NOS 0x00200000 /* no slave response */
+#define BUSCSR_CTO 0x00100000 /* CDAL data cycle timeout */
+#define BUSCSR_CDPE 0x00080000 /* CDAL parity error */
+#define BUSCSR_CTPE 0x00040000 /* CDAL tag parity error */
+#define BUSCSR_SERR 0x00020000 /* error on MSTATUS */
+#define BUSCSR_DBLE 0x00010000 /* double M-bus error */
+
+#define BUSCSR_RESET 0xffff0000 /* reset all conditions */
+
+/*
+ * FBIC control and status
+ */
+#define FBICSR_MFMD_MASK 0xc0000000 /* manufacturing mode */
+#define FBICSR_CMISS 0x08000000 /* CVAX cache miss */
+#define FBICSR_EXCAEN 0x04000000 /* external cache enable */
+#define FBICSR_HALTCPU 0x02000000 /* CVAX halt */
+#define FBICSR_RESET 0x01000000 /* CVAX reset */
+#define FBICSR_IRQEN_MASK 0x00f00000 /* interrupt enables */
+#define FBICSR_IRQEN_SHIFT 20
+#define FBIC_DEVIRQ0 0
+#define FBIC_DEVIRQ1 1
+#define FBIC_DEVIRQ2 2
+#define FBIC_DEVIRQ3 3
+#define FBIC_DEVIRQMAX 4
+#define FBICSR_IRQC2M_MASK 0x000f0000 /* interrupt direction */
+#define FBICSR_IRQC2M_SHIFT 16
+#define FBICSR_LEDS_MASK 0x00003f00 /* module leds, active low */
+#define FBICSR_LEDS_SHIFT 8
+#define FBICSR_HALTEN 0x00000080 /* halt enable */
+#define FBICSR_TSTFNC_MASK 0x0000007e /* test function */
+#define FBICSR_TSTFNC_SHIFT 1
+#define TSTFNC_NORMAL_MODE 0x1f /* normal operation */
+#define FBICSR_CDPE 0x00000001 /* CVAX parity enable */
+
+/*
+ * I/O Range
+ *
+ * This programs an M-bus address range which in the global I/O space, which
+ * is answered by this module. Note that the upper bit in the match field
+ * must be set, for the address to be in the I/O space; this is why the
+ * upper bit of the mask field acts as an enable.
+ */
+#define RANGE_MATCH 0xffff0000 /* address bits 31:16 */
+#define RANGE_ENABLE 0x00008000 /* mask address bit 31 */
+#define RANGE_MASK 0x00007fff /* address bits 30:16 */
+
+/*
+ * Interprocessor and device interrupts
+ */
+#define IPDVINT_IPL17 0x08000000 /* trigger IRQ3 */
+#define IPDVINT_IPL16 0x04000000 /* trigger IRQ2 */
+#define IPDVINT_IPL15 0x02000000 /* trigger IRQ1 */
+#define IPDVINT_IPL14 0x01000000 /* trigger IRQ0 */
+#define IPDVINT_IPUNIT 0x00020000 /* interrupts CPU */
+#define IPDVINT_DEVICE 0x00010000 /* interrupts M-bus */
+#define IPDVINT_VECTOR_MASK 0x0000fff0 /* interrupt vector */
+#define IPDVINT_VECTOR_SHIFT 4
+#define IPDVINT_IPL_MASK 0x0000000c /* interrupt ipl */
+#define IPDVINT_IPL_SHIFT 2
+
+/*
+ * CPUID (also EPR 14)
+ */
+#define CPUID_MID_MASK 0x0000001c /* slot mid */
+#define CPUID_MID_SHIFT 2
+#define CPUID_PROC_MASK 0x00000003 /* slot processor id */
+#define CPUID_PROC_SHIFT 0
+#define CPUID_PROC_0 0x00
+#define CPUID_PROC_1 0x03
+
+/*
+ * FMCM registers (not FBIC compatible except for MODTYPE and BUSCSR)
+ */
+
+/* module identification */
+#define FMCM_MODTYPE 0x1fc
+/* M-bus error status */
+/* NOTE: only implements FRZN, ICMD, MDPE, MSPE and MCPE */
+#define FMCM_BUSCSR 0x1f8
+/* FMCM control and status register */
+#define FMCM_FMDCSR 0x1f4
+/* Memory space base address register */
+#define FMCM_BASEADDR 0x1f0
+
+#define FMDCSR_ISOLATE 0x00008000 /* no MABORT on error */
+#define FMDCSR_DIAGNOSTIC_REFRESH_START 0x00004000
+#define FMDCSR_REFRESH_PERIOD_SELECT 0x00002000 /* set: slow (80ns) */
+#define FMDCSR_DISABLE_REFRESH 0x00001000
+
+#define BASEADDR_STARTADDR_MASK 0x7ff00000
+#define BASEADDR_MEMORY_SPACE_ENABLE 0x80000000
+
+/*
+ * Interrupt vector assignments
+ *
+ * Since each FBIC controls four interrupts, and passes the IPI in bits
+ * 3:2 of the vector number, we have to reserve them on 0x10 boundaries.
+ *
+ * Note that this is different from the usual scheme of using bits 5:4
+ * for this purpose.
+ *
+ * CPU boards also use the IPDVINT to have an extra 0x10 range for IPIs.
+ *
+ * To make things simpler, we use a static assignment where the number is
+ * computed from the mid and fbic number (for cpu boards).
+ *
+ * This means the 0x100..0x1fc range is used for M-bus interrupts only.
+ * Q-bus interrupts will use the usual 0x200..0x3fc range.
+ */
+
+#define MBUS_VECTOR_BASE(mid,fbic) (0x100 + (mid) * 0x20 + (fbic) * 0x10)
+#define MBUS_VECTOR_TO_MID(vec) (((vec) - 0x100) >> 5)
+#define MBUS_VECTOR_TO_FBIC(vec) (((vec) & 0x10) >> 4)
+#define MBUS_VECTOR_TO_IRQ(vec) (((vec) & 0xc) >> 2)
diff --git a/sys/arch/vax/mbus/mbusvar.h b/sys/arch/vax/mbus/mbusvar.h
new file mode 100644
index 00000000000..d48fdda3002
--- /dev/null
+++ b/sys/arch/vax/mbus/mbusvar.h
@@ -0,0 +1,33 @@
+/* $OpenBSD: mbusvar.h,v 1.1 2008/08/18 23:19:25 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+struct mbus_attach_args {
+ unsigned int maa_mid;
+ uint8_t maa_class;
+ uint8_t maa_subclass;
+ uint8_t maa_interface;
+ uint8_t maa_revision;
+ paddr_t maa_addr;
+ unsigned int maa_vecbase;
+};
+
+extern unsigned int mbus_ioslot;
+
+int mbus_intr_establish(unsigned int, int, int (*)(void *), void *,
+ const char *);
+uint32_t mbus_ddb_hook(int, uint32_t);
diff --git a/sys/arch/vax/mbus/sii_fwio.c b/sys/arch/vax/mbus/sii_fwio.c
new file mode 100644
index 00000000000..f1d329a2121
--- /dev/null
+++ b/sys/arch/vax/mbus/sii_fwio.c
@@ -0,0 +1,163 @@
+/* $OpenBSD: sii_fwio.c,v 1.1 2008/08/18 23:19:25 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <vax/mbus/mbusreg.h>
+#include <vax/mbus/mbusvar.h>
+#include <vax/mbus/fwioreg.h>
+#include <vax/mbus/fwiovar.h>
+
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+#include <scsi/scsi_message.h>
+
+#include <vax/dec/siireg.h>
+#include <vax/dec/siivar.h>
+
+struct sii_fwio_softc {
+ struct sii_softc sc_dev;
+ u_char *sc_buf;
+};
+
+int sii_fwio_match(struct device *, void *, void *);
+void sii_fwio_attach(struct device *, struct device *, void *);
+
+struct cfattach sii_fwio_ca = {
+ sizeof(struct sii_fwio_softc), sii_fwio_match, sii_fwio_attach
+};
+
+extern struct cfdriver sii_cd;
+
+void sii_fwio_copyfrombuf(void *, u_int, u_char *, int);
+void sii_fwio_copytobuf(void *, u_char *, u_int, int);
+int sii_fwio_intr(void *);
+
+int
+sii_fwio_match(struct device *parent, void *vcf, void *aux)
+{
+ struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;
+
+ return strcmp(faa->faa_dev, sii_cd.cd_name) == 0 ? 1 : 0;
+}
+
+void
+sii_fwio_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;
+ struct sii_fwio_softc *sfc = (struct sii_fwio_softc *)self;
+ struct sii_softc *sc = &sfc->sc_dev;
+ unsigned int vec;
+
+ vec = faa->faa_vecbase + FBIC_DEVIRQ0 * 4;
+ printf(" vec %d", vec);
+
+ /*
+ * Map registers.
+ */
+
+ sc->sc_regs =
+ (SIIRegs *)vax_map_physmem(faa->faa_base + FWIO_SII_REG_OFFSET, 1);
+
+ /*
+ * Map buffers.
+ */
+
+ sfc->sc_buf = (u_char *)uvm_km_valloc(kernel_map, FWIO_SII_BUF_SIZE);
+ if (sfc->sc_buf == NULL) {
+ vax_unmap_physmem(faa->faa_base + FWIO_SII_REG_OFFSET, 1);
+ printf(": can't map buffers\n");
+ return;
+ }
+
+ ioaccess((vaddr_t)sfc->sc_buf, faa->faa_base + FWIO_SII_BUF_OFFSET,
+ FWIO_SII_BUF_SIZE >> VAX_PGSHIFT);
+
+ sc->sii_copytobuf = sii_fwio_copytobuf;
+ sc->sii_copyfrombuf = sii_fwio_copyfrombuf;
+
+ /*
+ * Register interrupt handler.
+ */
+
+ if (mbus_intr_establish(vec, IPL_BIO, sii_fwio_intr, sfc,
+ self->dv_xname) != 0) {
+ vax_unmap_physmem(faa->faa_base + FWIO_SII_REG_OFFSET, 1);
+ uvm_km_free(kernel_map, (vaddr_t)sfc->sc_buf,
+ FWIO_SII_BUF_SIZE);
+ printf(": can't establish interrupt\n");
+ return;
+ }
+
+ /*
+ * Complete attachment.
+ */
+ sc->sc_hostid = 7; /* hardcoded */
+ sii_attach(sc);
+}
+
+int
+sii_fwio_intr(void *v)
+{
+ struct sii_softc *sc = (struct sii_softc *)v;
+ int rc;
+ uint16_t csr;
+
+ /*
+ * FBIC expects edge interrupts, while the sii does level
+ * interrupts. To avoid missing interrupts while servicing,
+ * we disable further device interrupts while servicing.
+ */
+ csr = sc->sc_regs->csr;
+ sc->sc_regs->csr = csr & ~SII_IE;
+
+ rc = sii_intr(v);
+
+ sc->sc_regs->csr = csr;
+
+ return rc;
+}
+
+/*
+ * Copy data between the fixed SCSI buffers. The sii driver only ``knows''
+ * offsets inside the SCSI buffer.
+ */
+
+void
+sii_fwio_copyfrombuf(void *v, u_int offs, u_char *dst, int len)
+{
+ struct sii_fwio_softc *sc = (struct sii_fwio_softc *)v;
+ u_char *src = sc->sc_buf + offs;
+
+ memcpy(dst, src, len);
+}
+
+void
+sii_fwio_copytobuf(void *v, u_char *src, u_int offs, int len)
+{
+ struct sii_fwio_softc *sc = (struct sii_fwio_softc *)v;
+ u_char *dst = sc->sc_buf + offs;
+
+ memcpy(dst, src, len);
+}
diff --git a/sys/arch/vax/mbus/uba_mbus.c b/sys/arch/vax/mbus/uba_mbus.c
new file mode 100644
index 00000000000..ed78ffdcf2b
--- /dev/null
+++ b/sys/arch/vax/mbus/uba_mbus.c
@@ -0,0 +1,174 @@
+/* $OpenBSD: uba_mbus.c,v 1.1 2008/08/18 23:19:25 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Copyright (c) 1996 Jonathan Stone.
+ * Copyright (c) 1994, 1996 Ludd, University of Lule}, Sweden.
+ * Copyright (c) 1982, 1986 The Regents of the University of California.
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)uba.c 7.10 (Berkeley) 12/16/90
+ * @(#)autoconf.c 7.20 (Berkeley) 5/9/91
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/mtpr.h>
+#include <machine/sgmap.h>
+
+#include <vax/mbus/mbusreg.h>
+#include <vax/mbus/mbusvar.h>
+
+#include <arch/vax/qbus/ubavar.h>
+#include <arch/vax/uba/uba_common.h>
+#include <arch/vax/uba/ubareg.h>
+
+#define QBASIZE (8192 * VAX_NBPG)
+
+void uba_mbus_attach(struct device *, struct device *, void *);
+int uba_mbus_match(struct device *, void *, void *);
+
+const struct cfattach uba_mbus_ca = {
+ sizeof(struct uba_vsoftc), uba_mbus_match, uba_mbus_attach
+};
+
+void uba_mbus_beforescan(struct uba_softc*);
+void uba_mbus_init(struct uba_softc*);
+
+extern struct vax_bus_space vax_mem_bus_space;
+
+int
+uba_mbus_match(struct device *parent, void *vcf, void *aux)
+{
+ struct mbus_attach_args *maa = (struct mbus_attach_args *)aux;
+
+ /*
+ * There can only be one QBus adapter (because it uses range-mapped
+ * MBus I/O), and it has to be in slot zero for connectivity reasons.
+ */
+ if (maa->maa_mid != 0)
+ return 0;
+
+ if (maa->maa_class == CLASS_BA && maa->maa_interface == INTERFACE_FBIC)
+ return 1;
+
+ return 0;
+}
+
+void
+uba_mbus_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct mbus_attach_args *maa = (struct mbus_attach_args *)aux;
+ struct uba_vsoftc *sc = (void *)self;
+ paddr_t modaddr;
+ vaddr_t fbic;
+
+ printf(": Q22\n");
+
+ /*
+ * Configure M-Bus I/O range.
+ *
+ * This will map the sgmap at 2008xxxx (QBAMAP), and the doorbell
+ * registers at 2000xxxx (QIOPAGE).
+ */
+ modaddr = MBUS_SLOT_BASE(maa->maa_mid);
+ fbic = vax_map_physmem(modaddr + FBIC_BASE, 1);
+ if (fbic == NULL) {
+ printf("%s: can't setup M-bus range register\n");
+ return;
+ }
+ *(uint32_t *)(fbic + FBIC_RANGE) =
+ (HOST_TO_MBUS(QBAMAP & RANGE_MATCH)) | RANGE_ENABLE |
+ ((QBAMAP ^ QIOPAGE) >> 16);
+ vax_unmap_physmem(fbic, 1);
+
+ /*
+ * There is nothing special to do to enable interrupt routing;
+ * the CQBIC will route Q-bus interrupts to the C-bus, and
+ * mbus(4) has already configured our FBIC interrupt registers
+ * to route C-bus interrupts to the M-bus (whether they are
+ * generated by the FBIC or by the Q-bus), which will make them
+ * visible to the processor.
+ *
+ * Note that we do not enable the boards' FBIC memory error
+ * interrupt yet.
+ */
+
+ /*
+ * Fill in bus specific data.
+ */
+ sc->uv_sc.uh_beforescan = uba_mbus_beforescan;
+ sc->uv_sc.uh_ubainit = uba_mbus_init;
+ sc->uv_sc.uh_iot = &vax_mem_bus_space;
+ sc->uv_sc.uh_dmat = &sc->uv_dmat;
+
+ /*
+ * Fill in variables used by the sgmap system.
+ */
+ sc->uv_size = QBASIZE; /* Size in bytes of Qbus space */
+ sc->uv_addr = QBAMAP; /* Physical address of map registers */
+
+ uba_dma_init(sc);
+ uba_attach(&sc->uv_sc, QIOPAGE);
+}
+
+/*
+ * Called when the CQBIC is set up; to enable DMA access from
+ * Q-bus devices to main memory.
+ */
+void
+uba_mbus_beforescan(sc)
+ struct uba_softc *sc;
+{
+ bus_space_write_2(sc->uh_tag, sc->uh_ioh, QIPCR, Q_LMEAE);
+}
+
+void
+uba_mbus_init(sc)
+ struct uba_softc *sc;
+{
+ DELAY(500000);
+ uba_mbus_beforescan(sc);
+}