diff options
author | Hugh Graham <hugh@cvs.openbsd.org> | 2002-06-11 09:36:25 +0000 |
---|---|---|
committer | Hugh Graham <hugh@cvs.openbsd.org> | 2002-06-11 09:36:25 +0000 |
commit | 10ca5e5818bb80e596db244327a2663b6703bb18 (patch) | |
tree | c7ac330b34d73ea4e0c78d17a9eed0a3b6df63aa /sys/arch/vax/bi | |
parent | 180b34af9885b092bee0f67c5b2ac8577d972cfe (diff) |
New boot code, mostly from ragge's work in NetBSD.
Some header syncing and a couple network drivers came along for the ride.
Assembly files have been renamed from .s to .S to facilitate diffs.
Kernel is backwards compat - with manual interaction.
OpenBSD features have been preserved.
Diffstat (limited to 'sys/arch/vax/bi')
-rw-r--r-- | sys/arch/vax/bi/bi.c | 143 | ||||
-rw-r--r-- | sys/arch/vax/bi/bireg.h | 10 | ||||
-rw-r--r-- | sys/arch/vax/bi/bivar.h | 15 | ||||
-rw-r--r-- | sys/arch/vax/bi/if_ni.c | 909 | ||||
-rw-r--r-- | sys/arch/vax/bi/if_nireg.h | 307 | ||||
-rw-r--r-- | sys/arch/vax/bi/kdb.c | 298 | ||||
-rw-r--r-- | sys/arch/vax/bi/kdbreg.h | 4 |
7 files changed, 1476 insertions, 210 deletions
diff --git a/sys/arch/vax/bi/bi.c b/sys/arch/vax/bi/bi.c index 11b69b12087..8c49ceaf503 100644 --- a/sys/arch/vax/bi/bi.c +++ b/sys/arch/vax/bi/bi.c @@ -1,5 +1,5 @@ -/* $OpenBSD: bi.c,v 1.4 2002/03/14 03:16:02 millert Exp $ */ -/* $NetBSD: bi.c,v 1.4 1996/10/13 03:34:44 christos Exp $ */ +/* $OpenBSD: bi.c,v 1.5 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: bi.c,v 1.17 2001/11/13 12:51:34 lukem Exp $ */ /* * Copyright (c) 1996 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -41,44 +41,36 @@ * handle BIbus errors more gracefully. */ +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: bi.c,v 1.17 2001/11/13 12:51:34 lukem Exp $"); + #include <sys/param.h> -#include <sys/device.h> +#include <sys/systm.h> -#include <machine/mtpr.h> -#include <machine/nexus.h> +#include <machine/bus.h> #include <machine/cpu.h> -#include <arch/vax/bi/bireg.h> -#include <arch/vax/bi/bivar.h> - -static int bi_match(struct device *, void *, void *); -static void bi_attach(struct device *, struct device *, void *); -static int bi_print(void *, const char *); +#include <dev/bi/bireg.h> +#include <dev/bi/bivar.h> -struct cfdriver bi_cd = { - NULL, "bi", DV_DULL -}; - -struct cfattach bi_ca = { - sizeof(struct bi_softc), bi_match, bi_attach -}; +static int bi_print __P((void *, const char *)); struct bi_list bi_list[] = { - {BIDT_MS820, 1, "ms820"}, - {BIDT_DRB32, 0, "drb32"}, - {BIDT_DWBUA, 0, "dwbua"}, - {BIDT_KLESI, 0, "klesi"}, - {BIDT_KA820, 1, "ka820"}, - {BIDT_DB88, 0, "db88"}, - {BIDT_CIBCA, 0, "cibca"}, - {BIDT_DMB32, 0, "dmb32"}, - {BIDT_CIBCI, 0, "cibci"}, - {BIDT_KA800, 0, "ka800"}, - {BIDT_KDB50, 0, "kdb50"}, - {BIDT_DWMBA, 0, "dwmba"}, - {BIDT_KFBTA, 0, "kfbta"}, - {BIDT_DEBNK, 0, "debnk"}, - {BIDT_DEBNA, 0, "debna"}, + {BIDT_MS820, DT_HAVDRV, "ms820"}, + {BIDT_DRB32, DT_UNSUPP, "drb32"}, + {BIDT_DWBUA, DT_HAVDRV|DT_ADAPT, "dwbua"}, + {BIDT_KLESI, DT_HAVDRV|DT_ADAPT, "klesi"}, + {BIDT_KA820, DT_HAVDRV, "ka820"}, + {BIDT_DB88, DT_HAVDRV|DT_QUIET, "db88"}, + {BIDT_CIBCA, DT_UNSUPP, "cibca"}, + {BIDT_DMB32, DT_UNSUPP, "dmb32"}, + {BIDT_CIBCI, DT_UNSUPP, "cibci"}, + {BIDT_KA800, DT_UNSUPP, "ka800"}, + {BIDT_KDB50, DT_HAVDRV|DT_VEC, "kdb50"}, + {BIDT_DWMBA, DT_HAVDRV|DT_QUIET, "dwmba"}, + {BIDT_KFBTA, DT_UNSUPP, "kfbta"}, + {BIDT_DEBNK, DT_HAVDRV|DT_VEC, "debnk"}, + {BIDT_DEBNA, DT_HAVDRV|DT_VEC, "debna"}, {0,0,0} }; @@ -89,61 +81,70 @@ bi_print(aux, name) { struct bi_attach_args *ba = aux; struct bi_list *bl; + u_int16_t nr; + + nr = bus_space_read_2(ba->ba_iot, ba->ba_ioh, 0); + for (bl = &bi_list[0]; bl->bl_nr; bl++) + if (bl->bl_nr == nr) + break; if (name) { - for (bl = &bi_list[0]; bl->bl_nr; bl++) - if (bl->bl_nr == ba->ba_node->biic.bi_dtype) { - printf(bl->bl_name); - break; - } if (bl->bl_nr == 0) - printf("unknown device 0x%x", - ba->ba_node->biic.bi_dtype); + printf("unknown device 0x%x", nr); + else + printf(bl->bl_name); printf(" at %s", name); } printf(" node %d", ba->ba_nodenr); - return bl->bl_havedriver ? UNCONF : UNSUPP; -} - -int -bi_match(parent, match, aux) - struct device *parent; - void *match, *aux; -{ - struct bp_conf *bp = aux; - - if (strcmp(bp->type, "bi")) - return 0; - return 1; + if (bl->bl_havedriver & DT_VEC) + printf(" vec %o", ba->ba_ivec & 511); +#ifdef DEBUG + if (bus_space_read_4(ba->ba_iot, ba->ba_ioh, BIREG_SADR) && + bus_space_read_4(ba->ba_iot, ba->ba_ioh, BIREG_EADR)) + printf(" [sadr %x eadr %x]", + bus_space_read_4(ba->ba_iot, ba->ba_ioh, BIREG_SADR), + bus_space_read_4(ba->ba_iot, ba->ba_ioh, BIREG_EADR)); +#endif + if (bl->bl_havedriver & DT_QUIET) + printf("\n"); + return bl->bl_havedriver & DT_QUIET ? QUIET : + bl->bl_havedriver & DT_HAVDRV ? UNCONF : UNSUPP; } void -bi_attach(parent, self, aux) - struct device *parent, *self; - void *aux; +bi_attach(sc) + struct bi_softc *sc; { - struct bp_conf *bp = aux; - struct bi_softc *bi = (void *)self; - struct bi_node *binode; struct bi_attach_args ba; int nodenr; printf("\n"); - binode = bi->bi_base = (struct bi_node *)bp->bp_addr; - ba.ba_intcpu = 1 << mastercpu; + ba.ba_iot = sc->sc_iot; + ba.ba_busnr = sc->sc_busnr; + ba.ba_dmat = sc->sc_dmat; + ba.ba_intcpu = sc->sc_intcpu; + ba.ba_icookie = sc; + /* + * Interrupt numbers. Assign them as described in + * VAX 8800 system maintenance manual; this means like nexus + * adapters have them assigned. + * XXX - must address Unibus adapters. + */ for (nodenr = 0; nodenr < NNODEBI; nodenr++) { - if (badaddr((caddr_t)&binode[nodenr], 4)) + if (bus_space_map(sc->sc_iot, sc->sc_addr + BI_NODE(nodenr), + BI_NODESIZE, 0, &ba.ba_ioh)) { + printf("bi_attach: bus_space_map failed, node %d\n", + nodenr); + return; + } + if (badaddr((caddr_t)ba.ba_ioh, 4) || + (bus_space_read_2(ba.ba_iot, ba.ba_ioh, 0) == 0)) { + bus_space_unmap(ba.ba_iot, ba.ba_ioh, BI_NODESIZE); continue; - - ba.ba_node = &binode[nodenr]; + } ba.ba_nodenr = nodenr; - config_found(self, &ba, bi_print); + ba.ba_ivec = sc->sc_lastiv + 64 + 4 * nodenr; /* all on spl5 */ + config_found(&sc->sc_dev, &ba, bi_print); } } - -void -bi_buserr() -{ - panic("bi_buserr"); -} diff --git a/sys/arch/vax/bi/bireg.h b/sys/arch/vax/bi/bireg.h index edc75f91ab7..6b9a68d00c1 100644 --- a/sys/arch/vax/bi/bireg.h +++ b/sys/arch/vax/bi/bireg.h @@ -1,5 +1,5 @@ -/* $OpenBSD: bireg.h,v 1.3 2000/04/28 03:42:39 bjc Exp $ */ -/* $NetBSD: bireg.h,v 1.6 1999/08/04 19:12:22 ragge Exp $ */ +/* $OpenBSD: bireg.h,v 1.4 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: bireg.h,v 1.7 2000/07/06 17:47:02 ragge Exp $ */ /* * Copyright (c) 1988 Regents of the University of California. * All rights reserved. @@ -45,8 +45,8 @@ /* * BI node addresses */ -#define NODESIZE 0x2000 /* Size of one BI node */ -#define BI_NODE(node) (NODESIZE * (node)) +#define BI_NODESIZE 0x2000 /* Size of one BI node */ +#define BI_NODE(node) (BI_NODESIZE * (node)) #define BI_BASE(bi,nod) ((0x20000000 + (bi) * 0x2000000) + BI_NODE(nod)) #define MAXNBI 16 /* Spec says there can be 16 anyway */ #define NNODEBI 16 /* 16 nodes per BI */ @@ -60,6 +60,7 @@ * * 990712: The structs not used anymore due to conversion to bus.h. */ +#ifdef notdef struct biiregs { u_short bi_dtype; /* device type */ u_short bi_revs; /* revisions */ @@ -101,6 +102,7 @@ struct bi_cpu { u_long bi_xxx[63]; /* pad */ u_long bi_rxcd; /* receive console data register */ }; +#endif #define BIREG_DTYPE 0x00 #define BIREG_VAXBICSR 0x04 diff --git a/sys/arch/vax/bi/bivar.h b/sys/arch/vax/bi/bivar.h index a44ace650fb..ebd21677460 100644 --- a/sys/arch/vax/bi/bivar.h +++ b/sys/arch/vax/bi/bivar.h @@ -1,5 +1,5 @@ -/* $OpenBSD: bivar.h,v 1.5 2002/03/14 03:16:02 millert Exp $ */ -/* $NetBSD: bivar.h,v 1.5 2000/03/26 11:45:04 ragge Exp $ */ +/* $OpenBSD: bivar.h,v 1.6 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: bivar.h,v 1.8 2000/07/26 12:41:40 ragge Exp $ */ /* * Copyright (c) 1996, 1999 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -69,6 +69,13 @@ struct bi_list { char *bl_name; /* DEC name */ }; +/* bl_havedriver field meaning */ +#define DT_UNSUPP 0 /* pseudo define */ +#define DT_HAVDRV 1 /* device have driver */ +#define DT_ADAPT 2 /* is an adapter */ +#define DT_QUIET 4 /* don't complain when not conf'ed */ +#define DT_VEC 8 /* uses a interrupt vector */ + /* Prototype */ -void bi_attach(struct bi_softc *); -void bi_intr_establish(void *, int, void (*)(void *), void *); +void bi_attach (struct bi_softc *); +void bi_intr_establish (void *, int, void (*)(void *), void *, struct evcnt *); diff --git a/sys/arch/vax/bi/if_ni.c b/sys/arch/vax/bi/if_ni.c new file mode 100644 index 00000000000..414d84968b0 --- /dev/null +++ b/sys/arch/vax/bi/if_ni.c @@ -0,0 +1,909 @@ +/* $OpenBSD: if_ni.c,v 1.1 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: if_ni.c,v 1.15 2002/05/22 16:03:14 wiz Exp $ */ +/* + * Copyright (c) 2000 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. + */ + +/* + * Driver for DEBNA/DEBNT/DEBNK ethernet cards. + * Things that is still to do: + * Collect statistics. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: if_ni.c,v 1.15 2002/05/22 16:03:14 wiz Exp $"); + +#include "opt_inet.h" +#include "bpfilter.h" + +#include <sys/param.h> +#include <sys/mbuf.h> +#include <sys/socket.h> +#include <sys/device.h> +#include <sys/systm.h> +#include <sys/sockio.h> +#include <sys/sched.h> + +#include <net/if.h> +#include <net/if_ether.h> +#include <net/if_dl.h> + +#include <netinet/in.h> +#include <netinet/if_inarp.h> + +#if NBPFILTER > 0 +#include <net/bpf.h> +#include <net/bpfdesc.h> +#endif + +#include <machine/bus.h> +#ifdef __vax__ +#include <machine/mtpr.h> +#include <machine/pte.h> +#endif + +#include <dev/bi/bireg.h> +#include <dev/bi/bivar.h> + +#include "ioconf.h" +#include "locators.h" + +/* + * Tunable buffer parameters. Good idea to have them as power of 8; then + * they will fit into a logical VAX page. + */ +#define NMSGBUF 8 /* Message queue entries */ +#define NTXBUF 16 /* Transmit queue entries */ +#define NTXFRAGS 8 /* Number of transmit buffer fragments */ +#define NRXBUF 24 /* Receive queue entries */ +#define NBDESCS (NTXBUF * NTXFRAGS + NRXBUF) +#define NQUEUES 3 /* RX + TX + MSG */ +#define PKTHDR 18 /* Length of (control) packet header */ +#define RXADD 18 /* Additional length of receive datagram */ +#define TXADD (10+NTXFRAGS*8) /* "" transmit "" */ +#define MSGADD 134 /* "" message "" */ + +#include <dev/bi/if_nireg.h> /* XXX include earlier */ + +/* + * Macros for (most cases of) insqti/remqhi. + * Retry NRETRIES times to do the operation, if it still fails assume + * a lost lock and panic. + */ +#define NRETRIES 100 +#define INSQTI(e, h) ({ \ + int ret, i; \ + for (i = 0; i < NRETRIES; i++) { \ + if ((ret = insqti(e, h)) != ILCK_FAILED) \ + break; \ + } \ + if (i == NRETRIES) \ + panic("ni: insqti failed at %d", __LINE__); \ + ret; \ +}) +#define REMQHI(h) ({ \ + int i;void *ret; \ + for (i = 0; i < NRETRIES; i++) { \ + if ((ret = remqhi(h)) != (void *)ILCK_FAILED) \ + break; \ + } \ + if (i == NRETRIES) \ + panic("ni: remqhi failed at %d", __LINE__); \ + ret; \ +}) + + +#define nipqb (&sc->sc_gvppqb->nc_pqb) +#define gvp sc->sc_gvppqb +#define fqb sc->sc_fqb +#define bbd sc->sc_bbd + +struct ni_softc { + struct device sc_dev; /* Configuration common part */ + struct evcnt sc_intrcnt; /* Interrupt coounting */ + struct ethercom sc_ec; /* Ethernet common part */ +#define sc_if sc_ec.ec_if /* network-visible interface */ + bus_space_tag_t sc_iot; + bus_addr_t sc_ioh; + bus_dma_tag_t sc_dmat; + struct ni_gvppqb *sc_gvppqb; /* Port queue block */ + struct ni_gvppqb *sc_pgvppqb; /* Phys address of PQB */ + struct ni_fqb *sc_fqb; /* Free Queue block */ + struct ni_bbd *sc_bbd; /* Buffer descriptors */ + u_int8_t sc_enaddr[ETHER_ADDR_LEN]; +}; + +static int nimatch __P((struct device *, struct cfdata *, void *)); +static void niattach __P((struct device *, struct device *, void *)); +static void niinit __P((struct ni_softc *)); +static void nistart __P((struct ifnet *)); +static void niintr __P((void *)); +static int niioctl __P((struct ifnet *, u_long, caddr_t)); +static int ni_add_rxbuf(struct ni_softc *, struct ni_dg *, int); +static void ni_setup __P((struct ni_softc *)); +static void nitimeout __P((struct ifnet *)); +static void ni_shutdown(void *); +static void ni_getpgs(struct ni_softc *sc, int size, caddr_t *v, paddr_t *p); +static int failtest(struct ni_softc *, int, int, int, char *); + +volatile int endwait, retry; /* Used during autoconfig */ + +struct cfattach ni_ca = { + sizeof(struct ni_softc), nimatch, niattach +}; + +#define NI_WREG(csr, val) \ + bus_space_write_4(sc->sc_iot, sc->sc_ioh, csr, val) +#define NI_RREG(csr) \ + bus_space_read_4(sc->sc_iot, sc->sc_ioh, csr) + +#define WAITREG(csr,val) while (NI_RREG(csr) & val); +/* + * Check for present device. + */ +int +nimatch(parent, cf, aux) + struct device *parent; + struct cfdata *cf; + void *aux; +{ + struct bi_attach_args *ba = aux; + u_short type; + + type = bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE); + if (type != BIDT_DEBNA && type != BIDT_DEBNT && type != BIDT_DEBNK) + return 0; + + if (cf->cf_loc[BICF_NODE] != BICF_NODE_DEFAULT && + cf->cf_loc[BICF_NODE] != ba->ba_nodenr) + return 0; + + return 1; +} + +/* + * Allocate a bunch of descriptor-safe memory. + * We need to get the structures from the beginning of its own pages. + */ +static void +ni_getpgs(struct ni_softc *sc, int size, caddr_t *v, paddr_t *p) +{ + bus_dma_segment_t seg; + int nsegs, error; + + if ((error = bus_dmamem_alloc(sc->sc_dmat, size, NBPG, 0, &seg, 1, + &nsegs, BUS_DMA_NOWAIT)) != 0) + panic(" unable to allocate memory: error %d", error); + + if ((error = bus_dmamem_map(sc->sc_dmat, &seg, nsegs, size, v, + BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) + panic(" unable to map memory: error %d", error); + + if (p) + *p = seg.ds_addr; + memset(*v, 0, size); +} + +static int +failtest(struct ni_softc *sc, int reg, int mask, int test, char *str) +{ + int i = 100; + + do { + DELAY(100000); + } while (((NI_RREG(reg) & mask) != test) && --i); + + if (i == 0) { + printf("%s: %s\n", sc->sc_dev.dv_xname, str); + return 1; + } + return 0; +} + + +/* + * Interface exists: make available by filling in network interface + * record. System will initialize the interface when it is ready + * to accept packets. + */ +void +niattach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct bi_attach_args *ba = aux; + struct ni_softc *sc = (struct ni_softc *)self; + struct ifnet *ifp = (struct ifnet *)&sc->sc_if; + struct ni_msg *msg; + struct ni_ptdb *ptdb; + caddr_t va; + int i, j, s, res; + u_short type; + + type = bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE); + printf(": DEBN%c\n", type == BIDT_DEBNA ? 'A' : type == BIDT_DEBNT ? + 'T' : 'K'); + sc->sc_iot = ba->ba_iot; + sc->sc_ioh = ba->ba_ioh; + sc->sc_dmat = ba->ba_dmat; + + bi_intr_establish(ba->ba_icookie, ba->ba_ivec, + niintr, sc, &sc->sc_intrcnt); + evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL, + sc->sc_dev.dv_xname, "intr"); + + ni_getpgs(sc, sizeof(struct ni_gvppqb), (caddr_t *)&sc->sc_gvppqb, + (paddr_t *)&sc->sc_pgvppqb); + ni_getpgs(sc, sizeof(struct ni_fqb), (caddr_t *)&sc->sc_fqb, 0); + ni_getpgs(sc, NBDESCS * sizeof(struct ni_bbd), + (caddr_t *)&sc->sc_bbd, 0); + /* + * Zero the newly allocated memory. + */ + + nipqb->np_veclvl = (ba->ba_ivec << 2) + 2; + nipqb->np_node = ba->ba_intcpu; + nipqb->np_vpqb = (u_int32_t)gvp; +#ifdef __vax__ + nipqb->np_spt = nipqb->np_gpt = mfpr(PR_SBR); + nipqb->np_sptlen = nipqb->np_gptlen = mfpr(PR_SLR); +#else +#error Must fix support for non-vax. +#endif + nipqb->np_bvplvl = 1; + nipqb->np_vfqb = (u_int32_t)fqb; + nipqb->np_vbdt = (u_int32_t)bbd; + nipqb->np_nbdr = NBDESCS; + + /* Free queue block */ + nipqb->np_freeq = NQUEUES; + fqb->nf_mlen = PKTHDR+MSGADD; + fqb->nf_dlen = PKTHDR+TXADD; + fqb->nf_rlen = PKTHDR+RXADD; + + strcpy(ifp->if_xname, sc->sc_dev.dv_xname); + ifp->if_softc = sc; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_start = nistart; + ifp->if_ioctl = niioctl; + ifp->if_watchdog = nitimeout; + IFQ_SET_READY(&ifp->if_snd); + + /* + * Start init sequence. + */ + + /* Reset the node */ + NI_WREG(BIREG_VAXBICSR, NI_RREG(BIREG_VAXBICSR) | BICSR_NRST); + DELAY(500000); + i = 20; + while ((NI_RREG(BIREG_VAXBICSR) & BICSR_BROKE) && --i) + DELAY(500000); + if (i == 0) { + printf("%s: BROKE bit set after reset\n", sc->sc_dev.dv_xname); + return; + } + + /* Check state */ + if (failtest(sc, NI_PSR, PSR_STATE, PSR_UNDEF, "not undefined state")) + return; + + /* Clear owner bits */ + NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN); + NI_WREG(NI_PCR, NI_RREG(NI_PCR) & ~PCR_OWN); + + /* kick off init */ + NI_WREG(NI_PCR, (u_int32_t)sc->sc_pgvppqb | PCR_INIT | PCR_OWN); + while (NI_RREG(NI_PCR) & PCR_OWN) + DELAY(100000); + + /* Check state */ + if (failtest(sc, NI_PSR, PSR_INITED, PSR_INITED, "failed initialize")) + return; + + NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN); + + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_OWN|PCR_ENABLE); + WAITREG(NI_PCR, PCR_OWN); + WAITREG(NI_PSR, PSR_OWN); + + /* Check state */ + if (failtest(sc, NI_PSR, PSR_STATE, PSR_ENABLED, "failed enable")) + return; + + NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN); + + /* + * The message queue packets must be located on the beginning + * of a page. A VAX page is 512 bytes, but it clusters 8 pages. + * This knowledge is used here when allocating pages. + * !!! How should this be done on MIPS and Alpha??? !!! + */ +#if NBPG < 4096 +#error pagesize too small +#endif + s = splvm(); + /* Set up message free queue */ + ni_getpgs(sc, NMSGBUF * 512, &va, 0); + for (i = 0; i < NMSGBUF; i++) { + struct ni_msg *msg; + + msg = (void *)(va + i * 512); + + res = INSQTI(msg, &fqb->nf_mforw); + } + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + WAITREG(NI_PCR, PCR_OWN); + + /* Set up xmit queue */ + ni_getpgs(sc, NTXBUF * 512, &va, 0); + for (i = 0; i < NTXBUF; i++) { + struct ni_dg *data; + + data = (void *)(va + i * 512); + data->nd_status = 0; + data->nd_len = TXADD; + data->nd_ptdbidx = 1; + data->nd_opcode = BVP_DGRAM; + for (j = 0; j < NTXFRAGS; j++) { + data->bufs[j]._offset = 0; + data->bufs[j]._key = 1; + bbd[i * NTXFRAGS + j].nb_key = 1; + bbd[i * NTXFRAGS + j].nb_status = 0; + data->bufs[j]._index = i * NTXFRAGS + j; + } + res = INSQTI(data, &fqb->nf_dforw); + } + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN); + WAITREG(NI_PCR, PCR_OWN); + + /* recv buffers */ + ni_getpgs(sc, NRXBUF * 512, &va, 0); + for (i = 0; i < NRXBUF; i++) { + struct ni_dg *data; + int idx; + + data = (void *)(va + i * 512); + data->nd_len = RXADD; + data->nd_opcode = BVP_DGRAMRX; + data->nd_ptdbidx = 2; + data->bufs[0]._key = 1; + + idx = NTXBUF * NTXFRAGS + i; + if (ni_add_rxbuf(sc, data, idx)) + panic("niattach: ni_add_rxbuf: out of mbufs"); + + res = INSQTI(data, &fqb->nf_rforw); + } + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_FREEQNE|PCR_RFREEQ|PCR_OWN); + WAITREG(NI_PCR, PCR_OWN); + + splx(s); + + /* Set initial parameters */ + msg = REMQHI(&fqb->nf_mforw); + + msg->nm_opcode = BVP_MSG; + msg->nm_status = 0; + msg->nm_len = sizeof(struct ni_param) + 6; + msg->nm_opcode2 = NI_WPARAM; + ((struct ni_param *)&msg->nm_text[0])->np_flags = NP_PAD; + + endwait = retry = 0; + res = INSQTI(msg, &gvp->nc_forw0); + +retry: WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + WAITREG(NI_PCR, PCR_OWN); + i = 1000; + while (endwait == 0 && --i) + DELAY(10000); + + if (endwait == 0) { + if (++retry < 3) + goto retry; + printf("%s: no response to set params\n", sc->sc_dev.dv_xname); + return; + } + + /* Clear counters */ + msg = REMQHI(&fqb->nf_mforw); + msg->nm_opcode = BVP_MSG; + msg->nm_status = 0; + msg->nm_len = sizeof(struct ni_param) + 6; + msg->nm_opcode2 = NI_RCCNTR; + + res = INSQTI(msg, &gvp->nc_forw0); + + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + WAITREG(NI_PCR, PCR_OWN); + + /* Enable transmit logic */ + msg = REMQHI(&fqb->nf_mforw); + + msg->nm_opcode = BVP_MSG; + msg->nm_status = 0; + msg->nm_len = 18; + msg->nm_opcode2 = NI_STPTDB; + ptdb = (struct ni_ptdb *)&msg->nm_text[0]; + memset(ptdb, 0, sizeof(struct ni_ptdb)); + ptdb->np_index = 1; + ptdb->np_fque = 1; + + res = INSQTI(msg, &gvp->nc_forw0); + + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + WAITREG(NI_PCR, PCR_OWN); + + /* Wait for everything to finish */ + WAITREG(NI_PSR, PSR_OWN); + + printf("%s: hardware address %s\n", sc->sc_dev.dv_xname, + ether_sprintf(sc->sc_enaddr)); + + /* + * Attach the interface. + */ + if_attach(ifp); + ether_ifattach(ifp, sc->sc_enaddr); + if (shutdownhook_establish(ni_shutdown, sc) == 0) + printf("%s: WARNING: unable to establish shutdown hook\n", + sc->sc_dev.dv_xname); +} + +/* + * Initialization of interface. + */ +void +niinit(sc) + struct ni_softc *sc; +{ + struct ifnet *ifp = (struct ifnet *)&sc->sc_if; + + /* + * Set flags (so ni_setup() do the right thing). + */ + ifp->if_flags |= IFF_RUNNING; + ifp->if_flags &= ~IFF_OACTIVE; + + /* + * Send setup messages so that the rx/tx locic starts. + */ + ni_setup(sc); + +} + +/* + * Start output on interface. + */ +void +nistart(ifp) + struct ifnet *ifp; +{ + struct ni_softc *sc = ifp->if_softc; + struct ni_dg *data; + struct ni_bbd *bdp; + struct mbuf *m, *m0; + int i, cnt, res, mlen; + + if (ifp->if_flags & IFF_OACTIVE) + return; +#ifdef DEBUG + if (ifp->if_flags & IFF_DEBUG) + printf("%s: nistart\n", sc->sc_dev.dv_xname); +#endif + + while (fqb->nf_dforw) { + IFQ_POLL(&ifp->if_snd, m); + if (m == 0) + break; + + data = REMQHI(&fqb->nf_dforw); + if ((int)data == Q_EMPTY) { + ifp->if_flags |= IFF_OACTIVE; + break; + } + + IFQ_DEQUEUE(&ifp->if_snd, m); + + /* + * Count number of mbufs in chain. + * Always do DMA directly from mbufs, therefore the transmit + * ring is really big. + */ + for (m0 = m, cnt = 0; m0; m0 = m0->m_next) + if (m0->m_len) + cnt++; + if (cnt > NTXFRAGS) + panic("nistart"); /* XXX */ + +#if NBPFILTER > 0 + if (ifp->if_bpf) + bpf_mtap(ifp->if_bpf, m); +#endif + bdp = &bbd[(data->bufs[0]._index & 0x7fff)]; + for (m0 = m, i = 0, mlen = 0; m0; m0 = m0->m_next) { + if (m0->m_len == 0) + continue; + bdp->nb_status = (mtod(m0, u_int32_t) & NIBD_OFFSET) | + NIBD_VALID; + bdp->nb_pte = (u_int32_t)kvtopte(mtod(m0, void *)); + bdp->nb_len = m0->m_len; + data->bufs[i]._offset = 0; + data->bufs[i]._len = bdp->nb_len; + data->bufs[i]._index |= NIDG_CHAIN; + mlen += bdp->nb_len; + bdp++; + i++; + } + data->nd_opcode = BVP_DGRAM; + data->nd_pad3 = 1; + data->nd_ptdbidx = 1; + data->nd_len = 10 + i * 8; + data->bufs[i - 1]._index &= ~NIDG_CHAIN; + if (mlen < 64) + data->bufs[i - 1]._len = bdp[-1].nb_len += (64 - mlen); + data->nd_cmdref = (u_int32_t)m; +#ifdef DEBUG + if (ifp->if_flags & IFF_DEBUG) + printf("%s: sending %d bytes (%d segments)\n", + sc->sc_dev.dv_xname, mlen, i); +#endif + + res = INSQTI(data, &gvp->nc_forw0); + if (res == Q_EMPTY) { + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + } + } +} + +void +niintr(void *arg) +{ + struct ni_softc *sc = arg; + struct ni_dg *data; + struct ni_msg *msg; + struct ifnet *ifp = &sc->sc_if; + struct ni_bbd *bd; + struct mbuf *m; + int idx, res; + + if ((NI_RREG(NI_PSR) & PSR_STATE) != PSR_ENABLED) + return; + + if ((NI_RREG(NI_PSR) & PSR_ERR)) + printf("%s: PSR %x\n", sc->sc_dev.dv_xname, NI_RREG(NI_PSR)); + + KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE); + /* Got any response packets? */ + while ((NI_RREG(NI_PSR) & PSR_RSQ) && (data = REMQHI(&gvp->nc_forwr))) { + + switch (data->nd_opcode) { + case BVP_DGRAMRX: /* Receive datagram */ + idx = data->bufs[0]._index; + bd = &bbd[idx]; + m = (void *)data->nd_cmdref; + m->m_pkthdr.len = m->m_len = + data->bufs[0]._len - ETHER_CRC_LEN; + m->m_pkthdr.rcvif = ifp; + if (ni_add_rxbuf(sc, data, idx)) { + bd->nb_len = (m->m_ext.ext_size - 2); + bd->nb_pte = + (long)kvtopte(m->m_ext.ext_buf); + bd->nb_status = 2 | NIBD_VALID; + bd->nb_key = 1; + } + data->nd_len = RXADD; + data->nd_status = 0; + res = INSQTI(data, &fqb->nf_rforw); + if (res == Q_EMPTY) { + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_FREEQNE|PCR_RFREEQ|PCR_OWN); + } + if (m == (void *)data->nd_cmdref) + break; /* Out of mbufs */ + +#if NBPFILTER > 0 + if (ifp->if_bpf) + bpf_mtap(ifp->if_bpf, m); +#endif + (*ifp->if_input)(ifp, m); + break; + + case BVP_DGRAM: + m = (struct mbuf *)data->nd_cmdref; + ifp->if_flags &= ~IFF_OACTIVE; + m_freem(m); + res = INSQTI(data, &fqb->nf_dforw); + if (res == Q_EMPTY) { + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN); + } + break; + + case BVP_MSGRX: + msg = (struct ni_msg *)data; + switch (msg->nm_opcode2) { + case NI_WPARAM: + memcpy(sc->sc_enaddr, ((struct ni_param *)&msg->nm_text[0])->np_dpa, ETHER_ADDR_LEN); + endwait = 1; + break; + + case NI_RCCNTR: + case NI_CLPTDB: + case NI_STPTDB: + break; + + default: + printf("Unkn resp %d\n", + msg->nm_opcode2); + break; + } + res = INSQTI(data, &fqb->nf_mforw); + if (res == Q_EMPTY) { + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + } + break; + + default: + printf("Unknown opcode %d\n", data->nd_opcode); + res = INSQTI(data, &fqb->nf_mforw); + if (res == Q_EMPTY) { + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + } + } + } + + /* Try to kick on the start routine again */ + nistart(ifp); + + NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~(PSR_OWN|PSR_RSQ)); + KERNEL_UNLOCK(); +} + +/* + * Process an ioctl request. + */ +int +niioctl(ifp, cmd, data) + register struct ifnet *ifp; + u_long cmd; + caddr_t data; +{ + struct ni_softc *sc = ifp->if_softc; + struct ifreq *ifr = (struct ifreq *)data; + struct ifaddr *ifa = (struct ifaddr *)data; + int s = splnet(), error = 0; + + switch (cmd) { + + case SIOCSIFADDR: + ifp->if_flags |= IFF_UP; + switch(ifa->ifa_addr->sa_family) { +#ifdef INET + case AF_INET: + niinit(sc); + arp_ifinit(ifp, ifa); + break; +#endif + } + break; + + case SIOCSIFFLAGS: + if ((ifp->if_flags & IFF_UP) == 0 && + (ifp->if_flags & IFF_RUNNING) != 0) { + /* + * If interface is marked down and it is running, + * stop it. + */ + ifp->if_flags &= ~IFF_RUNNING; + ni_setup(sc); + } else if ((ifp->if_flags & IFF_UP) != 0 && + (ifp->if_flags & IFF_RUNNING) == 0) { + /* + * If interface it marked up and it is stopped, then + * start it. + */ + niinit(sc); + } else if ((ifp->if_flags & IFF_UP) != 0) { + /* + * Send a new setup packet to match any new changes. + * (Like IFF_PROMISC etc) + */ + ni_setup(sc); + } + break; + + case SIOCADDMULTI: + case SIOCDELMULTI: + /* + * Update our multicast list. + */ + error = (cmd == SIOCADDMULTI) ? + ether_addmulti(ifr, &sc->sc_ec): + ether_delmulti(ifr, &sc->sc_ec); + + if (error == ENETRESET) { + /* + * Multicast list has changed; set the hardware filter + * accordingly. + */ + ni_setup(sc); + error = 0; + } + break; + + default: + error = EINVAL; + + } + splx(s); + return (error); +} + +/* + * Add a receive buffer to the indicated descriptor. + */ +int +ni_add_rxbuf(struct ni_softc *sc, struct ni_dg *data, int idx) +{ + struct ni_bbd *bd = &bbd[idx]; + struct mbuf *m; + + MGETHDR(m, M_DONTWAIT, MT_DATA); + if (m == NULL) + return (ENOBUFS); + + MCLGET(m, M_DONTWAIT); + if ((m->m_flags & M_EXT) == 0) { + m_freem(m); + return (ENOBUFS); + } + + m->m_data += 2; + bd->nb_len = (m->m_ext.ext_size - 2); + bd->nb_pte = (long)kvtopte(m->m_ext.ext_buf); + bd->nb_status = 2 | NIBD_VALID; + bd->nb_key = 1; + + data->bufs[0]._offset = 0; + data->bufs[0]._len = bd->nb_len; + data->bufs[0]._index = idx; + data->nd_cmdref = (long)m; + + return (0); +} + +/* + * Create setup packet and put in queue for sending. + */ +void +ni_setup(struct ni_softc *sc) +{ + struct ifnet *ifp = &sc->sc_if; + struct ni_msg *msg; + struct ni_ptdb *ptdb; + struct ether_multi *enm; + struct ether_multistep step; + int i, res; + + msg = REMQHI(&fqb->nf_mforw); + if ((int)msg == Q_EMPTY) + return; /* What to do? */ + + ptdb = (struct ni_ptdb *)&msg->nm_text[0]; + memset(ptdb, 0, sizeof(struct ni_ptdb)); + + msg->nm_opcode = BVP_MSG; + msg->nm_len = 18; + ptdb->np_index = 2; /* definition type index */ + ptdb->np_fque = 2; /* Free queue */ + if (ifp->if_flags & IFF_RUNNING) { + msg->nm_opcode2 = NI_STPTDB; + ptdb->np_type = ETHERTYPE_IP; + ptdb->np_flags = PTDB_UNKN|PTDB_BDC; + if (ifp->if_flags & IFF_PROMISC) + ptdb->np_flags |= PTDB_PROMISC; + memset(ptdb->np_mcast[0], 0xff, ETHER_ADDR_LEN); /* Broadcast */ + ptdb->np_adrlen = 1; + msg->nm_len += 8; + ifp->if_flags &= ~IFF_ALLMULTI; + if ((ifp->if_flags & IFF_PROMISC) == 0) { + ETHER_FIRST_MULTI(step, &sc->sc_ec, enm); + i = 1; + while (enm != NULL) { + if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 6)) { + ifp->if_flags |= IFF_ALLMULTI; + ptdb->np_flags |= PTDB_AMC; + break; + } + msg->nm_len += 8; + ptdb->np_adrlen++; + memcpy(ptdb->np_mcast[i++], enm->enm_addrlo, + ETHER_ADDR_LEN); + ETHER_NEXT_MULTI(step, enm); + } + } + } else + msg->nm_opcode2 = NI_CLPTDB; + + res = INSQTI(msg, &gvp->nc_forw0); + if (res == Q_EMPTY) { + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + } +} + +/* + * Check for dead transmit logic. Not uncommon. + */ +void +nitimeout(ifp) + struct ifnet *ifp; +{ +#if 0 + struct ni_softc *sc = ifp->if_softc; + + if (sc->sc_inq == 0) + return; + + printf("%s: xmit logic died, resetting...\n", sc->sc_dev.dv_xname); + /* + * Do a reset of interface, to get it going again. + * Will it work by just restart the transmit logic? + */ + niinit(sc); +#endif +} + +/* + * Shutdown hook. Make sure the interface is stopped at reboot. + */ +void +ni_shutdown(arg) + void *arg; +{ + struct ni_softc *sc = arg; + + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_OWN|PCR_SHUTDOWN); + WAITREG(NI_PCR, PCR_OWN); + WAITREG(NI_PSR, PSR_OWN); + +} + diff --git a/sys/arch/vax/bi/if_nireg.h b/sys/arch/vax/bi/if_nireg.h new file mode 100644 index 00000000000..84abcac4e90 --- /dev/null +++ b/sys/arch/vax/bi/if_nireg.h @@ -0,0 +1,307 @@ +/* $OpenBSD: if_nireg.h,v 1.1 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: if_nireg.h,v 1.3 2001/08/20 12:20:07 wiz Exp $ */ +/* + * Copyright (c) 1988 Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * 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 University of + * California, Berkeley and its contributors. + * 4. 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. + * + * @(#)nireg.h 7.3 (Berkeley) 6/28/90 + */ + +/* + * Registers for the DEBNA and DEBNK Ethernet interfaces + * (DEC calls these Network Interfaces, hence nireg.h) + */ + +/* + * this seems to be intended to be more general, but I have no details, + * so it goes here for now + * + * BI Vax Port (BVP) stuff first: + */ +#ifdef notdef +struct bvpregs { + u_long p_pcr; /* port control register */ + u_long p_psr; /* port status register */ + u_long p_per; /* port error register */ + u_long p_pdr; /* port data register */ +}; + +/* + * BI node space registers + */ +struct ni_regs { + struct biiregs ni_bi; /* BIIC registers, except GPRs */ + struct bvpregs ni_tkp; /* tk50 port control via BIIC GPRs */ + u_long ni_xxx[64]; /* unused */ + u_long ni_rxcd; /* receive console data */ + struct bvpregs ni_nip; /* NI port control via BCI3 GPRs */ + u_long ni_pudr; /* power-up diagnostic register */ +}; +#endif + +#define NI_PCR 0x204 +#define NI_PSR 0x208 +#define NI_PER 0x20c +#define NI_PDR 0x210 +#define NI_PUDR 0x204 + +/* bits in PCR */ +#define PCR_OWN 0x80 +#define PCR_MFREEQ 0x000 +#define PCR_DFREEQ 0x100 +#define PCR_RFREEQ 0x200 +#define PCR_IFREEQ 0x300 +#define PCR_CMDQ0 PCR_MFREEQ +#define PCR_CMDQ1 PCR_DFREEQ +#define PCR_CMDQ2 PCR_RFREEQ +#define PCR_CMDQ3 PCR_IFREEQ +#define PCR_RESTART 11 +#define PCR_FREEQNE 7 +#define PCR_CMDQNE 6 +#define PCR_SHUTDOWN 4 +#define PCR_ENABLE 2 +#define PCR_INIT 1 + +/* bits in PSR */ +#define PSR_OWN 0x80000000 +#define PSR_STATE 0x00070000 +#define PSR_STOPPED 0x00060000 +#define PSR_ENABLED 0x00040000 +#define PSR_INITED 0x00020000 +#define PSR_UNDEF 0x00010000 +#define PSR_RSQ 0x00000080 +#define PSR_ERR 0x00000040 + +/* + * The DEBNx uses a very weird (set of) structure(s) to communicate + * with something as simple as an ethernet controller. This is not + * very different to the way communication is done over CI with disks. + */ + +/* Message packet */ +struct ni_msg { + u_int32_t nm_forw; + u_int32_t nm_back; + u_int32_t nm_pad1; + u_int8_t nm_pad2; + u_int8_t nm_status; + u_int8_t nm_opcode; + u_int8_t nm_pad3; + u_int16_t nm_len; + u_int8_t nm_opcode2; + u_int8_t nm_status2; + u_int32_t nm_pad4; + u_int8_t nm_text[128]; +}; + +/* Datagram packet */ +struct ni_dg { + u_int32_t nd_forw; + u_int32_t nd_back; + u_int32_t nd_pad1; + u_int8_t nd_pad2; + u_int8_t nd_status; + u_int8_t nd_opcode; + u_int8_t nd_pad3; + u_int16_t nd_len; + u_int16_t nd_status2; + u_int32_t nd_cmdref; + u_int32_t nd_ptdbidx; + struct { + u_int16_t _offset; + u_int16_t _len; + u_int16_t _index; + u_int16_t _key; + } bufs[NTXFRAGS]; +}; + +#define NIDG_CHAIN 0x8000 + +/* NI parameter block */ +struct ni_param { + u_int8_t np_dpa[8]; + u_int8_t np_apa[8]; + u_int8_t np_lsa[8]; + u_int8_t np_bvc[8]; + u_int16_t np_curaddr; + u_int16_t np_maxaddr; + u_int16_t np_curptt; + u_int16_t np_maxptt; + u_int16_t np_curfq; + u_int16_t np_maxfq; + u_int32_t np_sid; + u_int32_t np_mop; + u_int32_t np_flags; + u_int32_t np_rcto; + u_int32_t np_xmto; +}; + +#define NP_ECT 0x01 +#define NP_PAD 0x02 +#define NP_BOO 0x04 +#define NP_CAR 0x08 +#define NP_ILP 0x10 +#define NP_ELP 0x20 +#define NP_DCRC 0x40 +#define NP_THRU 0x80 + +/* Protocol type definition block */ +struct ni_ptdb { + u_int16_t np_type; /* Protocol type */ + u_int8_t np_fque; /* Free queue */ + u_int8_t np_flags; /* See below */ + u_int32_t np_index; /* protocol type index */ + u_int16_t np_adrlen; /* # of multicast addresses */ + u_int16_t np_802; /* for IEEE 802 packets */ + u_int8_t np_mcast[16][8];/* Multicast (direct match) array */ +}; + +#define PTDB_PROMISC 0x08 +#define PTDB_802 0x10 +#define PTDB_BDC 0x20 +#define PTDB_UNKN 0x40 +#define PTDB_AMC 0x80 + +/* Buffer descriptor */ +struct ni_bbd { + u_int16_t nb_status; /* Offset, valid etc */ + u_int16_t nb_key; + u_int32_t nb_len; /* Buffer length */ + u_int32_t nb_pte; /* start (vax) PTE for this buffer */ + u_int32_t nb_pad; +}; +#define NIBD_OFFSET 0x1ff +#define NIBD_VALID 0x8000 + + +/* Free Queue Block */ +struct ni_fqb { + u_int32_t nf_mlen; + u_int32_t nf_mpad; + u_int32_t nf_mforw; + u_int32_t nf_mback; + u_int32_t nf_dlen; + u_int32_t nf_dpad; + u_int32_t nf_dforw; + u_int32_t nf_dback; + u_int32_t nf_rlen; + u_int32_t nf_rpad; + u_int32_t nf_rforw; + u_int32_t nf_rback; + u_int32_t nf_ilen; + u_int32_t nf_ipad; + u_int32_t nf_iforw; + u_int32_t nf_iback; +}; + +/* DEBNx specific part of Generic VAX Port */ +struct ni_pqb { + u_int16_t np_veclvl; /* Interrupt vector + level */ + u_int16_t np_node; /* Where to interrupt */ + u_int32_t np_freeq; + u_int32_t np_vfqb; /* Free queue block pointer */ + u_int32_t np_pad1[39]; + u_int32_t np_bvplvl; + u_int32_t np_vpqb; /* Virtual address of Generic PQB */ + u_int32_t np_vbdt; /* Virtual address of descriptors */ + u_int32_t np_nbdr; /* Number of descriptors */ + u_int32_t np_spt; /* System Page Table */ + u_int32_t np_sptlen; /* System Page Table length */ + u_int32_t np_gpt; /* Global Page Table */ + u_int32_t np_gptlen; /* Global Page Table length */ + u_int32_t np_mask; + u_int32_t np_pad2[67]; +}; + +/* "Generic VAX Port Control Block" whatever it means */ +struct ni_gvppqb { + u_int32_t nc_forw0; + u_int32_t nc_back0; + u_int32_t nc_forw1; + u_int32_t nc_back1; + u_int32_t nc_forw2; + u_int32_t nc_back2; + u_int32_t nc_forw3; + u_int32_t nc_back3; + u_int32_t nc_forwr; + u_int32_t nc_backr; + struct ni_pqb nc_pqb; /* DEBNx specific part of struct */ +}; + + +/* BVP opcodes, should be somewhere else */ +#define BVP_DGRAM 1 +#define BVP_MSG 2 +#define BVP_DGRAMI 3 +#define BVP_DGRAMRX 33 +#define BVP_MSGRX 34 +#define BVP_DGRAMIRX 35 + +/* NI-specific sub-opcodes */ +#define NI_WSYSID 1 +#define NI_RSYSID 2 +#define NI_WPARAM 3 +#define NI_RPARAM 4 +#define NI_RCCNTR 5 +#define NI_RDCNTR 6 +#define NI_STPTDB 7 +#define NI_CLPTDB 8 + +/* bits in ni_pudr */ +#define PUDR_TAPE 0x40000000 /* tk50 & assoc logic ok */ +#define PUDR_PATCH 0x20000000 /* patch logic ok */ +#define PUDR_VRAM 0x10000000 /* DEBNx onboard RAM ok */ +#define PUDR_VROM1 0x08000000 /* uVax ROM 1 ok */ /* ? */ +#define PUDR_VROM2 0x04000000 /* uVax ROM 2 ok */ +#define PUDR_VROM3 0x02000000 /* uVax ROM 3 ok */ +#define PUDR_VROM4 0x01000000 /* uVax ROM 4 ok */ +#define PUDR_UVAX 0x00800000 /* uVax passes self test */ +#define PUDR_BI 0x00400000 /* BIIC and BCI3 chips ok */ +#define PUDR_TMR 0x00200000 /* interval timer ok */ +#define PUDR_IRQ 0x00100000 /* no IRQ lines stuck */ +#define PUDR_NI 0x00080000 /* Ethernet ctlr ok */ +#define PUDR_TK50 0x00040000 /* tk50 present */ +#define PUDR_PRES 0x00001000 /* tk50 present (again?!) */ +#define PUDR_UVINT 0x00000800 /* uVax-to-80186 intr logic ok */ +#define PUDR_BUSHD 0x00000400 /* no bus hold errors */ +#define PUDR_II32 0x00000200 /* II32 transceivers ok */ +#define PUDR_MPSC 0x00000100 /* MPSC logic ok */ +#define PUDR_GAP 0x00000080 /* gap-detect logic ok */ +#define PUDR_MISC 0x00000040 /* misc. registers ok */ +#define PUDR_UNEXP 0x00000020 /* unexpected interrupt trapped */ +#define PUDR_80186 0x00000010 /* 80186 ok */ +#define PUDR_PATCH2 0x00000008 /* patch logic ok (again) */ +#define PUDR_8RAM 0x00000004 /* 80186 RAM ok */ +#define PUDR_8ROM2 0x00000002 /* 80186 ROM1 ok */ +#define PUDR_8ROM1 0x00000001 /* 80186 ROM2 ok */ diff --git a/sys/arch/vax/bi/kdb.c b/sys/arch/vax/bi/kdb.c index 0362e0958ca..f03de356ff1 100644 --- a/sys/arch/vax/bi/kdb.c +++ b/sys/arch/vax/bi/kdb.c @@ -1,5 +1,5 @@ -/* $OpenBSD: kdb.c,v 1.6 2002/03/14 01:26:47 millert Exp $ */ -/* $NetBSD: kdb.c,v 1.5 1997/01/11 11:34:39 ragge Exp $ */ +/* $OpenBSD: kdb.c,v 1.7 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: kdb.c,v 1.26 2001/11/13 12:51:34 lukem Exp $ */ /* * Copyright (c) 1996 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -14,8 +14,8 @@ * 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. + * 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 * @@ -40,54 +40,64 @@ * Nices hardware error handling. */ +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: kdb.c,v 1.26 2001/11/13 12:51:34 lukem Exp $"); + #include <sys/param.h> #include <sys/kernel.h> #include <sys/buf.h> #include <sys/device.h> #include <sys/proc.h> +#include <sys/user.h> #include <sys/malloc.h> +#include <sys/systm.h> +#include <sys/sched.h> #include <uvm/uvm_extern.h> -#include <machine/sid.h> +#ifdef __vax__ #include <machine/pte.h> #include <machine/pcb.h> -#include <machine/trap.h> -#include <machine/scb.h> +#endif +#include <machine/bus.h> + +#include <dev/bi/bireg.h> +#include <dev/bi/bivar.h> +#include <dev/bi/kdbreg.h> + +#include <dev/mscp/mscp.h> +#include <dev/mscp/mscpreg.h> +#include <dev/mscp/mscpvar.h> -#include <vax/bi/bireg.h> -#include <vax/bi/bivar.h> -#include <vax/bi/kdbreg.h> +#include "locators.h" -#include <vax/mscp/mscp.h> -#include <vax/mscp/mscpvar.h> -#include <vax/mscp/mscpreg.h> +#define KDB_WL(adr, val) bus_space_write_4(sc->sc_iot, sc->sc_ioh, adr, val) +#define KDB_RL(adr) bus_space_read_4(sc->sc_iot, sc->sc_ioh, adr) +#define KDB_RS(adr) bus_space_read_2(sc->sc_iot, sc->sc_ioh, adr) -#define b_forw b_hash.le_next +#define b_forw b_hash.le_next /* * Software status, per controller. */ struct kdb_softc { struct device sc_dev; /* Autoconfig info */ - struct ivec_dsp sc_ivec; /* Interrupt vector handler */ - struct mscp_pack sc_kdb; /* Struct for kdb communication */ + struct evcnt sc_intrcnt; /* Interrupt counting */ + caddr_t sc_kdb; /* Struct for kdb communication */ struct mscp_softc *sc_softc; /* MSCP info (per mscpvar.h) */ - struct kdb_regs *sc_kr; /* KDB controller registers */ - struct mscp *sc_mscp; /* Keep pointer to active mscp */ + bus_dma_tag_t sc_dmat; + bus_dmamap_t sc_cmap; /* Control structures */ + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; }; -int kdbmatch(struct device *, void *, void *); -void kdbattach(struct device *, struct device *, void *); -void kdbreset(int); -void kdbintr(int); -void kdbctlrdone(struct device *, int); -int kdbprint(void *, const char *); -void kdbsaerror(struct device *, int); -int kdbgo(struct device *, struct buf *); - -struct cfdriver kdb_cd = { - NULL, "kdb", DV_DULL -}; +int kdbmatch __P((struct device *, struct cfdata *, void *)); +void kdbattach __P((struct device *, struct device *, void *)); +void kdbreset __P((int)); +void kdbintr __P((void *)); +void kdbctlrdone __P((struct device *)); +int kdbprint __P((void *, const char *)); +void kdbsaerror __P((struct device *, int)); +void kdbgo __P((struct device *, struct mscp_xi *)); struct cfattach kdb_ca = { sizeof(struct kdb_softc), kdbmatch, kdbattach @@ -116,20 +126,21 @@ kdbprint(aux, name) * Poke at a supposed KDB to see if it is there. */ int -kdbmatch(parent, match, aux) +kdbmatch(parent, cf, aux) struct device *parent; - void *match, *aux; + struct cfdata *cf; + void *aux; { - struct cfdata *cf = match; struct bi_attach_args *ba = aux; - if (ba->ba_node->biic.bi_dtype != BIDT_KDB50) - return 0; + if (bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE) != BIDT_KDB50) + return 0; - if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != ba->ba_nodenr) - return 0; + if (cf->cf_loc[BICF_NODE] != BICF_NODE_DEFAULT && + cf->cf_loc[BICF_NODE] != ba->ba_nodenr) + return 0; - return 1; + return 1; } void @@ -140,104 +151,135 @@ kdbattach(parent, self, aux) struct kdb_softc *sc = (void *)self; struct bi_attach_args *ba = aux; struct mscp_attach_args ma; - extern struct ivec_dsp idsptch; volatile int i = 10000; + int error, rseg; + bus_dma_segment_t seg; printf("\n"); - bcopy(&idsptch, &sc->sc_ivec, sizeof(struct ivec_dsp)); - scb->scb_nexvec[1][ba->ba_nodenr] = &sc->sc_ivec; - sc->sc_ivec.hoppaddr = kdbintr; - sc->sc_ivec.pushlarg = self->dv_unit; - sc->sc_kr = (void *)ba->ba_node; + bi_intr_establish(ba->ba_icookie, ba->ba_ivec, + kdbintr, sc, &sc->sc_intrcnt); + evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL, + sc->sc_dev.dv_xname, "intr"); - bzero(&sc->sc_kdb, sizeof (struct mscp_pack)); + sc->sc_iot = ba->ba_iot; + sc->sc_ioh = ba->ba_ioh; + sc->sc_dmat = ba->ba_dmat; + + /* + * Map the communication area and command and + * response packets into Unibus space. + */ + if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct mscp_pack), + NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { + printf("Alloc ctrl area %d\n", error); + return; + } + if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, + sizeof(struct mscp_pack), &sc->sc_kdb, + BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) { + printf("Map ctrl area %d\n", error); +err: bus_dmamem_free(sc->sc_dmat, &seg, rseg); + return; + } + if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct mscp_pack), + 1, sizeof(struct mscp_pack), 0, BUS_DMA_NOWAIT, &sc->sc_cmap))) { + printf("Create DMA map %d\n", error); +err2: bus_dmamem_unmap(sc->sc_dmat, sc->sc_kdb, + sizeof(struct mscp_pack)); + goto err; + } + if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmap, + sc->sc_kdb, sizeof(struct mscp_pack), 0, BUS_DMA_NOWAIT))) { + printf("Load ctrl map %d\n", error); + bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmap); + goto err2; + } + memset(sc->sc_kdb, 0, sizeof(struct mscp_pack)); ma.ma_mc = &kdb_mscp_ctlr; ma.ma_type = MSCPBUS_DISK|MSCPBUS_KDB; - ma.ma_uuda = (struct mscp_pack *)kvtophys(&sc->sc_kdb); - ma.ma_uda = &sc->sc_kdb; - ma.ma_ip = &sc->sc_kr->kdb_ip; - ma.ma_sa = &sc->sc_kr->kdb_sa; - ma.ma_sw = &sc->sc_kr->kdb_sw; + ma.ma_uda = (struct mscp_pack *)sc->sc_kdb; ma.ma_softc = &sc->sc_softc; - ma.ma_ivec = (int)&scb->scb_nexvec[1][ba->ba_nodenr] - (int)scb; + ma.ma_iot = sc->sc_iot; + ma.ma_iph = sc->sc_ioh + KDB_IP; + ma.ma_sah = sc->sc_ioh + KDB_SA; + ma.ma_swh = sc->sc_ioh + KDB_SW; + ma.ma_dmat = sc->sc_dmat; + ma.ma_dmam = sc->sc_cmap; + ma.ma_ivec = ba->ba_ivec; ma.ma_ctlrnr = ba->ba_nodenr; - sc->sc_kr->kdb_bi.bi_csr |= BICSR_NRST; + ma.ma_adapnr = ba->ba_busnr; + + KDB_WL(BIREG_VAXBICSR, KDB_RL(BIREG_VAXBICSR) | BICSR_NRST); while (i--) /* Need delay??? */ ; - sc->sc_kr->kdb_bi.bi_intrdes = ba->ba_intcpu; - sc->sc_kr->kdb_bi.bi_bcicsr |= BCI_STOPEN | BCI_IDENTEN | BCI_UINTEN | - BCI_INTEN; - sc->sc_kr->kdb_bi.bi_uintrcsr = ma.ma_ivec; + KDB_WL(BIREG_INTRDES, ba->ba_intcpu); /* Interrupt on CPU # */ + KDB_WL(BIREG_BCICSR, KDB_RL(BIREG_BCICSR) | + BCI_STOPEN | BCI_IDENTEN | BCI_UINTEN | BCI_INTEN); + KDB_WL(BIREG_UINTRCSR, ba->ba_ivec); config_found(&sc->sc_dev, &ma, kdbprint); } -int -kdbgo(usc, bp) +void +kdbgo(usc, mxi) struct device *usc; - struct buf *bp; + struct mscp_xi *mxi; { struct kdb_softc *sc = (void *)usc; - struct mscp_softc *mi = sc->sc_softc; - struct mscp *mp = (void *)bp->b_actb; - struct pcb *pcb; - pt_entry_t *pte; - int pfnum, npf, o, i; - unsigned info = 0; - caddr_t addr; - - o = (int)bp->b_un.b_addr & PGOFSET; - npf = btoc(bp->b_bcount + o) + 1; - addr = bp->b_un.b_addr; - - /* - * Get a pointer to the pte pointing out the first virtual address. - * Use different ways in kernel and user space. - */ - if ((bp->b_flags & B_PHYS) == 0) { - pte = kvtopte(addr); - } else { - pcb = bp->b_proc->p_vmspace->vm_map.pmap->pm_pcb; - pte = uvtopte(addr, pcb); - } - - /* - * When we are doing DMA to user space, be sure that all pages - * we want to transfer to is mapped. WHY DO WE NEED THIS??? - * SHOULDN'T THEY ALWAYS BE MAPPED WHEN DOING THIS??? - */ - for (i = 0; i < (npf - 1); i++) { - if ((pte + i)->pg_pfn == 0) { - int rv; - rv = vm_fault(&bp->b_proc->p_vmspace->vm_map, - (unsigned)addr + i * NBPG, - VM_PROT_READ|VM_PROT_WRITE, FALSE); - if (rv) - panic("KDB DMA to nonexistent page, %d", rv); - } - } + struct buf *bp = mxi->mxi_bp; + struct mscp *mp = mxi->mxi_mp; + u_int32_t addr = (u_int32_t)bp->b_data; + u_int32_t mapaddr; + int err; + + /* + * The KDB50 wants to read VAX Page tables directly, therefore + * the result from bus_dmamap_load() is uninteresting. (But it + * should never fail!). + * + * On VAX, point to the corresponding page tables. (user/sys) + * On other systems, do something else... + */ + err = bus_dmamap_load(sc->sc_dmat, mxi->mxi_dmam, bp->b_data, + bp->b_bcount, (bp->b_flags & B_PHYS ? bp->b_proc : 0), + BUS_DMA_NOWAIT); + + if (err) /* Shouldn't happen */ + panic("kdbgo: bus_dmamap_load: error %d", err); + +#ifdef __vax__ /* - * pte's for userspace isn't necessary positioned - * in consecutive physical pages. We check if they - * are, otherwise we need to copy the pte's to a - * physically contigouos page area. - * XXX some copying here may be unneccessary. Subject to fix. + * Get a pointer to the pte pointing out the first virtual address. + * Use different ways in kernel and user space. */ - if (bp->b_flags & B_PHYS) { - int i = kvtophys(pte); - unsigned k; - - if (trunc_page(i) != trunc_page(kvtophys(pte) + npf * 4)) { - info = (unsigned)malloc(2 * NBPG, M_DEVBUF, M_WAITOK); - k = (info + PGOFSET) & ~PGOFSET; - bcopy(pte, (void *)k, NBPG); - i = kvtophys(k); + if ((bp->b_flags & B_PHYS) == 0) { + mapaddr = ((u_int32_t)kvtopte(addr)) & ~KERNBASE; + } else { + struct pcb *pcb; + u_int32_t eaddr; + + /* + * We check if the PTE's needed crosses a page boundary. + * If they do; only transfer the amount of data that is + * mapped by the first PTE page and led the system handle + * the rest of the data. + */ + pcb = &bp->b_proc->p_addr->u_pcb; + mapaddr = (u_int32_t)uvtopte(addr, pcb); + eaddr = (u_int32_t)uvtopte(addr + (bp->b_bcount - 1), pcb); + if (trunc_page(mapaddr) != trunc_page(eaddr)) { + mp->mscp_seq.seq_bytecount = + (((round_page(mapaddr) - mapaddr)/4) * 512); } - mp->mscp_seq.seq_mapbase = i; - } else - mp->mscp_seq.seq_mapbase = (unsigned)pte; - mscp_dgo(mi, KDB_MAP | o, info, bp); - return 1; + mapaddr = kvtophys(mapaddr); + } +#else +#error Must write code to handle KDB50 on non-vax. +#endif + + mp->mscp_seq.seq_mapbase = mapaddr; + mxi->mxi_dmam->dm_segs[0].ds_addr = (addr & 511) | KDB_MAP; + mscp_dgo(sc->sc_softc, mxi); } void @@ -246,11 +288,11 @@ kdbsaerror(usc, doreset) int doreset; { struct kdb_softc *sc = (void *)usc; - register int code = sc->sc_kr->kdb_sa; - if ((code & MP_ERR) == 0) + if ((KDB_RS(KDB_SA) & MP_ERR) == 0) return; - printf("%s: controller error, sa=0x%x\n", sc->sc_dev.dv_xname, code); + printf("%s: controller error, sa=0x%x\n", sc->sc_dev.dv_xname, + KDB_RS(KDB_SA)); /* What to do now??? */ } @@ -260,18 +302,17 @@ kdbsaerror(usc, doreset) * interrupts, and process responses. */ void -kdbintr(ctlr) - int ctlr; +kdbintr(void *arg) { - struct kdb_softc *sc = kdb_cd.cd_devs[ctlr]; - struct uba_softc *uh; - struct mscp_pack *ud; + struct kdb_softc *sc = arg; - if (sc->sc_kr->kdb_sa & MP_ERR) { /* ctlr fatal error */ + if (KDB_RS(KDB_SA) & MP_ERR) { /* ctlr fatal error */ kdbsaerror(&sc->sc_dev, 1); return; } + KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE); mscp_intr(sc->sc_softc); + KERNEL_UNLOCK(); } #ifdef notyet @@ -283,7 +324,7 @@ void kdbreset(ctlr) int ctlr; { - register struct kdb_softc *sc; + struct kdb_softc *sc; sc = kdb_cd.cd_devs[ctlr]; printf(" kdb%d", ctlr); @@ -304,10 +345,7 @@ kdbreset(ctlr) #endif void -kdbctlrdone(usc, info) +kdbctlrdone(usc) struct device *usc; - int info; { - if (info) - free((void *)info, NBPG * 2); } diff --git a/sys/arch/vax/bi/kdbreg.h b/sys/arch/vax/bi/kdbreg.h index c92bd0bf732..0103bb7e21e 100644 --- a/sys/arch/vax/bi/kdbreg.h +++ b/sys/arch/vax/bi/kdbreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kdbreg.h,v 1.3 2000/04/28 03:42:39 bjc Exp $ */ +/* $OpenBSD: kdbreg.h,v 1.4 2002/06/11 09:36:23 hugh Exp $ */ /* $NetBSD: kdbreg.h,v 1.3 1999/11/03 21:57:40 ragge Exp $ */ /* * Copyright (c) 1988 Regents of the University of California. @@ -42,6 +42,7 @@ * The KDB50 registers are embedded inside the bi interface * general-purpose registers. */ +#ifdef notdef struct kdb_regs { struct biiregs kdb_bi; short kdb_xxx; /* first half of GPR 0 unused */ @@ -49,6 +50,7 @@ struct kdb_regs { short kdb_sa; /* status & address (r/o half) */ short kdb_sw; /* status & address (w/o half) */ }; +#endif #define KDB_IP 0xf2 #define KDB_SA 0xf4 |