diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2008-08-18 23:19:30 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2008-08-18 23:19:30 +0000 |
commit | 87d00f400eaf86a770dc09268649713d4a3d50f4 (patch) | |
tree | 9303df1e5e118503c8e8801c63811ceb1e56e53a /sys/arch/vax/mbus | |
parent | fdbef39f25299be7dfee8fd1e022a3c078802917 (diff) |
Add support for the ``Firefox'' VAXstation 3520/3540/3820/3840 workstations,
currently limited to serial console and a single processor working.
All ``on-board'' devices, including the Q-bus adapter, but except for
the frame buffer, are supported. The machine will boot over the network
or from SCSI devices.
Lots of thanks to Al Kossow for www.bitsavers.org, on which I found the
technical documentation allowing me to complete this port (which was
lacking at the time I got that machine...).
Diffstat (limited to 'sys/arch/vax/mbus')
-rw-r--r-- | sys/arch/vax/mbus/dz_fwio.c | 215 | ||||
-rw-r--r-- | sys/arch/vax/mbus/files.mbus | 29 | ||||
-rw-r--r-- | sys/arch/vax/mbus/fwio.c | 111 | ||||
-rw-r--r-- | sys/arch/vax/mbus/fwioreg.h | 45 | ||||
-rw-r--r-- | sys/arch/vax/mbus/fwiovar.h | 28 | ||||
-rw-r--r-- | sys/arch/vax/mbus/if_le_fwio.c | 272 | ||||
-rw-r--r-- | sys/arch/vax/mbus/mbus.c | 441 | ||||
-rw-r--r-- | sys/arch/vax/mbus/mbusreg.h | 251 | ||||
-rw-r--r-- | sys/arch/vax/mbus/mbusvar.h | 33 | ||||
-rw-r--r-- | sys/arch/vax/mbus/sii_fwio.c | 163 | ||||
-rw-r--r-- | sys/arch/vax/mbus/uba_mbus.c | 174 |
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); +} |