diff options
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); +} |