summaryrefslogtreecommitdiff
path: root/sys/arch/alpha/tc/ioasic.c
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2002-05-02 22:56:08 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2002-05-02 22:56:08 +0000
commitf69ff2bae348f49f6e5fccbf1594b839e98792ef (patch)
tree984c07207f03eebcb847988db98df196a848c27e /sys/arch/alpha/tc/ioasic.c
parentd7aff648af7518e317842f78e06a3d197eca9629 (diff)
Big TURBOchannel support catchup from NetBSD, part 1.
A few local changes and tweaks remain. This bring DEC 3000 machines back in the game, but framebuffers are still not supported at the moment. Thanks to ericj@ and nate@ for supplying me a DEC 3000 for testing.
Diffstat (limited to 'sys/arch/alpha/tc/ioasic.c')
-rw-r--r--sys/arch/alpha/tc/ioasic.c262
1 files changed, 125 insertions, 137 deletions
diff --git a/sys/arch/alpha/tc/ioasic.c b/sys/arch/alpha/tc/ioasic.c
index d95660442b6..a66b8eaf010 100644
--- a/sys/arch/alpha/tc/ioasic.c
+++ b/sys/arch/alpha/tc/ioasic.c
@@ -1,5 +1,42 @@
-/* $OpenBSD: ioasic.c,v 1.8 2002/03/14 01:26:28 millert Exp $ */
-/* $NetBSD: ioasic.c,v 1.10 1996/12/05 01:39:41 cgd Exp $ */
+/* $OpenBSD: ioasic.c,v 1.9 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: ioasic.c,v 1.34 2000/07/18 06:10:06 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 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) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -32,33 +69,21 @@
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <sys/malloc.h>
#include <machine/autoconf.h>
+#include <machine/bus.h>
#include <machine/pte.h>
#include <machine/rpb.h>
-#ifndef EVCNT_COUNTERS
#include <machine/intrcnt.h>
-#endif
#include <dev/tc/tcvar.h>
-#include <alpha/tc/ioasicreg.h>
+#include <dev/tc/ioasicreg.h>
#include <dev/tc/ioasicvar.h>
-struct ioasic_softc {
- struct device sc_dv;
-
- tc_addr_t sc_base;
- void *sc_cookie;
-};
-
/* Definition of the driver for autoconfig. */
-#ifdef __BROKEN_INDIRECT_CONFIG
int ioasicmatch(struct device *, void *, void *);
-#else
-int ioasicmatch(struct device *, struct cfdata *, void *);
-#endif
void ioasicattach(struct device *, struct device *, void *);
-int ioasicprint(void *, const char *);
struct cfattach ioasic_ca = {
sizeof(struct ioasic_softc), ioasicmatch, ioasicattach,
@@ -82,24 +107,26 @@ int ioasic_intrnull(void *);
#define IOASIC_NCOOKIES 4
-struct ioasic_dev {
- char *iad_modname;
- tc_offset_t iad_offset;
- void *iad_cookie;
- u_int32_t iad_intrbits;
-} ioasic_devs[] = {
- /* XXX lance name */
- { "lance", 0x000c0000, C(IOASIC_DEV_LANCE), IOASIC_INTR_LANCE, },
- { "z8530 ", 0x00100000, C(IOASIC_DEV_SCC0), IOASIC_INTR_SCC_0, },
- { "z8530 ", 0x00180000, C(IOASIC_DEV_SCC1), IOASIC_INTR_SCC_1, },
- { "TOY_RTC ", 0x00200000, C(IOASIC_DEV_BOGUS), 0, },
- { "AMD79c30", 0x00240000, C(IOASIC_DEV_ISDN), IOASIC_INTR_ISDN, },
+struct ioasic_dev ioasic_devs[] = {
+ { "PMAD-BA ", IOASIC_SLOT_3_START, C(IOASIC_DEV_LANCE),
+ IOASIC_INTR_LANCE, },
+ { "z8530 ", IOASIC_SLOT_4_START, C(IOASIC_DEV_SCC0),
+ IOASIC_INTR_SCC_0, },
+ { "z8530 ", IOASIC_SLOT_6_START, C(IOASIC_DEV_SCC1),
+ IOASIC_INTR_SCC_1, },
+ { "TOY_RTC ", IOASIC_SLOT_8_START, C(IOASIC_DEV_BOGUS),
+ 0, },
+ { "AMD79c30", IOASIC_SLOT_9_START, C(IOASIC_DEV_ISDN),
+ IOASIC_INTR_ISDN_TXLOAD | IOASIC_INTR_ISDN_RXLOAD, },
};
int ioasic_ndevs = sizeof(ioasic_devs) / sizeof(ioasic_devs[0]);
struct ioasicintr {
int (*iai_func)(void *);
void *iai_arg;
+#ifdef EVCNT_COUNTERS
+ struct evcnt iai_evcnt;
+#endif
} ioasicintrs[IOASIC_NCOOKIES];
tc_addr_t ioasic_base; /* XXX XXX XXX */
@@ -107,17 +134,10 @@ tc_addr_t ioasic_base; /* XXX XXX XXX */
/* There can be only one. */
int ioasicfound;
-extern int cputype;
-
int
ioasicmatch(parent, cfdata, aux)
struct device *parent;
-#ifdef __BROKEN_INDIRECT_CONFIG
- void *cfdata;
-#else
- struct cfdata *cfdata;
-#endif
- void *aux;
+ void *cfdata, *aux;
{
struct tc_attach_args *ta = aux;
@@ -142,20 +162,30 @@ ioasicattach(parent, self, aux)
{
struct ioasic_softc *sc = (struct ioasic_softc *)self;
struct tc_attach_args *ta = aux;
- struct ioasicdev_attach_args ioasicdev;
- u_long i;
+#ifdef DEC_3000_300
+ u_long ssr;
+#endif
+ u_long i, imsk;
+ const struct evcnt *pevcnt;
+ char *cp;
ioasicfound = 1;
- sc->sc_base = ta->ta_addr;
- ioasic_base = sc->sc_base; /* XXX XXX XXX */
- sc->sc_cookie = ta->ta_cookie;
+ sc->sc_bst = ta->ta_memt;
+ if (bus_space_map(ta->ta_memt, ta->ta_addr,
+ 0x400000, 0, &sc->sc_bsh)) {
+ printf("%s: unable to map device\n", sc->sc_dv.dv_xname);
+ return;
+ }
+ sc->sc_dmat = ta->ta_dmat;
+
+ ioasic_base = sc->sc_base = ta->ta_addr; /* XXX XXX XXX */
#ifdef DEC_3000_300
if (cputype == ST_DEC_3000_300) {
- *(volatile u_int *)IOASIC_REG_CSR(sc->sc_base) |=
- IOASIC_CSR_FASTMODE;
- tc_mb();
+ ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
+ ssr |= IOASIC_CSR_FASTMODE;
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
printf(": slow mode\n");
} else
#endif
@@ -165,57 +195,34 @@ ioasicattach(parent, self, aux)
* Turn off all device interrupt bits.
* (This does _not_ include 3000/300 TC option slot bits.
*/
+ imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK);
for (i = 0; i < ioasic_ndevs; i++)
- *(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) &=
- ~ioasic_devs[i].iad_intrbits;
- tc_mb();
+ imsk &= ~ioasic_devs[i].iad_intrbits;
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk);
/*
* Set up interrupt handlers.
*/
+ pevcnt = tc_intr_evcnt(parent, ta->ta_cookie);
for (i = 0; i < IOASIC_NCOOKIES; i++) {
ioasicintrs[i].iai_func = ioasic_intrnull;
ioasicintrs[i].iai_arg = (void *)i;
+
+ cp = malloc(12, M_DEVBUF, M_NOWAIT);
+ if (cp == NULL)
+ panic("ioasicattach");
+ sprintf(cp, "slot %lu", i);
+#ifdef EVCNT_COUNTERS
+ evcnt_attach_dynamic(&ioasicintrs[i].iai_evcnt,
+ EVCNT_TYPE_INTR, pevcnt, self->dv_xname, cp);
+#endif
}
- tc_intr_establish(parent, sc->sc_cookie, TC_IPL_NONE, ioasic_intr, sc);
+ tc_intr_establish(parent, ta->ta_cookie, TC_IPL_NONE, ioasic_intr, sc);
- /*
+ /*
* Try to configure each device.
*/
- for (i = 0; i < ioasic_ndevs; i++) {
- strncpy(ioasicdev.iada_modname, ioasic_devs[i].iad_modname,
- TC_ROM_LLEN);
- ioasicdev.iada_modname[TC_ROM_LLEN] = '\0';
- ioasicdev.iada_offset = ioasic_devs[i].iad_offset;
- ioasicdev.iada_addr = sc->sc_base + ioasic_devs[i].iad_offset;
- ioasicdev.iada_cookie = ioasic_devs[i].iad_cookie;
-
- /* Tell the autoconfig machinery we've found the hardware. */
- config_found(self, &ioasicdev, ioasicprint);
- }
-}
-
-int
-ioasicprint(aux, pnp)
- void *aux;
- const char *pnp;
-{
- struct ioasicdev_attach_args *d = aux;
-
- if (pnp)
- printf("%s at %s", d->iada_modname, pnp);
- printf(" offset 0x%lx", (long)d->iada_offset);
- return (UNCONF);
-}
-
-int
-ioasic_submatch(match, d)
- struct cfdata *match;
- struct ioasicdev_attach_args *d;
-{
-
- return ((match->ioasiccf_offset == d->iada_offset) ||
- (match->ioasiccf_offset == IOASIC_OFFSET_UNKNOWN));
+ ioasic_attach_devs(sc, ioasic_devs, ioasic_ndevs);
}
void
@@ -225,7 +232,8 @@ ioasic_intr_establish(ioa, cookie, level, func, arg)
tc_intrlevel_t level;
int (*func)(void *);
{
- u_long dev, i;
+ struct ioasic_softc *sc = (void *)ioasic_cd.cd_devs[0];
+ u_long dev, i, imsk;
dev = (u_long)cookie;
#ifdef DIAGNOSTIC
@@ -233,7 +241,7 @@ ioasic_intr_establish(ioa, cookie, level, func, arg)
#endif
if (ioasicintrs[dev].iai_func != ioasic_intrnull)
- panic("ioasic_intr_establish: cookie %d twice", dev);
+ panic("ioasic_intr_establish: cookie %lu twice", dev);
ioasicintrs[dev].iai_func = func;
ioasicintrs[dev].iai_arg = arg;
@@ -244,9 +252,10 @@ ioasic_intr_establish(ioa, cookie, level, func, arg)
break;
if (i == ioasic_ndevs)
panic("ioasic_intr_establish: invalid cookie.");
- *(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) |=
- ioasic_devs[i].iad_intrbits;
- tc_mb();
+
+ imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK);
+ imsk |= ioasic_devs[i].iad_intrbits;
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk);
}
void
@@ -254,7 +263,8 @@ ioasic_intr_disestablish(ioa, cookie)
struct device *ioa;
void *cookie;
{
- u_long dev, i;
+ struct ioasic_softc *sc = (void *)ioasic_cd.cd_devs[0];
+ u_long dev, i, imsk;
dev = (u_long)cookie;
#ifdef DIAGNOSTIC
@@ -262,7 +272,7 @@ ioasic_intr_disestablish(ioa, cookie)
#endif
if (ioasicintrs[dev].iai_func == ioasic_intrnull)
- panic("ioasic_intr_disestablish: cookie %d missing intr", dev);
+ panic("ioasic_intr_disestablish: cookie %lu missing intr", dev);
/* Enable interrupts for the device. */
for (i = 0; i < ioasic_ndevs; i++)
@@ -270,9 +280,10 @@ ioasic_intr_disestablish(ioa, cookie)
break;
if (i == ioasic_ndevs)
panic("ioasic_intr_disestablish: invalid cookie.");
- *(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) &=
- ~ioasic_devs[i].iad_intrbits;
- tc_mb();
+
+ imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK);
+ imsk &= ~ioasic_devs[i].iad_intrbits;
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk);
ioasicintrs[dev].iai_func = ioasic_intrnull;
ioasicintrs[dev].iai_arg = (void *)dev;
@@ -288,8 +299,7 @@ ioasic_intrnull(val)
}
/*
- * asic_intr --
- * ASIC interrupt handler.
+ * ASIC interrupt handler.
*/
int
ioasic_intr(val)
@@ -298,66 +308,44 @@ ioasic_intr(val)
register struct ioasic_softc *sc = val;
register int ifound;
int gifound;
- u_int32_t sir;
- volatile u_int32_t *sirp;
-
- sirp = (volatile u_int32_t *)IOASIC_REG_INTR(sc->sc_base);
+ u_int32_t sir, osir;
gifound = 0;
do {
ifound = 0;
tc_syncbus();
- sir = *sirp;
+ osir = sir =
+ bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_INTR);
#ifdef EVCNT_COUNTERS
- /* No interrupt counting via evcnt counters */
- XXX BREAK HERE XXX
-#else /* !EVCNT_COUNTERS */
+#define INCRINTRCNT(slot) ioasicintrs[slot].iai_evcnt.ev_count++
+#else
#define INCRINTRCNT(slot) intrcnt[INTRCNT_IOASIC + slot]++
-#endif /* EVCNT_COUNTERS */
+#endif
/* XXX DUPLICATION OF INTERRUPT BIT INFORMATION... */
-#define CHECKINTR(slot, bits) \
- if (sir & bits) { \
+#define CHECKINTR(slot, bits, clear) \
+ if (sir & (bits)) { \
ifound = 1; \
INCRINTRCNT(slot); \
(*ioasicintrs[slot].iai_func) \
(ioasicintrs[slot].iai_arg); \
+ if (clear) \
+ sir &= ~(bits); \
}
- CHECKINTR(IOASIC_DEV_SCC0, IOASIC_INTR_SCC_0);
- CHECKINTR(IOASIC_DEV_SCC1, IOASIC_INTR_SCC_1);
- CHECKINTR(IOASIC_DEV_LANCE, IOASIC_INTR_LANCE);
- CHECKINTR(IOASIC_DEV_ISDN, IOASIC_INTR_ISDN);
+ CHECKINTR(IOASIC_DEV_SCC0, IOASIC_INTR_SCC_0, 0);
+ CHECKINTR(IOASIC_DEV_SCC1, IOASIC_INTR_SCC_1, 0);
+ CHECKINTR(IOASIC_DEV_LANCE, IOASIC_INTR_LANCE, 0);
+ CHECKINTR(IOASIC_DEV_ISDN, IOASIC_INTR_ISDN_TXLOAD |
+ IOASIC_INTR_ISDN_RXLOAD | IOASIC_INTR_ISDN_OVRUN, 1);
+
+ if (sir != osir)
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh,
+ IOASIC_INTR, sir);
gifound |= ifound;
} while (ifound);
return (gifound);
}
-
-/* XXX */
-char *
-ioasic_lance_ether_address()
-{
-
- return (u_char *)IOASIC_SYS_ETHER_ADDRESS(ioasic_base);
-}
-
-void
-ioasic_lance_dma_setup(v)
- void *v;
-{
- volatile u_int32_t *ldp;
- tc_addr_t tca;
-
- tca = (tc_addr_t)v;
-
- ldp = (volatile u_int *)IOASIC_REG_LANCE_DMAPTR(ioasic_base);
- *ldp = ((tca << 3) & ~(tc_addr_t)0x1f) | ((tca >> 29) & 0x1f);
- tc_wmb();
-
- *(volatile u_int32_t *)IOASIC_REG_CSR(ioasic_base) |=
- IOASIC_CSR_DMAEN_LANCE;
- tc_mb();
-}