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 | |
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')
83 files changed, 8409 insertions, 3375 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 diff --git a/sys/arch/vax/boot/Makefile.inc b/sys/arch/vax/boot/Makefile.inc index 1df25851203..bbe032e06d2 100644 --- a/sys/arch/vax/boot/Makefile.inc +++ b/sys/arch/vax/boot/Makefile.inc @@ -1,12 +1,11 @@ -# $OpenBSD: Makefile.inc,v 1.2 2000/10/04 04:03:10 bjc Exp $ -# $NetBSD: Makefile.inc,v 1.2 1999/07/18 05:55:45 abs Exp $ +# $OpenBSD: Makefile.inc,v 1.3 2002/06/11 09:36:23 hugh Exp $ +# $NetBSD: Makefile.inc,v 1.6 2002/02/24 01:04:23 matt Exp $ -XXRPB=0x354240 RELOC=0x39F000 .PATH: ${.CURDIR}/../../vax ${.CURDIR}/../common -CPPFLAGS+=-I${.CURDIR}/../../../../ -I${.CURDIR}/../../ -I${.CURDIR}/../common -I${.CURDIR}/../../include -CPPFLAGS+=-DXXRPB=${XXRPB} -DRELOC=${RELOC} +CPPFLAGS+=-I. -I${.CURDIR}/../../../../ -I${.CURDIR}/../../ -I${.CURDIR}/../common -I${.CURDIR}/../../include +CPPFLAGS+=-DRELOC=${RELOC} # Private handling of assembler files. .s.o: diff --git a/sys/arch/vax/boot/boot/Makefile b/sys/arch/vax/boot/boot/Makefile index 49f3c3cb072..b48472504f1 100644 --- a/sys/arch/vax/boot/boot/Makefile +++ b/sys/arch/vax/boot/boot/Makefile @@ -1,23 +1,27 @@ -# $OpenBSD: Makefile,v 1.3 2002/02/14 20:45:31 deraadt Exp $ -# $NetBSD: Makefile,v 1.4 1999/05/23 21:58:19 ragge Exp $ +# $OpenBSD: Makefile,v 1.4 2002/06/11 09:36:23 hugh Exp $ +# $NetBSD: Makefile,v 1.27 2002/04/07 07:00:25 matt Exp $ S!= cd ${.CURDIR}/../../../../; pwd +NOMAN= # defined + +.include <bsd.own.mk> -NOMAN= 1 PROG= boot -DEVS= hp.c ctu.c ra.c tmscp.c mfm.c if_qe.c if_le.c if_ze.c -SRCS= srt0.s boot.c devopen.c conf.c autoconf.c netio.c rom.c romread.s \ - urem.s udiv.s consio.c str.s ${DEVS} findcpu.c -#OBJS= autoconf.o boot.o conf.o consio.o ctu.o devopen.o findcpu.o hp.o \ -# if_le.o if_qe.o if_ze.o mfm.o netio.o ra.o rom.o romread.o srt0.o \ -# str.o tmscp.o udiv.o urem.o - -CLEANFILES+=${PROG}.mop -CPPFLAGS+=-DSUPPORT_BOOTPARAMS -DSUPPORT_DHCP -D_STANDALONE +WARNS?= 1 +DEVS= hp.c ctu.c ra.c mfm.c if_qe.c if_le.c if_ze.c if_de.c if_ni.c +SRCS= srt0.S boot.c devopen.c conf.c autoconf.c netio.c rom.c romread.S \ + urem.s udiv.s consio.c consio2.S str.S ${DEVS} findcpu.c + +CLEANFILES+=${PROG} ${PROG}.sym +CPPFLAGS+=-DSUPPORT_BOOTPARAMS -DSUPPORT_DHCP -D_STANDALONE \ + -DNO_MID_CHECK #CPPFLAGS+=-DBOOTP_DEBUG -DNETIF_DEBUG -DETHER_DEBUG -DNFS_DEBUG -DDEV_DEBUG \ -# -DRPC_DEBUG -DRARP_DEBUG -DPARANOID -DSUPPORT_BOOTP -BINDIR= /usr/mdec +# -DRPC_DEBUG -DRARP_DEBUG -DPARANOID + +BINDIR=/usr/mdec +#SA_AS= library +#SAMISCMAKEFLAGS=SA_USE_CREAD=yes SA_INCLUDE_NET=yes SA_USE_LOADFILE=yes SA_ZLIB= yes SAREL= .include "${S}/lib/libsa/Makefile.inc" @@ -32,15 +36,36 @@ LIBZ= ${ZLIB} #.include "${S}/lib/libkern/Makefile.inc" #LIBKERN=${KERNLIB} -boot: ${OBJS} ${SALIB} ${LIBZ} ${LIBKERN} - ld -N -Ttext ${RELOC} -e nisse -o ${PROG} -Llib/sa -L. ${OBJS} \ - ${LIBSA} ${LIBZ} -lsa ${LIBKERN} - /usr/sbin/mopa.out ${PROG} ${PROG}.mop - strip ${PROG} - size ${PROG} +.if ${MACHINE} == "vax" +.PHONY: machine-links +beforedepend: machine-links +machine-links: + @rm -f machine && ln -s ${S}/arch/${MACHINE}/include machine + @rm -f ${MACHINE_ARCH} && ln -s ${S}/arch/${MACHINE_ARCH}/include ${MACHINE_ARCH} +.NOPATH: machine ${MACHINE_ARCH} +CLEANFILES+= machine ${MACHINE_ARCH} +.endif + +#.if ${OBJECT_FMT} == "ELF" +#START=start +#.else +START=nisse +#.endif + +${PROG}: machine-links ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN} + ${LD} -N -Ttext ${RELOC} -e ${START} -o ${PROG}.sym -Llib/sa -L. ${OBJS} \ + ${LIBSA} ${LIBZ} ${LIBSA} ${LIBKERN} + /usr/sbin/mopa.out ${PROG}.sym ${PROG}.mop + /bin/cp ${PROG}.sym ${PROG} + /usr/bin/strip ${PROG} + /usr/bin/size ${PROG} clean:: rm -f a.out [Ee]rrs mklog core *.core ${PROG} ${OBJS} ${LOBJS} \ ${CLEANFILES} +#install: +# ${INSTALL_FILE} -o ${BINOWN} -g ${BINGRP} -m 555 \ +# ${PROG} ${DESTDIR}${MDEC_DIR}/${PROG} + .include <bsd.prog.mk> diff --git a/sys/arch/vax/boot/boot/autoconf.c b/sys/arch/vax/boot/boot/autoconf.c index d3fe75802ce..00a2db03583 100644 --- a/sys/arch/vax/boot/boot/autoconf.c +++ b/sys/arch/vax/boot/boot/autoconf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: autoconf.c,v 1.7 2002/03/09 03:36:33 hugh Exp $ */ -/* $NetBSD: autoconf.c,v 1.5 1999/08/23 19:09:27 ragge Exp $ */ +/* $OpenBSD: autoconf.c,v 1.8 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: autoconf.c,v 1.19 2002/06/01 15:33:22 ragge Exp $ */ /* * Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -34,112 +34,65 @@ -#include "sys/param.h" +#include <sys/param.h> + +#include <lib/libsa/stand.h> + #include "../../include/mtpr.h" #include "../../include/sid.h" +#include "../../include/intr.h" +#include "../../include/rpb.h" #include "../../include/scb.h" #include "vaxstand.h" -extern const struct ivec_dsp idsptch; /* since we are not KERNEL */ - -int nmba=0, nuba=0, nbi=0,nsbi=0,nuda=0; -int *mbaaddr, *ubaaddr, *biaddr; -int *udaaddr, *uioaddr, tmsaddr, *bioaddr; - -static int mba750[]={0xf28000,0xf2a000,0xf2c000}; -static int uba750[]={0xf30000,0xf32000}; -static int uio750[]={0xfc0000,0xf80000}; -static int uda750[]={0772150}; - -/* 11/780's only have 4, 8600 have 8 of these. */ -/* XXX - all of these should be bound to physical addresses */ -static int mba780[]={0x20010000,0x20012000,0x20014000,0x20016000, - 0x22010000,0x22012000,0x22014000,0x22016000}; -static int uba780[]={0, 0, 0, 0x20006000,0x20008000,0x2000a000,0x2000c000, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x22006000,0x22008000,0x2200a000,0x2200c000}; -static int uio780[]={0, 0, 0, 0x20100000,0x20140000,0x20180000,0x201c0000, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x22100000,0x22140000,0x22180000,0x221c0000}; -static int bi8200[]={0x20000000, 0x22000000, 0x24000000, 0x26000000, - 0x28000000, 0x2a000000}; -static int bio8200[]={0x20400000}; - -static int uba630[]={0x20087800}; -static int uio630[]={0x30000000}; -#define qbdev(csr) (((csr) & 017777)-0x10000000) -static int uda630[]={qbdev(0772150),qbdev(0760334)}; - -static int uba670[]={0x20040000}; -static int uio670[]={0x20000000}; -static int uda670[]={0x20004030,0x20004230}; -#define qb670dev(csr) (((csr) & 017777)+0x20000000) +void autoconf(void); +void findcpu(void); +void consinit(void); +void scbinit(void); +int getsecs(void); +void scb_stray(void *); +void longjmp(int *, int); +void rtimer(void *); + +long *bootregs; /* - * Autoconf routine is really stupid; but it actually don't - * need any intelligence. We just assume that all possible - * devices exists on each cpu. Fast & easy. + * Do some initial setup. Also create a fake RPB for net-booted machines + * that don't have an in-prom VMB. */ +void autoconf() { - extern int memsz; int copyrpb = 1; + int fromnet = (bootregs[12] != -1); findcpu(); /* Configures CPU variables */ consinit(); /* Allow us to print out things */ scbinit(); /* Fix interval clock etc */ +#ifdef DEV_DEBUG + printf("Register contents:\n"); + for (copyrpb = 0; copyrpb < 13; copyrpb++) + printf("r%d: %lx\n", copyrpb, bootregs[copyrpb]); +#endif switch (vax_boardtype) { - default: - printf("\nCPU type %d not supported by boot\n",vax_cputype); - printf("trying anyway...\n"); - break; - case VAX_BTYP_780: case VAX_BTYP_790: - memsz = 0; - nmba = 8; - nuba = 32; /* XXX */ - nuda = 1; - mbaaddr = mba780; - ubaaddr = uba780; - udaaddr = uda750; - uioaddr = uio780; - tmsaddr = 0774500; - break; - - case VAX_BTYP_750: - memsz = 0; - nmba = 3; - nuba = 2; - nuda = 1; - mbaaddr = mba750; - ubaaddr = uba750; - udaaddr = uda750; - uioaddr = uio750; - tmsaddr = 0774500; - break; - - case VAX_BTYP_630: /* the same for uvaxIII */ - case VAX_BTYP_650: - case VAX_BTYP_660: - case VAX_BTYP_670: - nuba = 1; - nuda = 2; - ubaaddr = uba630; - udaaddr = uda630; - uioaddr = uio630; - tmsaddr = qbdev(0774500); - break; - case VAX_BTYP_8000: + case VAX_BTYP_9CC: + case VAX_BTYP_9RR: + case VAX_BTYP_1202: + if (fromnet == 0) + break; copyrpb = 0; - memsz = 0; - nbi = 1; - biaddr = bi8200; - bioaddr = bio8200; + bootrpb.devtyp = bootregs[0]; + bootrpb.adpphy = bootregs[1]; + bootrpb.csrphy = bootregs[2]; + bootrpb.unit = bootregs[3]; + bootrpb.rpb_bootr5 = bootregs[5]; + bootrpb.pfncnt = 0; break; case VAX_BTYP_46: @@ -153,15 +106,18 @@ autoconf() map[i] = 0x80000000 | i; }break; - case VAX_BTYP_410: - case VAX_BTYP_420: - case VAX_BTYP_43: - case VAX_BTYP_49: - case VAX_BTYP_1301: - case VAX_BTYP_1303: - case VAX_BTYP_1305: break; } + + if (copyrpb) { + struct rpb *prpb = (struct rpb *)bootregs[11]; + bcopy((caddr_t)prpb, &bootrpb, sizeof(struct rpb)); + if (prpb->iovec) { + bootrpb.iovec = (int)alloc(prpb->iovecsz); + bcopy((caddr_t)prpb->iovec, (caddr_t)bootrpb.iovec, + prpb->iovecsz); + } + } } /* @@ -170,25 +126,34 @@ autoconf() volatile int tickcnt; +int getsecs() { - volatile int loop; - int todr; - return tickcnt/100; } -void scb_stray(), rtimer(); struct ivec_dsp **scb; struct ivec_dsp *scb_vec; +extern struct ivec_dsp idsptch; +extern int jbuf[10]; + +static void +mcheck(void *arg) +{ + int off, *mfp = (int *)&arg; + + off = (mfp[7]/4 + 8); + printf("Machine check, pc=%x, psl=%x\n", mfp[off], mfp[off+1]); + longjmp(jbuf, 1); +} /* * Init the SCB and set up a handler for all vectors in the lower space, * to detect unwanted interrupts. */ +void scbinit() { - extern int timer; int i; /* @@ -211,18 +176,19 @@ scbinit() scb_vec[i].ev = NULL; } scb_vec[0xc0/4].hoppaddr = rtimer; + scb_vec[4/4].hoppaddr = mcheck; - mtpr(-10000, PR_NICR); /* Load in count register */ + if (vax_boardtype != VAX_BTYP_VXT) + mtpr(-10000, PR_NICR); /* Load in count register */ mtpr(0x800000d1, PR_ICCS); /* Start clock and enable interrupt */ mtpr(20, PR_IPL); } -extern int jbuf[10]; extern int sluttid, senast, skip; void -rtimer() +rtimer(void *arg) { mtpr(31, PR_IPL); tickcnt++; @@ -230,29 +196,40 @@ rtimer() if (skip) return; if ((vax_boardtype == VAX_BTYP_46) || - (vax_boardtype == VAX_BTYP_48) || - (vax_boardtype == VAX_BTYP_49)) { + (vax_boardtype == VAX_BTYP_48) || + (vax_boardtype == VAX_BTYP_49)) { int nu = sluttid - getsecs(); if (senast != nu) { mtpr(20, PR_IPL); - longjmp(jbuf); + longjmp(jbuf, 1); } } } +#ifdef __ELF__ +#define IDSPTCH "idsptch" +#define EIDSPTCH "eidsptch" +#define CMN_IDSPTCH "cmn_idsptch" +#else +#define IDSPTCH "_idsptch" +#define EIDSPTCH "_eidsptch" +#define CMN_IDSPTCH "_cmn_idsptch" +#endif + asm(" + .text .align 2 - .globl _idsptch, _eidsptch -_idsptch: + .globl " IDSPTCH ", " EIDSPTCH " +" IDSPTCH ": pushr $0x3f .word 0x9f16 - .long _cmn_idsptch + .long " CMN_IDSPTCH " .long 0 .long 0 .long 0 -_eidsptch: +" EIDSPTCH ": -_cmn_idsptch: +" CMN_IDSPTCH ": movl (sp)+,r0 pushl 4(r0) calls $1,*(r0) @@ -265,8 +242,7 @@ _cmn_idsptch: * This function must _not_ save any registers (in the reg save mask). */ void -scb_stray(arg) - int arg; +scb_stray(void *arg) { static int vector, ipl; @@ -274,4 +250,3 @@ scb_stray(arg) vector = (int) arg; printf("stray interrupt: vector 0x%x, ipl %d\n", vector, ipl); } - diff --git a/sys/arch/vax/boot/boot/boot.c b/sys/arch/vax/boot/boot/boot.c index 5b18de3404f..dd5a4756e98 100644 --- a/sys/arch/vax/boot/boot/boot.c +++ b/sys/arch/vax/boot/boot/boot.c @@ -1,5 +1,5 @@ -/* $OpenBSD: boot.c,v 1.9 2002/02/13 02:42:20 deraadt Exp $ */ -/* $NetBSD: boot.c,v 1.4 1999/10/23 14:42:22 ragge Exp $ */ +/* $OpenBSD: boot.c,v 1.10 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: boot.c,v 1.18 2002/05/31 15:58:26 ragge Exp $ */ /*- * Copyright (c) 1982, 1986 The Regents of the University of California. * All rights reserved. @@ -35,13 +35,18 @@ * @(#)boot.c 7.15 (Berkeley) 5/4/91 */ -#include "sys/param.h" -#include "sys/reboot.h" -#include "rpb.h" +#include <sys/param.h> +#include <sys/reboot.h> #include "lib/libsa/stand.h" +#ifdef notyet +#include "lib/libsa/loadfile.h" +#include "lib/libkern/libkern.h" +#endif #define V750UCODE(x) ((x>>8)&255) +#include "machine/rpb.h" + #include "vaxstand.h" /* @@ -51,16 +56,20 @@ */ char line[100]; -int devtype, bootdev, howto, debug; +int bootdev, debug; extern unsigned opendev; -extern unsigned *bootregs; -struct rpb *rpb; -void usage(), boot(), halt(); +void usage(char *), boot(char *), halt(char *); +void Xmain(void); +void autoconf(void); +int getsecs(void); +int setjmp(int *); +int testkey(void); +void loadpcs(void); -struct vals { +const struct vals { char *namn; - void (*func)(); + void (*func)(char *); char *info; } val[] = { {"?", usage, "Show this help menu"}, @@ -70,34 +79,37 @@ struct vals { {0, 0}, }; -char *filer[] = { - "bsd", - "bsd.gz", - "bsd.old", - 0, +static struct { + char name[12]; + int quiet; +} filelist[] = { + { "bsd", 0 }, + { "bsd.old", 0 }, + { "bsd.vax", 1 }, + { "bsd.gz", 0 }, + { "", 0 }, }; int jbuf[10]; -int sluttid, senast, skip; +int sluttid, senast, skip, askname; +struct rpb bootrpb; -Xmain() +void +Xmain(void) { - int io, type, filindex = 0; + int io; int j, nu; - volatile int askname; - - /* make sure the rpb is out of the way so it does not get trampled; - * this will be the case if booting from net - */ +#ifdef noyet + u_long marks[MARK_MAX]; +#endif + extern const char bootprog_rev[], bootprog_date[]; - rpb = (struct rpb *)bootregs[11]; - bootdev = rpb->devtyp; - io=0; + io = 0; skip = 1; autoconf(); - askname = howto & RB_ASKNAME; - printf("\n\r>> OpenBSD/vax boot [%s %s] <<\n", __DATE__, __TIME__); + askname = bootrpb.rpb_bootr5 & RB_ASKNAME; + printf("\n\r>> OpenBSD/vax boot [%s] [%s] <<\n", "1.9", __DATE__); printf(">> Press enter to autoboot now, or any other key to abort: "); sluttid = getsecs() + 5; senast = 0; @@ -122,25 +134,46 @@ Xmain() skip = 1; printf("\n"); + if (setjmp(jbuf)) + askname = 1; + /* First try to autoboot */ if (askname == 0) { - type = (devtype >> B_TYPESHIFT) & B_TYPEMASK; - if ((unsigned)type < ndevs && devsw[type].dv_name) - while (filer[filindex]) { - errno = 0; - printf("> boot %s\n", filer[filindex]); - exec(filer[filindex++], 0, 0); - printf("boot failed: %s\n", strerror(errno)); -#if 0 - if (testkey()) - break; + int fileindex; + for (fileindex = 0; filelist[fileindex].name[0] != '\0'; + fileindex++) { +#ifdef notyet + int err; #endif + errno = 0; + if (!filelist[fileindex].quiet) + printf("> boot %s\n", filelist[fileindex].name); + exec(filelist[fileindex].name, 0, 0); +#ifdef notyet + marks[MARK_START] = 0; + err = loadfile(filelist[fileindex].name, marks, + LOAD_KERNEL|COUNT_KERNEL); + if (err == 0) { + machdep_start((char *)marks[MARK_ENTRY], + marks[MARK_NSYM], + (void *)marks[MARK_START], + (void *)marks[MARK_SYM], + (void *)marks[MARK_END]); } +#endif + if (!filelist[fileindex].quiet) + printf("%s: boot failed: %s\n", + filelist[fileindex].name, strerror(errno)); +#if 0 /* Will hang VAX 4000 machines */ + if (testkey()) + break; +#endif + } } /* If any key pressed, go to conversational boot */ for (;;) { - struct vals *v = &val[0]; + const struct vals *v = &val[0]; char *c, *d; printf("> "); @@ -165,21 +198,23 @@ Xmain() (*v->func)(d); else printf("Unknown command: %s\n", c); - } } void -halt() +halt(char *hej) { asm("halt"); } void -boot(arg) - char *arg; +boot(char *arg) { char *fn = "bsd"; + int howto, fl, err; +#ifdef notyet + u_long marks[MARK_MAX]; +#endif if (arg) { while (*arg == ' ') @@ -195,10 +230,12 @@ boot(arg) goto load; } if (*arg != '-') { -fail: printf("usage: boot [filename] [-asd]\n"); +fail: printf("usage: boot [filename] [-acsd]\n"); return; } + howto = 0; + while (*++arg) { if (*arg == 'a') howto |= RB_ASKNAME; @@ -211,8 +248,21 @@ fail: printf("usage: boot [filename] [-asd]\n"); else goto fail; } + bootrpb.rpb_bootr5 = howto; + } +load: + exec(fn, 0, 0); +#ifdef notyet + marks[MARK_START] = 0; + err = loadfile(fn, marks, LOAD_KERNEL|COUNT_KERNEL); + if (err == 0) { + machdep_start((char *)marks[MARK_ENTRY], + marks[MARK_NSYM], + (void *)marks[MARK_START], + (void *)marks[MARK_SYM], + (void *)marks[MARK_END]); } -load: exec(fn, 0, 0); +#endif printf("Boot failed: %s\n", strerror(errno)); } @@ -230,12 +280,13 @@ load: exec(fn, 0, 0); #define extzv(one, two, three,four) \ ({ \ - asm __volatile (" extzv %0,%3,%1,(%2)+" \ + asm __volatile (" extzv %0,%3,(%1),(%2)+" \ : \ - : "g"(one),"g"(two),"r"(three),"g"(four)); \ + : "g"(one),"g"(two),"g"(three),"g"(four)); \ }) +void loadpcs() { static int pcsdone = 0; @@ -310,9 +361,9 @@ loadpcs() } void -usage() +usage(char *hej) { - struct vals *v = &val[0]; + const struct vals *v = &val[0]; printf("Commands:\n"); while (v->namn) { diff --git a/sys/arch/vax/boot/boot/conf.c b/sys/arch/vax/boot/boot/conf.c index a5a21df6d33..c08626642ec 100644 --- a/sys/arch/vax/boot/boot/conf.c +++ b/sys/arch/vax/boot/boot/conf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: conf.c,v 1.2 2000/10/04 04:36:29 bjc Exp $ */ -/* $NetBSD: conf.c,v 1.3 1999/10/23 14:42:21 ragge Exp $ */ +/* $OpenBSD: conf.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: conf.c,v 1.10 2000/06/15 19:53:23 ragge Exp $ */ /* * Copyright (c) 1994 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -38,34 +38,33 @@ #include "../../include/rpb.h" +#include "lib/libkern/libkern.h" + #include "lib/libsa/stand.h" #include "lib/libsa/ufs.h" #include "lib/libsa/nfs.h" +#include "lib/libsa/cd9660.h" #include "vaxstand.h" -int raopen(), rastrategy(); -int hpopen(), hpstrategy(); -int ctuopen(), ctustrategy(); -int tmscpopen(), tmscpstrategy(); -int romopen(), romstrategy(); -int mfmopen(), mfmstrategy(); -int sdopen(), sdstrategy(); -int netopen(), netstrategy(), netclose(); +static int nostrategy(void *, int, daddr_t, size_t, void *, size_t *); struct devsw devsw[]={ SADEV("hp",hpstrategy, hpopen, nullsys, noioctl), - SADEV("qe",netstrategy, netopen, netclose, noioctl), /* DEQNA */ + SADEV("qe",nostrategy, qeopen, qeclose, noioctl), /* DEQNA */ SADEV("ctu",ctustrategy, ctuopen, nullsys, noioctl), SADEV("ra",rastrategy, raopen, nullsys, noioctl), - SADEV("mt",tmscpstrategy, tmscpopen, nullsys, noioctl), + SADEV("mt",rastrategy, raopen, nullsys, noioctl), SADEV("rom",romstrategy, romopen, nullsys, noioctl), - SADEV("rd",mfmstrategy, mfmopen, nullsys, noioctl), + SADEV("hd",mfmstrategy, mfmopen, nullsys, noioctl), SADEV("sd",romstrategy, romopen, nullsys, noioctl), - SADEV("sd",romstrategy, romopen, nullsys, noioctl), /* SDN */ + SADEV("sd",romstrategy, romopen, nullsys, noioctl), /* SDN */ SADEV("st",nullsys, nullsys, nullsys, noioctl), - SADEV("le",netstrategy, netopen, netclose, noioctl), /* LANCE */ - SADEV("ze",netstrategy, netopen, netclose, noioctl), /* SGEC */ + SADEV("le",nostrategy, leopen, leclose, noioctl), /* LANCE */ + SADEV("ze",nostrategy, zeopen, zeclose, noioctl), /* SGEC */ + SADEV("rl",romstrategy, romopen, nullsys, noioctl), + SADEV("de",nostrategy, deopen, declose, noioctl), /* DEUNA */ + SADEV("ni",nostrategy, niopen, nullsys, noioctl), /* DEBNA */ }; int cnvtab[] = { @@ -81,6 +80,9 @@ int cnvtab[] = { BDEV_ST, BDEV_LE, BDEV_ZE, + BDEV_RL, + BDEV_DE, + BDEV_NI, }; int ndevs = (sizeof(devsw)/sizeof(devsw[0])); @@ -88,18 +90,17 @@ int ndevs = (sizeof(devsw)/sizeof(devsw[0])); struct fs_ops file_system[] = { { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat }, { nfs_open, nfs_close, nfs_read, nfs_write, nfs_seek, nfs_stat }, + { cd9660_open, cd9660_close, cd9660_read, cd9660_write, + cd9660_seek, cd9660_stat }, }; int nfsys = (sizeof(file_system) / sizeof(struct fs_ops)); -extern struct netif_driver qe_driver; -extern struct netif_driver le_driver; -extern struct netif_driver ze_driver; - -struct netif_driver *netif_drivers[] = { - &qe_driver, - &le_driver, - &ze_driver, -}; -int n_netif_drivers = (sizeof(netif_drivers) / sizeof(netif_drivers[0])); - +int +nostrategy(void *f, int func, daddr_t dblk, + size_t size, void *buf, size_t *rsize) +{ + *rsize = size; + bzero(buf, size); + return 0; +} diff --git a/sys/arch/vax/boot/boot/consio.c b/sys/arch/vax/boot/boot/consio.c index 39775324c5b..ddfb19c8c5b 100644 --- a/sys/arch/vax/boot/boot/consio.c +++ b/sys/arch/vax/boot/boot/consio.c @@ -1,5 +1,5 @@ -/* $OpenBSD: consio.c,v 1.3 2002/03/14 01:26:47 millert Exp $ */ -/* $NetBSD: consio.c,v 1.11 2000/07/19 00:58:24 matt Exp $ */ +/* $OpenBSD: consio.c,v 1.4 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: consio.c,v 1.13 2002/05/24 21:40:59 ragge Exp $ */ /* * Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -41,68 +41,66 @@ #include "mtpr.h" #include "sid.h" #include "rpb.h" +#include "ka630.h" #include "data.h" void setup(void); -unsigned *bootregs; -extern struct rpb *rpb; -struct bqo *bqo; - -static int (*put_fp)(int) = NULL; +static void (*put_fp)(int) = NULL; static int (*get_fp)(void) = NULL; static int (*test_fp)(void) = NULL; -/* Also added such a thing for KA53 - MK-991208 */ -unsigned char *ka53_conspage; -void ka53_consinit(void); - -int ka53_rom_putchar(int c); -int ka53_rom_getchar(void); -int ka53_rom_testchar(void); - -int pr_putchar(int c); /* putchar() using mtpr/mfpr */ +void pr_putchar(int c); /* putchar() using mtpr/mfpr */ int pr_getchar(void); int pr_testchar(void); -int rom_putchar(int c); /* putchar() using ROM routines */ +void rom_putchar(int c); /* putchar() using ROM routines */ int rom_getchar(void); int rom_testchar(void); -static int rom_putc; /* ROM-address of put-routine */ -static int rom_getc; /* ROM-address of get-routine */ - -/* Location of address of KA630 console page */ -#define NVR_ADRS 0x200B8024 -/* Definitions for various locations in the KA630 console page */ -#define KA630_PUTC_POLL 0x20 -#define KA630_PUTC 0x24 -#define KA630_GETC 0x1C -#define KA630_ROW 0x4C -#define KA630_MINROW 0x4D -#define KA630_MAXROW 0x4E -#define KA630_COL 0x50 -#define KA630_MINCOL 0x51 -#define KA630_MAXCOL 0x52 +int rom_putc; /* ROM-address of put-routine */ +int rom_getc; /* ROM-address of get-routine */ + /* Pointer to KA630 console page, initialized by ka630_consinit */ -unsigned char *ka630_conspage; +unsigned char *ka630_conspage; + /* Function that initializes things for KA630 ROM console I/O */ -void ka630_consinit(void); +void ka630_consinit __P((void)); + /* Functions that use KA630 ROM for console I/O */ -int ka630_rom_putchar(int c); -int ka630_rom_getchar(void); -int ka630_rom_testchar(void); +void ka630_rom_putchar __P((int c)); +int ka630_rom_getchar __P((void)); +int ka630_rom_testchar __P((void)); -putchar(c) - int c; +/* Also added such a thing for KA53 - MK-991208 */ +unsigned char *ka53_conspage; +void ka53_consinit(void); + +void ka53_rom_putchar(int c); +int ka53_rom_getchar(void); +int ka53_rom_testchar(void); + +void vxt_putchar(int c); +int vxt_getchar(void); +int vxt_testchar(void); + +void putchar(int); +int getchar(void); +int testkey(void); +void consinit(void); +void _rtt(void); + +void +putchar(int c) { (*put_fp)(c); if (c == 10) (*put_fp)(13); /* CR/LF */ } -getchar() +int +getchar(void) { int c; @@ -114,7 +112,8 @@ getchar() return c; } -testkey() +int +testkey(void) { return (*test_fp)(); } @@ -124,7 +123,7 @@ testkey() * initializes data which are globally used and is called before main(). */ void -consinit() +consinit(void) { put_fp = pr_putchar; /* Default */ get_fp = pr_getchar; @@ -141,14 +140,6 @@ consinit() */ switch (vax_boardtype) { - case VAX_BTYP_690: - put_fp = rom_putchar; - get_fp = rom_getchar; - test_fp = rom_testchar; - rom_putc = 0x20040058; /* 537133144 */ - rom_getc = 0x20040008; /* 537133064 */ - break; - case VAX_BTYP_43: case VAX_BTYP_410: case VAX_BTYP_420: @@ -159,9 +150,15 @@ consinit() rom_getc = 0x20040044; /* 537133124 */ break; + case VAX_BTYP_VXT: + put_fp = vxt_putchar; + get_fp = vxt_getchar; + test_fp = vxt_testchar; + break; + case VAX_BTYP_630: - ka630_consinit(); - break; + ka630_consinit(); + break; case VAX_BTYP_46: case VAX_BTYP_48: @@ -193,144 +190,82 @@ consinit() /* * putchar() using MTPR */ -pr_putchar(c) - int c; +void +pr_putchar(int c) { - int timeout = 1<<15; /* don't hang the machine! */ - while ((mfpr(PR_TXCS) & GC_RDY) == 0) /* Wait until xmit ready */ + int timeout = 1<<15; /* don't hang the machine! */ + + /* + * On KA88 we may get C-S/C-Q from the console. + * Must obey it. + */ + while (mfpr(PR_RXCS) & GC_DON) { + if ((mfpr(PR_RXDB) & 0x7f) == 19) { + while (1) { + while ((mfpr(PR_RXCS) & GC_DON) == 0) + ; + if ((mfpr(PR_RXDB) & 0x7f) == 17) + break; + } + } + } + + while ((mfpr(PR_TXCS) & GC_RDY) == 0) /* Wait until xmit ready */ if (--timeout < 0) break; - mtpr(c, PR_TXDB); /* xmit character */ + mtpr(c, PR_TXDB); /* xmit character */ } /* * getchar() using MFPR */ -pr_getchar() +int +pr_getchar(void) { - while ((mfpr(PR_RXCS) & GC_DON) == 0); /* wait for char */ + while ((mfpr(PR_RXCS) & GC_DON) == 0) + ; /* wait for char */ return (mfpr(PR_RXDB)); /* now get it */ } -pr_testchar() +int +pr_testchar(void) { if (mfpr(PR_RXCS) & GC_DON) return mfpr(PR_RXDB); else return 0; } -/* - * int rom_putchar (int c) ==> putchar() using ROM-routines - */ -asm(" - .globl _rom_putchar - _rom_putchar: - .word 0x04 # save-mask: R2 - movl 4(ap), r2 # move argument to R2 - jsb *_rom_putc # write it - ret # that's all -"); - - -/* - * int rom_getchar (void) ==> getchar() using ROM-routines - */ -asm(" - .globl _rom_getchar - _rom_getchar: - .word 0x02 # save-mask: R1 - loop: # do { - jsb *_rom_getc # call the getc-routine - tstl r0 # check if char ready - beql loop # } while (R0 == 0) - movl r1, r0 # R1 holds char - ret # we're done - - _rom_testchar: - .word 0 - mnegl $1,r0 - jsb *_rom_getc - tstl r0 - beql 1f - movl r1,r0 - 1: ret -"); - -_rtt() -{ - asm("halt"); -} - - /* * void ka630_rom_getchar (void) ==> initialize KA630 ROM console I/O */ -void ka630_consinit() +void ka630_consinit(void) { - register short *NVR; - register int i; + short *NVR; + int i; - /* Find the console page */ - NVR = (short *) NVR_ADRS; + /* Find the console page */ + NVR = (short *) KA630_NVR_ADRS; - i = *NVR++ & 0xFF; - i |= (*NVR++ & 0xFF) << 8; - i |= (*NVR++ & 0xFF) << 16; - i |= (*NVR++ & 0xFF) << 24; + i = *NVR++ & 0xFF; + i |= (*NVR++ & 0xFF) << 8; + i |= (*NVR++ & 0xFF) << 16; + i |= (*NVR++ & 0xFF) << 24; - ka630_conspage = (char *) i; + ka630_conspage = (char *) i; - /* Go to last row to minimize confusion */ + /* Go to last row to minimize confusion */ ka630_conspage[KA630_ROW] = ka630_conspage[KA630_MAXROW]; ka630_conspage[KA630_COL] = ka630_conspage[KA630_MINCOL]; - /* Use KA630 ROM console I/O routines */ + /* Use KA630 ROM console I/O routines */ put_fp = ka630_rom_putchar; get_fp = ka630_rom_getchar; test_fp = ka630_rom_testchar; } - -/* - * int ka630_rom_getchar (void) ==> getchar() using ROM-routines on KA630 - */ -asm(" - .globl _ka630_rom_getchar - _ka630_rom_getchar: - .word 0x802 # save-mask: R1, R11 - movl _ka630_conspage,r11 # load location of console page - loop630g: # do { - jsb *0x1C(r11) # call the getc-routine (KA630_GETC) - blbc r0, loop630g # } while (R0 == 0) - movl r1, r0 # R1 holds char - ret # we're done - - _ka630_rom_testchar: - .word 0 - movl _ka630_conspage,r3 - jsb *0x1C(r3) - blbc r0,1f - movl r1,r0 - 1: ret -"); /* - * int ka630_rom_putchar (int c) ==> putchar() using ROM-routines on KA630 - */ -asm(" - .globl _ka630_rom_putchar - _ka630_rom_putchar: - .word 0x802 # save-mask: R1, R11 - movl _ka630_conspage,r11 # load location of console page - loop630p: # do { - jsb *0x20(r11) # is rom ready? (KA630_PUTC_POLL) - blbc r0, loop630p # } while (R0 == 0) - movl 4(ap), r1 # R1 holds char - jsb *0x24(r11) # output character (KA630_PUTC) - ret # we're done -"); -/* * void ka53_consinit (void) ==> initialize KA53 ROM console I/O */ void ka53_consinit(void) @@ -342,46 +277,33 @@ void ka53_consinit(void) test_fp = ka53_rom_testchar; } -/* - * int ka53_rom_getchar (void) ==> getchar() using ROM-routines - */ +static volatile int *vxtregs = (int *)0x200A0000; -asm(" - .globl _ka53_rom_getchar - _ka53_rom_getchar: - .word 0x0802 # r1, r11 - movl _ka53_conspage, r11 # load location of console page -1: jsb *0x64(r11) # test for char - blbc r0, 1b # while r0 is 0 - jsb *0x6c(r11) # get char - ret -"); - -asm(" - .globl _ka53_rom_testchar - _ka53_rom_testchar: - .word 0x8 # r3 - movl _ka53_conspage, r3 - jsb *0x64(r3) - blbc r0, 1f - jsb *0x6c(r3) # get it -1: ret -"); - -/* - * int ka53_rom_putchar (int c) ==> putchar() using ROM-routines - */ +#define CH_SR 1 +#define CH_DAT 3 +#define SR_TX_RDY 0x04 +#define SR_RX_RDY 0x01 -asm(" - .globl _ka53_rom_putchar - _ka53_rom_putchar: - .word 0x0802 # r1, r11 - movl _ka53_conspage, r11 -1: jsb *0x20(r11) # ready to write? - blbc r0, 1b # keep going if r0 == 0 - movl 4(ap), r1 # char is in r1 - jsb *0x24(r11) # output char - ret -"); +void +vxt_putchar(int c) +{ + while ((vxtregs[CH_SR] & SR_TX_RDY) == 0) + ; + vxtregs[CH_DAT] = c; +} +int +vxt_getchar(void) +{ + while ((vxtregs[CH_SR] & SR_RX_RDY) == 0) + ; + return vxtregs[CH_DAT]; +} +int +vxt_testchar(void) +{ + if ((vxtregs[CH_SR] & SR_RX_RDY) == 0) + return 0; + return vxtregs[CH_DAT]; +} diff --git a/sys/arch/vax/boot/boot/consio2.S b/sys/arch/vax/boot/boot/consio2.S new file mode 100644 index 00000000000..a8a279e7d87 --- /dev/null +++ b/sys/arch/vax/boot/boot/consio2.S @@ -0,0 +1,128 @@ +/* $OpenBSD: consio2.S,v 1.1 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: consio2.S,v 1.1 2002/02/24 01:04:24 matt Exp $ */ +/* + * Copyright (c) 1994, 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}. + * 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 <machine/asm.h> + +/* + * int rom_putchar (int c) ==> putchar() using ROM-routines + */ +ENTRY(rom_putchar, 0x0004) # save-mask: R2 + movl 4(ap), r2 # move argument to R2 + jsb *_C_LABEL(rom_putc) # write it + ret # that is all + + +/* + * int rom_getchar (void) ==> getchar() using ROM-routines + */ +ENTRY(rom_getchar, 0x0002) # save-mask: R1 +loop: # do { + jsb *_C_LABEL(rom_getc) # call the getc-routine + tstl r0 # check if char ready + beql loop # } while (R0 == 0) + movl r1, r0 # R1 holds char + ret # we are done + +ENTRY(rom_testchar, 0) + mnegl $1,r0 + jsb *_C_LABEL(rom_getc) + tstl r0 + beql 1f + movl r1,r0 +1: ret + +ENTRY(_rtt, 0) + halt + + +/* + * int ka630_rom_getchar (void) ==> getchar() using ROM-routines on KA630 + */ +ENTRY(ka630_rom_getchar, 0x0802) # save-mask: R1, R11 + movl _C_LABEL(ka630_conspage),r11 # load location of console page +1: # do { + jsb *0x1C(r11) # call the getc-routine (KA630_GETC) + blbc r0,1b # } while (R0 == 0) + movl r1,r0 # R1 holds char + ret # we are done + +ENTRY(ka630_rom_testchar, 0) + movl _C_LABEL(ka630_conspage),r3 + jsb *0x1C(r3) + blbc r0,1f + movl r1,r0 +1: ret + +/* + * int ka630_rom_putchar (int c) ==> putchar() using ROM-routines on KA630 + */ +ENTRY(ka630_rom_putchar, 0x802) # save-mask: R1, R11 + movl _C_LABEL(ka630_conspage),r11 + # load location of console page +1: # do { + jsb *0x20(r11) # is rom ready? (KA630_PUTC_POLL) + blbc r0,1b # } while (R0 == 0) + movl 4(ap),r1 # R1 holds char + jsb *0x24(r11) # output character (KA630_PUTC) + ret # we are done + +/* + * int ka53_rom_getchar (void) ==> getchar() using ROM-routines on KA53 + */ +ENTRY(ka53_rom_getchar, 0x0802) # save-mask: R1, R11 + movl _C_LABEL(ka53_conspage),r11 + # load location of console page +1: # do { + jsb *0x64(r11) # test for char + blbc r0,1b # } while (R0 == 0) + jsb *0x6c(r11) # get the char + ret # we are done + +ENTRY(ka53_rom_testchar, 0) + movl _C_LABEL(ka53_conspage),r3 + jsb *0x64(r3) + blbc r0,1f + jsb *0x6c(r3) # get the char +1: ret + +/* + * int ka53_rom_putchar (int c) ==> putchar() using ROM-routines on KA53 + */ +ENTRY(ka53_rom_putchar, 0x0802) # save-mask: R1, R11 + movl _C_LABEL(ka53_conspage),r11 + # load location of console page +1: # do { + jsb *0x20(r11) # is rom ready? + blbc r0,1b # } whi le (R0 == 0) + movl 4(ap),r1 # R1 holds char + jsb *0x24(r11) # output character + ret # we are done diff --git a/sys/arch/vax/boot/boot/ctu.c b/sys/arch/vax/boot/boot/ctu.c index acdd35a7c70..b8a9b863faf 100644 --- a/sys/arch/vax/boot/boot/ctu.c +++ b/sys/arch/vax/boot/boot/ctu.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ctu.c,v 1.2 2002/03/14 01:26:47 millert Exp $ */ -/* $NetBSD: ctu.c,v 1.1 1996/02/17 18:23:20 ragge Exp $ */ +/* $OpenBSD: ctu.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: ctu.c,v 1.3 2000/05/20 13:30:03 ragge Exp $ */ /* * Copyright (c) 1996 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -43,6 +43,10 @@ #include <machine/mtpr.h> #include <machine/rsp.h> +#include "vaxstand.h" + +static short ctu_cksum(unsigned short *, int); + enum tu_state { SC_INIT, SC_READY, @@ -78,15 +82,13 @@ ctuopen(f, adapt, ctlr, unit, part) } int -ctustrategy(ra, func, dblk, size, buf, rsize) - struct ra_softc *ra; +ctustrategy(f, func, dblk, size, buf, rsize) + void *f; int func; daddr_t dblk; - char *buf; - u_int size, *rsize; + void *buf; + size_t size, *rsize; { - int s; - struct rsp *rsp = (struct rsp *)tu_sc.sc_rsp; tu_sc.sc_xfptr = buf; @@ -101,7 +103,7 @@ ctustrategy(ra, func, dblk, size, buf, rsize) rsp->rsp_sw = rsp->rsp_xx1 = rsp->rsp_xx2 = 0; rsp->rsp_cnt = tu_sc.sc_nbytes; rsp->rsp_blk = dblk; - rsp->rsp_sum = ctu_cksum(rsp, 6); + rsp->rsp_sum = ctu_cksum((u_short *)rsp, 6); tu_sc.sc_state = SC_SEND_CMD; while (tu_sc.sc_state != SC_GET_RESP) ctutintr(); @@ -144,7 +146,9 @@ cturintr() break; tu_sc.sc_xfptr[tu_sc.sc_xbytes++] = status; break; - + case SC_READY: + case SC_SEND_CMD: + break; } } @@ -165,6 +169,7 @@ ctutintr() } } +short ctu_cksum(buf, words) unsigned short *buf; int words; diff --git a/sys/arch/vax/boot/boot/data.h b/sys/arch/vax/boot/boot/data.h index 9098d501d70..e91bfaf789d 100644 --- a/sys/arch/vax/boot/boot/data.h +++ b/sys/arch/vax/boot/boot/data.h @@ -1,5 +1,5 @@ -/* $OpenBSD: data.h,v 1.1 2000/04/27 02:26:25 bjc Exp $ */ -/* $NetBSD: data.h,v 1.4 1995/09/16 15:58:57 ragge Exp $ */ +/* $OpenBSD: data.h,v 1.2 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: data.h,v 1.3 2001/07/26 15:05:09 wiz Exp $ */ /* * Copyright (c) 1995 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -38,8 +38,6 @@ -extern unsigned *bootregs; - /* * rpb->iovec gives pointer to this structure. * @@ -67,7 +65,7 @@ struct bqo { long umr_tmpl; /* 4 UNIBUS map register template */ /* offset: 60 */ /* - * the rest is unknown / unneccessary ... + * the rest is unknown / unnecessary ... */ long xxx[6]; /* 24 -- total: 84 bytes */ }; diff --git a/sys/arch/vax/boot/boot/devopen.c b/sys/arch/vax/boot/boot/devopen.c index dac5993df30..5cb9ade2994 100644 --- a/sys/arch/vax/boot/boot/devopen.c +++ b/sys/arch/vax/boot/boot/devopen.c @@ -1,5 +1,5 @@ -/* $OpenBSD: devopen.c,v 1.2 2000/10/04 04:09:01 bjc Exp $ */ -/* $NetBSD: devopen.c,v 1.2 1999/06/30 18:30:42 ragge Exp $ */ +/* $OpenBSD: devopen.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: devopen.c,v 1.10 2002/05/24 21:40:59 ragge Exp $ */ /* * Copyright (c) 1997 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -31,14 +31,20 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/reboot.h> - #include "lib/libsa/stand.h" + +#include "machine/rpb.h" +#include "machine/sid.h" +#include "machine/pte.h" +#define VAX780 1 +#include "machine/ka750.h" + +#include "arch/vax/bi/bireg.h" + #include "vaxstand.h" -#include "rpb.h" -unsigned int opendev; -extern struct rpb *rpb; +int atoi(char *); +int nexaddr, csrbase; int devopen(f, fname, file) @@ -46,21 +52,33 @@ devopen(f, fname, file) const char *fname; char **file; { - int dev, ctlr, unit, part, adapt, i, a[4], x; + int dev, unit, ctlr, part, adapt, i, a[4], x; + int *mapregs; struct devsw *dp; extern int cnvtab[]; - char *s, *c, *u; + char *s, *c; + + part = 0; + + /* + * Adaptor and controller are normally zero (or uninteresting), + * but we need to do some conversion here anyway (if it's a + * manual boot, but that's checked by the device driver). + * Set them to -1 to tell if it's a set number or default. + */ + dev = bootrpb.devtyp; + unit = bootrpb.unit; + adapt = ctlr = -1; - dev = rpb->devtyp; - unit = rpb->unit; - adapt = ctlr = part = 0; + if (dev == BDEV_KDB) + dev = BDEV_UDA; /* use the same driver */ for (i = 0, dp = 0; i < ndevs; i++) if (cnvtab[i] == dev) dp = devsw + i; x = 0; - if ((s = index(fname, '('))) { + if ((s = index((char *)fname, '('))) { *s++ = 0; for (i = 0, dp = devsw; i < ndevs; i++, dp++) @@ -99,29 +117,87 @@ devopen(f, fname, file) if (x > 3) adapt = a[0]; *file = c; - - x = 1; } else { *file = (char *)fname; c = (char *)fname; } - if (!dp->dv_open) + if (!dp->dv_open) { + printf("Can't open device type %d\n", dev); return(ENODEV); + } f->f_dev = dp; - - if (dev > 95) { /* MOP boot over network, root & swap over NFS */ - i = (*dp->dv_open)(f, dp->dv_name); - } else - i = (*dp->dv_open)(f, adapt, ctlr, unit, part); - - if(x == 0) { - dev = rpb->devtyp; /* dv_open may have modified rpb */ - unit = rpb->unit; + bootrpb.unit = unit; + bootrpb.devtyp = dev; + + nexaddr = bootrpb.adpphy; + switch (vax_boardtype) { + case VAX_BTYP_750: + csrbase = (nexaddr == 0xf30000 ? 0xffe000 : 0xfbe000); + if (adapt < 0) + break; + nexaddr = (NEX750 + NEXSIZE * adapt); + csrbase = (adapt == 8 ? 0xffe000 : 0xfbe000); + break; + case VAX_BTYP_780: + case VAX_BTYP_790: + csrbase = 0x2007e000 + 0x40000 * ((nexaddr & 0x1e000) >> 13); + if (adapt < 0) + break; + nexaddr = ((int)NEX780 + NEXSIZE * adapt); + csrbase = 0x2007e000 + 0x40000 * adapt; + break; + case VAX_BTYP_9CC: /* 6000/200 */ + case VAX_BTYP_9RR: /* 6000/400 */ + case VAX_BTYP_1202: /* 6000/500 */ + csrbase = 0; + if (ctlr < 0) + ctlr = bootrpb.adpphy & 15; + if (adapt < 0) + adapt = (bootrpb.adpphy >> 4) & 15; + nexaddr = BI_BASE(adapt, ctlr); + break; + + case VAX_BTYP_8000: + case VAX_BTYP_8800: + case VAX_BTYP_8PS: + csrbase = 0; /* _may_ be a KDB */ + nexaddr = bootrpb.csrphy; + if (ctlr < 0) + break; + if (adapt < 0) + nexaddr = (nexaddr & 0xff000000) + BI_NODE(ctlr); + else + nexaddr = BI_BASE(adapt, ctlr); + break; + case VAX_BTYP_610: + nexaddr = 0; /* No map regs */ + csrbase = 0x20000000; + break; + + case VAX_BTYP_VXT: + nexaddr = 0; + csrbase = bootrpb.csrphy; + break; + default: + nexaddr = 0; /* No map regs */ + csrbase = 0x20000000; + /* Always map in the lowest 4M on qbus-based machines */ + mapregs = (void *)0x20088000; + if (bootrpb.adpphy == 0x20087800) + for (i = 0; i < 8192; i++) + mapregs[i] = PG_V | i; + break; } - opendev = MAKEBOOTDEV(dev, adapt, ctlr, unit, part); - return i; +#ifdef DEV_DEBUG + printf("rpb.type %d rpb.unit %d rpb.csr %lx rpb.adp %lx\n", + bootrpb.devtyp, bootrpb.unit, bootrpb.csrphy, bootrpb.adpphy); + printf("adapter %d ctlr %d unit %d part %d\n", adapt, ctlr, unit, part); + printf("nexaddr %x csrbase %x\n", nexaddr, csrbase); +#endif + + return (*dp->dv_open)(f, adapt, ctlr, unit, part); usage: printf("usage: dev(adapter,controller,unit,partition)file -asd\n"); diff --git a/sys/arch/vax/boot/boot/hp.c b/sys/arch/vax/boot/boot/hp.c index 30f29ae1101..a45e4ae3687 100644 --- a/sys/arch/vax/boot/boot/hp.c +++ b/sys/arch/vax/boot/boot/hp.c @@ -1,5 +1,5 @@ -/* $OpenBSD: hp.c,v 1.1 2000/04/27 02:26:25 bjc Exp $ */ -/* $NetBSD: hp.c,v 1.2 1999/04/01 20:40:07 ragge Exp $ */ +/* $OpenBSD: hp.c,v 1.2 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: hp.c,v 1.5 2000/07/19 00:58:25 matt Exp $ */ /* * Copyright (c) 1994 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -40,7 +40,11 @@ #include "lib/libsa/stand.h" #include "../include/pte.h" -/*#include "../include/macros.h"*/ +#include "../include/rpb.h" +#include "../include/sid.h" +#define VAX780 1 +struct proc; +#include "../include/ka750.h" #include "../mba/mbareg.h" #include "../mba/hpreg.h" @@ -54,113 +58,97 @@ * But it works :) */ -struct hp_softc { - int adapt; - int ctlr; - int unit; - int part; -}; - -struct disklabel hplabel; -struct hp_softc hp_softc; -char io_buf[DEV_BSIZE]; -daddr_t part_offset; - -hpopen(f, adapt, ctlr, unit, part) - struct open_file *f; - int ctlr, unit, part; +static struct disklabel hplabel; +static char io_buf[DEV_BSIZE]; +static int dpart; +static int adpadr, unitadr; + +#define MBA_WCSR(reg, val) \ + ((void)(*(volatile u_int32_t *)((adpadr) + (reg)) = (val))); +#define MBA_RCSR(reg) \ + (*(volatile u_int32_t *)((adpadr) + (reg))) +#define HP_WCSR(reg, val) \ + ((void)(*(volatile u_int32_t *)((unitadr) + (reg)) = (val))); +#define HP_RCSR(reg) \ + (*(volatile u_int32_t *)((unitadr) + (reg))) + +int +hpopen(struct open_file *f, int adapt, int ctlr, int unit, int part) { - struct disklabel *lp; - struct hp_softc *hs; - volatile struct mba_regs *mr; - volatile struct hp_drv *hd; char *msg; - int i,err; - - lp = &hplabel; - hs = &hp_softc; - mr = (void *)mbaaddr[ctlr]; - hd = (void *)&mr->mba_md[unit]; - - if (adapt > nsbi) return(EADAPT); - if (ctlr > nmba) return(ECTLR); - if (unit > MAXMBAU) return(EUNIT); - - bzero(lp, sizeof(struct disklabel)); + int err; + size_t i; + + if (askname == 0) { /* Take info from RPB */ + adpadr = bootrpb.adpphy; + unitadr = adpadr + MUREG(bootrpb.unit, 0); + } else { + adpadr = nexaddr; + unitadr = adpadr + MUREG(unit, 0); + bootrpb.adpphy = adpadr; + bootrpb.unit = unit; + } + bzero(&hplabel, sizeof(struct disklabel)); - lp->d_secpercyl = 32; - lp->d_nsectors = 32; - hs->adapt = adapt; - hs->ctlr = ctlr; - hs->unit = unit; - hs->part = part; + hplabel.d_secpercyl = 32; + hplabel.d_nsectors = 32; /* Set volume valid and 16 bit format; only done once */ - mr->mba_cr = MBACR_INIT; - hd->hp_cs1 = HPCS_PA; - hd->hp_of = HPOF_FMT; + MBA_WCSR(MBA_CR, MBACR_INIT); + HP_WCSR(HP_CS1, HPCS_PA); + HP_WCSR(HP_OF, HPOF_FMT); - err = hpstrategy(hs, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i); + err = hpstrategy(0, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i); if (err) { printf("reading disklabel: %s\n", strerror(err)); return 0; } - msg = getdisklabel(io_buf + LABELOFFSET, lp); + msg = getdisklabel(io_buf + LABELOFFSET, &hplabel); if (msg) printf("getdisklabel: %s\n", msg); - - f->f_devdata = (void *)hs; return 0; } -hpstrategy(hs, func, dblk, size, buf, rsize) - struct hp_softc *hs; - daddr_t dblk; - u_int size, *rsize; - char *buf; - int func; +int +hpstrategy(void *f, int func, daddr_t dblk, + size_t size, void *buf, size_t *rsize) { - volatile struct mba_regs *mr; - volatile struct hp_drv *hd; - struct disklabel *lp; - unsigned int i, pfnum, mapnr, nsize, bn, cn, sn, tn; - - mr = (void *)mbaaddr[hs->ctlr]; - hd = (void *)&mr->mba_md[hs->unit]; - lp = &hplabel; + unsigned int pfnum, mapnr, nsize, bn, cn, sn, tn; pfnum = (u_int)buf >> VAX_PGSHIFT; - for(mapnr = 0, nsize = size; (nsize + VAX_NBPG) > 0; nsize -= VAX_NBPG) - *(int *)&mr->mba_map[mapnr++] = PG_V | pfnum++; + for(mapnr = 0, nsize = size; (nsize + VAX_NBPG) > 0; + nsize -= VAX_NBPG, mapnr++, pfnum++) + MBA_WCSR(MAPREG(mapnr), PG_V | pfnum); - mr->mba_var = ((u_int)buf & VAX_PGOFSET); - mr->mba_bc = (~size) + 1; - bn = dblk + lp->d_partitions[hs->part].p_offset; + MBA_WCSR(MBA_VAR, ((u_int)buf & VAX_PGOFSET)); + MBA_WCSR(MBA_BC, (~size) + 1); + bn = dblk + hplabel.d_partitions[dpart].p_offset; if (bn) { - cn = bn / lp->d_secpercyl; - sn = bn % lp->d_secpercyl; - tn = sn / lp->d_nsectors; - sn = sn % lp->d_nsectors; + cn = bn / hplabel.d_secpercyl; + sn = bn % hplabel.d_secpercyl; + tn = sn / hplabel.d_nsectors; + sn = sn % hplabel.d_nsectors; } else cn = sn = tn = 0; - hd->hp_dc = cn; - hd->hp_da = (tn << 8) | sn; + HP_WCSR(HP_DC, cn); + HP_WCSR(HP_DA, (tn << 8) | sn); +#ifdef notdef if (func == F_WRITE) - hd->hp_cs1 = HPCS_WRITE; + HP_WCSR(HP_CS1, HPCS_WRITE); else - hd->hp_cs1 = HPCS_READ; +#endif + HP_WCSR(HP_CS1, HPCS_READ); - while (mr->mba_sr & MBASR_DTBUSY) + while (MBA_RCSR(MBA_SR) & MBASR_DTBUSY) ; - if (mr->mba_sr & MBACR_ABORT) + if (MBA_RCSR(MBA_SR) & MBACR_ABORT) return 1; - - *rsize = size; + *rsize = size; return 0; } diff --git a/sys/arch/vax/boot/boot/if_de.c b/sys/arch/vax/boot/boot/if_de.c new file mode 100644 index 00000000000..b48d816c75f --- /dev/null +++ b/sys/arch/vax/boot/boot/if_de.c @@ -0,0 +1,290 @@ +/* $OpenBSD: if_de.c,v 1.1 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: if_de.c,v 1.2 2002/05/24 21:41:40 ragge 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. + * + * Standalone routine for the DEUNA Ethernet controller. + */ + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/queue.h> + +#include <net/if.h> + +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/if_ether.h> + +#include <lib/libsa/netif.h> +#include <lib/libsa/stand.h> + +#include <arch/vax/qbus/if_dereg.h> + +#include "arch/vax/include/sid.h" +#include "arch/vax/include/rpb.h" +#include "arch/vax/include/pte.h" + +#include "vaxstand.h" + +static int de_get(struct iodesc *, void *, size_t, time_t); +static int de_put(struct iodesc *, void *, size_t); +static void dewait(char *); + +struct netif_driver de_driver = { + 0, 0, 0, 0, de_get, de_put, +}; + +#define NRCV 8 /* allocate 8 receive descriptors */ +#define NXMT 4 /* and 4 transmit - must be >1 */ + +struct de_cdata { + /* the following structures are always mapped in */ + struct de_pcbb dc_pcbb; /* port control block */ + struct de_ring dc_xrent[NXMT]; /* transmit ring entrys */ + struct de_ring dc_rrent[NRCV]; /* receive ring entrys */ + struct de_udbbuf dc_udbbuf; /* UNIBUS data buffer */ + char dc_rbuf[NRCV][ETHER_MAX_LEN]; + char dc_xbuf[NXMT][ETHER_MAX_LEN]; + /* end mapped area */ +}; + +static volatile struct de_cdata *dc, *pdc; +static volatile char *addr; +static int crx, ctx; +#define DE_WCSR(csr, val) *(volatile u_short *)(addr + (csr)) = (val) +#define DE_WLOW(val) *(volatile u_char *)(addr + DE_PCSR0) = (val) +#define DE_WHIGH(val) *(volatile u_char *)(addr + DE_PCSR0 + 1) = (val) +#define DE_RCSR(csr) *(volatile u_short *)(addr + (csr)) +#define LOWORD(x) ((u_int)(x) & 0xffff) +#define HIWORD(x) (((u_int)(x) >> 16) & 0x3) +#define dereg(x) ((x) & 017777) + +int +deopen(struct open_file *f, int adapt, int ctlr, int unit, int part) +{ + int i, cdata, *map, npgs; + char eaddr[6]; + + /* point to the device in memory */ + if (askname == 0) /* Override if autoboot */ + addr = (char *)bootrpb.csrphy; + else { + addr = (char *)csrbase + dereg(0174510); + bootrpb.csrphy = (int)addr; + } +#ifdef DEV_DEBUG + printf("deopen: csrbase %x addr %p nexaddr %x\n", + csrbase, addr, nexaddr); +#endif + /* reset the device and wait for completion */ + DE_WCSR(DE_PCSR0, 0); + {volatile int j = 100; while (--j);} + DE_WCSR(DE_PCSR0, PCSR0_RSET); + dewait("reset"); + + /* Map in the control structures and buffers */ + dc = alloc(sizeof(struct de_cdata)); + (int)pdc = (int)dc & VAX_PGOFSET; + map = (int *)nexaddr + 512; + npgs = (sizeof(struct de_cdata) >> VAX_PGSHIFT) + 1; + cdata = (int)dc >> VAX_PGSHIFT; + for (i = 0; i < npgs; i++) { + map[i] = PG_V | (cdata + i); + } + + bzero((char *)dc, sizeof(struct de_cdata)); + + /* Tell the DEUNA about our PCB */ + DE_WCSR(DE_PCSR2, LOWORD(pdc)); + DE_WCSR(DE_PCSR3, HIWORD(pdc)); + DE_WLOW(CMD_GETPCBB); + dewait("pcbb"); + + /* Get our address */ + dc->dc_pcbb.pcbb0 = FC_RDPHYAD; + DE_WLOW(CMD_GETCMD); + dewait("read physaddr"); + bcopy((char *)&dc->dc_pcbb.pcbb2, eaddr, 6); + + /* Create and link the descriptors */ + for (i=0; i < NRCV; i++) { + volatile struct de_ring *rp = &dc->dc_rrent[i]; + + rp->r_lenerr = 0; + rp->r_segbl = LOWORD(&pdc->dc_rbuf[i][0]); + rp->r_segbh = HIWORD(&pdc->dc_rbuf[i][0]); + rp->r_flags = RFLG_OWN; + rp->r_slen = ETHER_MAX_LEN; + } + for (i=0; i < NXMT; i++) { + volatile struct de_ring *rp = &dc->dc_xrent[i]; + + rp->r_segbl = LOWORD(&pdc->dc_xbuf[i][0]); + rp->r_segbh = HIWORD(&pdc->dc_xbuf[i][0]); + rp->r_tdrerr = 0; + rp->r_flags = 0; + } + crx = ctx = 0; + + /* set the transmit and receive ring header addresses */ + dc->dc_pcbb.pcbb0 = FC_WTRING; + dc->dc_pcbb.pcbb2 = LOWORD(&pdc->dc_udbbuf); + dc->dc_pcbb.pcbb4 = HIWORD(&pdc->dc_udbbuf); + + dc->dc_udbbuf.b_tdrbl = LOWORD(&pdc->dc_xrent[0]); + dc->dc_udbbuf.b_tdrbh = HIWORD(&pdc->dc_xrent[0]); + dc->dc_udbbuf.b_telen = sizeof (struct de_ring) / sizeof(u_int16_t); + dc->dc_udbbuf.b_trlen = NXMT; + dc->dc_udbbuf.b_rdrbl = LOWORD(&pdc->dc_rrent[0]); + dc->dc_udbbuf.b_rdrbh = HIWORD(&pdc->dc_rrent[0]); + dc->dc_udbbuf.b_relen = sizeof (struct de_ring) / sizeof(u_int16_t); + dc->dc_udbbuf.b_rrlen = NRCV; + + DE_WLOW(CMD_GETCMD); + dewait("wtring"); + + dc->dc_pcbb.pcbb0 = FC_WTMODE; + dc->dc_pcbb.pcbb2 = MOD_DRDC|MOD_TPAD|MOD_HDX; + DE_WLOW(CMD_GETCMD); + dewait("wtmode"); + + DE_WLOW(CMD_START); + dewait("start"); + + DE_WLOW(CMD_PDMD); + dewait("initpoll"); + /* Should be running by now */ + + net_devinit(f, &de_driver, eaddr); + + return 0; +} + +int +de_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timeout) +{ + volatile int to = 100000 * timeout; + int len, csr0; + + if ((csr0 = DE_RCSR(DE_PCSR0)) & PCSR0_INTR) + DE_WHIGH(csr0 >> 8); +retry: + if (to-- == 0) + return 0; + + if (dc->dc_rrent[crx].r_flags & RFLG_OWN) + goto retry; + + if (dc->dc_rrent[crx].r_flags & RFLG_ERRS) + len = 0; + else + len = dc->dc_rrent[crx].r_lenerr & RERR_MLEN; + + if (len > maxlen) + len = maxlen; + if (len) + bcopy((char *)&dc->dc_rbuf[crx][0], pkt, len); + + dc->dc_rrent[crx].r_flags = RFLG_OWN; + dc->dc_rrent[crx].r_lenerr = 0; +#ifdef DEV_DEBUG + printf("Got packet: len %d idx %d maxlen %ld\n", len, crx, maxlen); +#endif + if (++crx == NRCV) + crx = 0; + + if (len == 0) + goto retry; + return len; +} + + +int +de_put(struct iodesc *desc, void *pkt, size_t len) +{ + volatile int to = 100000; + int csr0; + + if ((csr0 = DE_RCSR(DE_PCSR0)) & PCSR0_INTR) + DE_WHIGH(csr0 >> 8); +#ifdef DEV_DEBUG + printf("de_put: len %ld\n", len); +#endif +retry: + if (to-- == 0) + return -1; + + if (dc->dc_xrent[ctx].r_flags & RFLG_OWN) + goto retry; + + bcopy(pkt, (char *)&dc->dc_xbuf[ctx][0], len); + + dc->dc_xrent[ctx].r_slen = len; + dc->dc_xrent[ctx].r_tdrerr = 0; + dc->dc_xrent[ctx].r_flags = XFLG_OWN|XFLG_STP|XFLG_ENP; + + DE_WLOW(CMD_PDMD); + dewait("start"); + + if (++ctx == NXMT) + ctx = 0; + return len; +} + +int +declose(struct open_file *f) +{ + DE_WCSR(DE_PCSR0, PCSR0_RSET); + dewait("close"); + return 0; +} + +void +dewait(char *fn) +{ + int csr0; + +#ifdef DEV_DEBUG + printf("dewait: %s...", fn); +#endif + while ((DE_RCSR(DE_PCSR0) & PCSR0_INTR) == 0) + ; + csr0 = DE_RCSR(DE_PCSR0); + DE_WHIGH(csr0 >> 8); +#ifdef DEV_DEBUG + if (csr0 & PCSR0_PCEI) + printf("failed! CSR0 %x", csr0); + else + printf("done"); + printf(", PCSR1 %x\n", DE_RCSR(DE_PCSR1)); +#endif +} diff --git a/sys/arch/vax/boot/boot/if_le.c b/sys/arch/vax/boot/boot/if_le.c index 31fb9f756b1..2c32d88948c 100644 --- a/sys/arch/vax/boot/boot/if_le.c +++ b/sys/arch/vax/boot/boot/if_le.c @@ -1,5 +1,5 @@ -/* $OpenBSD: if_le.c,v 1.1 2000/04/27 02:26:25 bjc Exp $ */ -/* $NetBSD: if_le.c,v 1.4 1999/08/14 19:41:14 ragge Exp $ */ +/* $OpenBSD: if_le.c,v 1.2 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: if_le.c,v 1.6 2000/05/20 13:30:03 ragge Exp $ */ /* * Copyright (c) 1997, 1999 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -47,13 +47,17 @@ #include <netinet/if_ether.h> #include <../include/sid.h> +#include <../include/rpb.h> #include <lib/libsa/netif.h> +#include <lib/libsa/stand.h> #include <dev/ic/am7990reg.h> +#include "vaxstand.h" + /* - * The following are incorrect. Why doesn't DEC follow its own specs??? + * Buffer sizes. */ #define TLEN 1 #define NTBUF (1 << TLEN) @@ -62,23 +66,16 @@ #define BUFSIZE 1518 #define ETHER_MIN_LEN 64 /* minimum frame length, including CRC */ -#define QW_ALLOC(x) ((alloc((x) + 7) + 7) & ~7) - -int le_probe(), le_match(), le_get(), le_put(); -void le_init(), le_end(); -static void copyin(), copyout(); -struct netif_stats le_stats; +#define QW_ALLOC(x) (((int)alloc((x) + 7) + 7) & ~7) -struct netif_dif le_ifs[] = { -/* dif_unit dif_nsel dif_stats dif_private */ -{ 0, 1, &le_stats, }, -}; - -struct netif_stats le_stats; +static int le_get(struct iodesc *, void *, size_t, time_t); +static int le_put(struct iodesc *, void *, size_t); +static void copyout(void *from, int dest, int len); +static void copyin(int src, void *to, int len); struct netif_driver le_driver = { - "le", le_match, le_probe, le_init, le_get, le_put, le_end, le_ifs, 1, + 0, 0, 0, 0, le_get, le_put, }; /* @@ -98,7 +95,7 @@ struct nireg { volatile u_short ni_rdp; /* data port */ volatile short ni_pad0; volatile short ni_rap; /* register select port */ -} *nireg = (struct nireg *)0x200e0000; +} *nireg; volatile struct buffdesc { @@ -138,27 +135,11 @@ int next_rdesc, next_tdesc; (nireg->ni_rap = port, nireg->ni_rdp) int -le_match(nif, machdep_hint) - struct netif *nif; - void *machdep_hint; -{ - return strcmp(machdep_hint, "le") == 0; -} - -le_probe(nif, machdep_hint) - struct netif *nif; - void *machdep_hint; -{ - return 0; -} - -void -le_init(desc, machdep_hint) - struct iodesc *desc; - void *machdep_hint; +leopen(struct open_file *f, int adapt, int ctlr, int unit, int part) { - int stat, i, *ea; + int i, *ea; volatile int to = 100000; + u_char eaddr[6]; next_rdesc = next_tdesc = 0; @@ -170,7 +151,12 @@ le_init(desc, machdep_hint) } else { *(int *)0x20080014 = 0; /* Be sure we do DMA in low 16MB */ ea = (void *)0x20090000; /* XXX ethernetadressen */ + nireg = (void *)0x200e0000; } + if (askname == 0) /* Override if autoboot */ + nireg = (void *)bootrpb.csrphy; + else /* Tell kernel from where we booted */ + bootrpb.csrphy = (int)nireg; if (vax_boardtype == VAX_BTYP_43) addoff = 0x28000000; @@ -182,12 +168,13 @@ igen: ; for (i = 0; i < 6; i++) - desc->myea[i] = ea[i] & 0377; + eaddr[i] = ea[i] & 0377; if (initblock == NULL) { - initblock = (void *)QW_ALLOC(sizeof(struct initblock)) + addoff; + (void *)initblock = + (char *)QW_ALLOC(sizeof(struct initblock)) + addoff; initblock->ib_mode = LE_MODE_NORMAL; - bcopy(desc->myea, initblock->ib_padr, 6); + bcopy(eaddr, initblock->ib_padr, 6); initblock->ib_ladrf1 = 0; initblock->ib_ladrf2 = 0; @@ -210,7 +197,7 @@ igen: rdesc[i].bd_mcnt = 0; } if (kopiera) - copyout(rdesc, (int)rdesc - (int)initblock, + copyout((void *)rdesc, (int)rdesc - (int)initblock, sizeof(struct buffdesc) * NRBUF); for (i = 0; i < NTBUF; i++) { @@ -221,7 +208,7 @@ igen: tdesc[i].bd_mcnt = 0; } if (kopiera) - copyout(tdesc, (int)tdesc - (int)initblock, + copyout((void *)tdesc, (int)tdesc - (int)initblock, sizeof(struct buffdesc) * NTBUF); } @@ -246,14 +233,13 @@ igen: } LEWRCSR(LE_CSR0, LE_C0_INEA | LE_C0_STRT | LE_C0_IDON); + + net_devinit(f, &le_driver, eaddr); + return 0; } int -le_get(desc, pkt, maxlen, timeout) - struct iodesc *desc; - void *pkt; - int maxlen; - time_t timeout; +le_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timeout) { int csr, len; volatile int to = 100000 * timeout; @@ -267,7 +253,7 @@ retry: if (kopiera) copyin((int)&rdesc[next_rdesc] - (int)initblock, - &rdesc[next_rdesc], sizeof(struct buffdesc)); + (void *)&rdesc[next_rdesc], sizeof(struct buffdesc)); if (rdesc[next_rdesc].bd_adrflg & BR_OWN) goto retry; @@ -281,14 +267,14 @@ retry: copyin((rdesc[next_rdesc].bd_adrflg&0xffffff), pkt, len); else - bcopy((void *)(rdesc[next_rdesc].bd_adrflg&0xffffff) + + bcopy((char *)(rdesc[next_rdesc].bd_adrflg&0xffffff) + addoff, pkt, len); } rdesc[next_rdesc].bd_mcnt = 0; rdesc[next_rdesc].bd_adrflg |= BR_OWN; if (kopiera) - copyout(&rdesc[next_rdesc], (int)&rdesc[next_rdesc] - + copyout((void *)&rdesc[next_rdesc], (int)&rdesc[next_rdesc] - (int)initblock, sizeof(struct buffdesc)); if (++next_rdesc >= NRBUF) next_rdesc = 0; @@ -300,10 +286,7 @@ retry: } int -le_put(desc, pkt, len) - struct iodesc *desc; - void *pkt; - int len; +le_put(struct iodesc *desc, void *pkt, size_t len) { volatile int to = 100000; int csr; @@ -317,21 +300,21 @@ retry: if (kopiera) copyin((int)&tdesc[next_tdesc] - (int)initblock, - &tdesc[next_tdesc], sizeof(struct buffdesc)); + (void *)&tdesc[next_tdesc], sizeof(struct buffdesc)); if (tdesc[next_tdesc].bd_adrflg & BT_OWN) goto retry; if (kopiera) copyout(pkt, (tdesc[next_tdesc].bd_adrflg & 0xffffff), len); else - bcopy(pkt, (void *)(tdesc[next_tdesc].bd_adrflg & 0xffffff) + + bcopy(pkt, (char *)(tdesc[next_tdesc].bd_adrflg & 0xffffff) + addoff, len); tdesc[next_tdesc].bd_bcnt = (len < ETHER_MIN_LEN ? -ETHER_MIN_LEN : -len); tdesc[next_tdesc].bd_mcnt = 0; tdesc[next_tdesc].bd_adrflg |= BT_OWN | BT_STP | BT_ENP; if (kopiera) - copyout(&tdesc[next_tdesc], (int)&tdesc[next_tdesc] - + copyout((void *)&tdesc[next_tdesc], (int)&tdesc[next_tdesc] - (int)initblock, sizeof(struct buffdesc)); LEWRCSR(LE_CSR0, LE_C0_TDMD); @@ -350,17 +333,18 @@ retry: return -1; } -void -le_end() +int +leclose(struct open_file *f) { LEWRCSR(LE_CSR0, LE_C0_STOP); + + return 0; } void -copyout(from, dest, len) - short *from; - int dest, len; +copyout(void *f, int dest, int len) { + short *from = f; short *toaddr; toaddr = (short *)0x20120000 + dest; @@ -373,10 +357,9 @@ copyout(from, dest, len) } void -copyin(src, to, len) - short *to; - int src, len; +copyin(int src, void *f, int len) { + short *to = f; short *fromaddr; fromaddr = (short *)0x20120000 + src; diff --git a/sys/arch/vax/boot/boot/if_ni.c b/sys/arch/vax/boot/boot/if_ni.c new file mode 100644 index 00000000000..76f3477eb65 --- /dev/null +++ b/sys/arch/vax/boot/boot/if_ni.c @@ -0,0 +1,534 @@ +/* $OpenBSD: if_ni.c,v 1.1 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: if_ni.c,v 1.2 2000/07/10 10:40:38 ragge 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. + */ + +/* + * Standalone routine for DEBNA Ethernet controller. + */ + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/socket.h> + +#include <net/if.h> + +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/if_ether.h> + +#include <../include/sid.h> +#include <../include/rpb.h> +#include <../include/pte.h> +#include <../include/macros.h> +#include <../include/mtpr.h> +#include <../include/scb.h> + +#include <lib/libkern/libkern.h> + +#include <lib/libsa/netif.h> +#include <lib/libsa/stand.h> +#include <lib/libsa/net.h> + +#include <arch/vax/bi/bireg.h> + +#include "vaxstand.h" + +#undef NIDEBUG +/* + * 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 1 /* Number of transmit buffer fragments */ +#define NRXBUF 24 /* Receive queue entries */ +#define NBDESCS (NTXBUF + 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 18 /* "" transmit "" */ +#define MSGADD 134 /* "" message "" */ + +#include <arch/vax/bi/if_nireg.h> + + +#define SPTSIZ 16384 /* 8MB */ +#define roundpg(x) (((int)x + VAX_PGOFSET) & ~VAX_PGOFSET) +#define ALLOC(x) \ + allocbase;xbzero((caddr_t)allocbase,x);allocbase+=roundpg(x); +#define nipqb (&gvppqb->nc_pqb) +#define gvp gvppqb +#define NI_WREG(csr, val) *(volatile long *)(niaddr + (csr)) = (val) +#define NI_RREG(csr) *(volatile long *)(niaddr + (csr)) +#define DELAY(x) {volatile int i = x * 3;while (--i);} +#define WAITREG(csr,val) while (NI_RREG(csr) & val); + +static int ni_get(struct iodesc *, void *, size_t, time_t); +static int ni_put(struct iodesc *, void *, size_t); + +static int *syspte, allocbase, niaddr; +static struct ni_gvppqb *gvppqb; +static struct ni_fqb *fqb; +static struct ni_bbd *bbd; +static char enaddr[6]; +static int beenhere = 0; + +struct netif_driver ni_driver = { + 0, 0, 0, 0, ni_get, ni_put, +}; + +static void +xbzero(char *a, int s) +{ + while (s--) + *a++ = 0; +} + +static int +failtest(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("ni: %s\n", str); + return 1; + } + return 0; +} + +static int +INSQTI(void *e, void *h) +{ + int ret; + + while ((ret = insqti(e, h)) == ILCK_FAILED) + ; + return ret; +} + +static void * +REMQHI(void *h) +{ + void *ret; + + while ((ret = remqhi(h)) == (void *)ILCK_FAILED) + ; + return ret; +} + +static void +puton(void *pkt, void *q, int args) +{ + INSQTI(pkt, q); + + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, args); + WAITREG(NI_PCR, PCR_OWN); +} + +static void +remput(void *fq, void *pq, int args) +{ + struct ni_dg *data; + int res; + + while ((data = REMQHI(fq)) == 0) + ; + + res = INSQTI(data, pq); + if (res == Q_EMPTY) { + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, args); + } +} + +static void +insput(void *elem, void *q, int args) +{ + int res; + + res = INSQTI(elem, q); + if (res == Q_EMPTY) { + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, args); + } +} + +int +niopen(struct open_file *f, int adapt, int ctlr, int unit, int part) +{ + struct ni_dg *data; + struct ni_msg *msg; + struct ni_ptdb *ptdb; + int i, va, res; + + if (beenhere++ && askname == 0) + return 0; + + niaddr = nexaddr & ~(BI_NODESIZE - 1); + bootrpb.csrphy = niaddr; + if (adapt >= 0) + bootrpb.adpphy = adapt; + /* + * We need a bunch of memory, take it from our load + * address plus 1M. + */ + allocbase = RELOC + 1024 * 1024; + /* + * First create a SPT for the first 8MB of physmem. + */ + syspte = (int *)ALLOC(SPTSIZ*4); + for (i = 0; i < SPTSIZ; i++) + syspte[i] = PG_V|PG_RW|i; + + + gvppqb = (struct ni_gvppqb *)ALLOC(sizeof(struct ni_gvppqb)); + fqb = (struct ni_fqb *)ALLOC(sizeof(struct ni_fqb)); + bbd = (struct ni_bbd *)ALLOC(sizeof(struct ni_bbd) * NBDESCS); + + /* Init the PQB struct */ + nipqb->np_spt = nipqb->np_gpt = (int)syspte; + nipqb->np_sptlen = nipqb->np_gptlen = SPTSIZ; + nipqb->np_vpqb = (u_int32_t)gvp; + 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; +#ifdef NIDEBUG + printf("niopen: syspte %p gvp %p fqb %p bbd %p\n", + syspte, gvppqb, fqb, bbd); +#endif + + NI_WREG(BIREG_VAXBICSR, NI_RREG(BIREG_VAXBICSR) | BICSR_NRST); + DELAY(500000); + i = 20; + while ((NI_RREG(BIREG_VAXBICSR) & BICSR_BROKE) && --i) + DELAY(500000); +#ifdef NIDEBUG + if (i == 0) { + printf("ni: BROKE bit set after reset\n"); + return 1; + } +#endif + /* Check state */ + if (failtest(NI_PSR, PSR_STATE, PSR_UNDEF, "not undefined state")) + return 1; + + /* 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, (int)gvppqb | PCR_INIT | PCR_OWN); + while (NI_RREG(NI_PCR) & PCR_OWN) + DELAY(100000); + + /* Check state */ + if (failtest(NI_PSR, PSR_INITED, PSR_INITED, "failed initialize")) + return 1; + + 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(NI_PSR, PSR_STATE, PSR_ENABLED, "failed enable")) + return 1; + + NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN); + +#ifdef NIDEBUG + printf("Set up message free queue\n"); +#endif + + /* Set up message free queue */ + va = ALLOC(NMSGBUF * 512); + for (i = 0; i < NMSGBUF; i++) { + 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); + +#ifdef NIDEBUG + printf("Set up xmit queue\n"); +#endif + + /* Set up xmit queue */ + va = ALLOC(NTXBUF * 512); + 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; + data->bufs[0]._offset = 0; + data->bufs[0]._key = 1; + data->nd_cmdref = allocbase; + bbd[i].nb_key = 1; + bbd[i].nb_status = 0; + bbd[i].nb_pte = (int)&syspte[allocbase>>9]; + allocbase += 2048; + data->bufs[0]._index = i; + + 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); + +#ifdef NIDEBUG + printf("recv buffers\n"); +#endif + + /* recv buffers */ + va = ALLOC(NRXBUF * 512); + for (i = 0; i < NRXBUF; i++) { + struct ni_dg *data; + struct ni_bbd *bd; + int idx; + + data = (void *)(va + i * 512); + data->nd_cmdref = allocbase; + data->nd_len = RXADD; + data->nd_opcode = BVP_DGRAMRX; + data->nd_ptdbidx = 2; + data->bufs[0]._key = 1; + + idx = NTXBUF + i; + bd = &bbd[idx]; + bd->nb_pte = (int)&syspte[allocbase>>9]; + allocbase += 2048; + bd->nb_len = 2048; + bd->nb_status = NIBD_VALID; + bd->nb_key = 1; + data->bufs[0]._offset = 0; + data->bufs[0]._len = bd->nb_len; + data->bufs[0]._index = idx; + + 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); + +#ifdef NIDEBUG + printf("Set initial parameters\n"); +#endif + + /* 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; + + puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + + + while ((data = REMQHI(&gvp->nc_forwr)) == 0) + ; + + msg = (struct ni_msg *)data; +#ifdef NIDEBUG + if (msg->nm_opcode2 != NI_WPARAM) { + printf("ni: wrong response code %d\n", msg->nm_opcode2); + insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + } +#endif + bcopy(((struct ni_param *)&msg->nm_text[0])->np_dpa, + enaddr, ETHER_ADDR_LEN); + insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + +#ifdef NIDEBUG + printf("Clear counters\n"); +#endif + + /* 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; + + puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + +#ifdef NIDEBUG + printf("Enable transmit logic\n"); +#endif + + /* 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]; + bzero(ptdb, sizeof(struct ni_ptdb)); + ptdb->np_index = 1; + ptdb->np_fque = 1; + + puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + +#ifdef NIDEBUG + printf("ni: hardware address %s\n", ether_sprintf(enaddr)); + printf("Setting receive parameters\n"); +#endif + msg = REMQHI(&fqb->nf_mforw); + ptdb = (struct ni_ptdb *)&msg->nm_text[0]; + bzero(ptdb, sizeof(struct ni_ptdb)); + msg->nm_opcode = BVP_MSG; + msg->nm_len = 18; + ptdb->np_index = 2; + ptdb->np_fque = 2; + msg->nm_opcode2 = NI_STPTDB; + ptdb->np_type = ETHERTYPE_IP; + ptdb->np_flags = PTDB_UNKN|PTDB_BDC; + memset(ptdb->np_mcast[0], 0xff, ETHER_ADDR_LEN); + ptdb->np_adrlen = 1; + msg->nm_len += 8; + insput(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + +#ifdef NIDEBUG + printf("finished\n"); +#endif + + net_devinit(f, &ni_driver, enaddr); + return 0; +} + +int +ni_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timeout) +{ + struct ni_dg *data; + struct ni_bbd *bd; + int nsec = getsecs() + timeout; + int len, idx; + +loop: while ((data = REMQHI(&gvp->nc_forwr)) == 0 && (nsec > getsecs())) + ; + + if (nsec <= getsecs()) + return 0; + + switch (data->nd_opcode) { + case BVP_DGRAMRX: + idx = data->bufs[0]._index; + bd = &bbd[idx]; + len = data->bufs[0]._len; + if (len > maxlen) + len = maxlen; + bcopy((caddr_t)data->nd_cmdref, pkt, len); + bd->nb_pte = (int)&syspte[data->nd_cmdref>>9]; + data->bufs[0]._len = bd->nb_len = 2048; + data->bufs[0]._offset = 0; + data->bufs[0]._key = 1; + bd->nb_status = NIBD_VALID; + bd->nb_key = 1; + data->nd_len = RXADD; + data->nd_status = 0; + insput(data, &fqb->nf_rforw, + PCR_FREEQNE|PCR_RFREEQ|PCR_OWN); + return len; + + case BVP_DGRAM: + insput(data, &fqb->nf_dforw, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN); + break; + default: + insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + break; + } + + NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~(PSR_OWN|PSR_RSQ)); + goto loop; +} + +int +ni_put(struct iodesc *desc, void *pkt, size_t len) +{ + struct ni_dg *data; + struct ni_bbd *bdp; + + data = REMQHI(&fqb->nf_dforw); +#ifdef NIDEBUG + if (data == 0) { + printf("ni_put: driver problem, data == 0\n"); + return -1; + } +#endif + bdp = &bbd[(data->bufs[0]._index & 0x7fff)]; + bdp->nb_status = NIBD_VALID; + bdp->nb_len = (len < 64 ? 64 : len); + bcopy(pkt, (caddr_t)data->nd_cmdref, len); + data->bufs[0]._offset = 0; + data->bufs[0]._len = bdp->nb_len; + data->nd_opcode = BVP_DGRAM; + data->nd_pad3 = 1; + data->nd_ptdbidx = 1; + data->nd_len = 18; + insput(data, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + return len; +} + +int +niclose(struct open_file *f) +{ + if (beenhere) { + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_OWN|PCR_SHUTDOWN); + WAITREG(NI_PCR, PCR_OWN); + } + return 0; +} diff --git a/sys/arch/vax/boot/boot/if_qe.c b/sys/arch/vax/boot/boot/if_qe.c index a1c1c248907..36a6b30d376 100644 --- a/sys/arch/vax/boot/boot/if_qe.c +++ b/sys/arch/vax/boot/boot/if_qe.c @@ -1,5 +1,5 @@ -/* $OpenBSD: if_qe.c,v 1.2 2002/03/14 03:16:02 millert Exp $ */ -/* $NetBSD: if_qe.c,v 1.2 1999/06/30 18:19:26 ragge Exp $ */ +/* $OpenBSD: if_qe.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: if_qe.c,v 1.3 2000/05/20 13:30:03 ragge Exp $ */ /* * Copyright (c) 1998 Roar Thronæs. All rights reserved. @@ -39,116 +39,103 @@ #include <netinet/in_systm.h> #include <lib/libsa/netif.h> +#include <lib/libsa/stand.h> #include <arch/vax/if/if_qereg.h> -int qe_probe(), qe_match(), qe_get(), qe_put(); -void qe_init(), qe_end(); +#include "../include/rpb.h" -struct netif_stats qe_stats; +#include "vaxstand.h" -struct netif_dif qe_ifs[] = { -/* dif_unit dif_nsel dif_stats dif_private */ -{ 0, 1, &qe_stats, }, -}; - -struct netif_stats qe_stats; +static int qe_get(struct iodesc *desc, void *pkt, size_t, time_t timeout); +static int qe_put(struct iodesc *desc, void *pkt, size_t); +static void qe_init(u_char *eaddr); struct netif_driver qe_driver = { - "qe", qe_match, qe_probe, qe_init, qe_get, qe_put, qe_end, qe_ifs, 1, + 0, 0, 0, 0, qe_get, qe_put, }; -#define PG_V 0x80000000 -#define QBAMAP 0x20088000 +#define NRCV 1 /* Receive descriptors */ +#define NXMT 1 /* Transmit descriptors */ -#define NRCV 1 /* Receive descriptors */ -#define NXMT 1 /* Transmit descriptors */ +#define QE_INTS (QE_RCV_INT | QE_XMIT_INT) +#define MAXPACKETSIZE 0x800 /* Because of (buggy) DEQNA */ -#define QE_INTS (QE_RCV_INT | QE_XMIT_INT) -#define MAXPACKETSIZE 0x800 /* Because of (buggy) DEQNA */ - -struct qe_softc { - struct qe_ring rring[NRCV+2]; /* Receive ring descriptors */ - struct qe_ring tring[NXMT+2]; /* Xmit ring descriptors */ - u_char setup_pkt[16][8]; /* Setup packet */ +static struct qe_softc { + struct qe_ring rring[NRCV+2]; /* Receive ring descriptors */ + struct qe_ring tring[NXMT+2]; /* Xmit ring descriptors */ + u_char setup_pkt[16][8]; /* Setup packet */ char qein[2048], qeout[2048];/* Packet buffers */ -}; +} qe_softc; -static volatile struct qe_softc *sc; +static struct qe_softc *sc = &qe_softc; static int addr; #define QE_WCSR(csr, val) \ - (*((volatile u_short *)(addr + (csr))) = (val)) + (*((volatile u_short *)(addr + (csr))) = (val)) #define QE_RCSR(csr) \ - *((volatile u_short *)(addr + (csr))) -#define DELAY(x) {volatile int i = x;while (--i);} -#define LOWORD(x) ((int)(x) & 0xffff) -#define HIWORD(x) (((int)(x) >> 16) & 0x3f) + *((volatile u_short *)(addr + (csr))) +#define DELAY(x) {volatile int i = x;while (--i);} +#define LOWORD(x) ((int)(x) & 0xffff) +#define HIWORD(x) (((int)(x) >> 16) & 0x3f) +#define qereg(x) ((x) & 017777) int -qe_match(nif, machdep_hint) - struct netif *nif; - void *machdep_hint; -{ - return strcmp(machdep_hint, "qe") == 0; -} +qeopen(struct open_file *f, int adapt, int ctlr, int unit, int part) { + u_char eaddr[6]; + + if (askname == 0) + addr = bootrpb.csrphy; /* Autoboot; use RPB instead */ + else { + addr = 0x20000000; + if (unit == 0) + addr += qereg(0774440); /* XQA0 */ + else if (unit == 1) + addr += qereg(0174460); /* XQB0 */ + else + return ECTLR; + } -int -qe_probe(nif, machdep_hint) - struct netif *nif; - void *machdep_hint; -{ + qe_init(eaddr); + + net_devinit(f, &qe_driver, eaddr); return 0; } void -qe_init(desc, machdep_hint) - struct iodesc *desc; - void *machdep_hint; +qe_init(u_char *eaddr) { - int i,j; - u_int *qm=(u_int *) QBAMAP; - - sc = (void *)alloc(sizeof(struct qe_softc)); - - bzero(sc,sizeof(struct qe_softc)); - - for(i = 0; i < 8192; i++) - qm[i] = PG_V | i; - - /* XXX hardcoded addr */ - addr = (0x20000000 + (0774440 & 017777)); QE_WCSR(QE_CSR_CSR, QE_RESET); QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~QE_RESET); - for (i = 0; i < 6; i++) { - sc->setup_pkt[i][1] = QE_RCSR(i * 2); - sc->setup_pkt[i+8][1] = QE_RCSR(i * 2); + for (i = 0; i < 6; i++) { + sc->setup_pkt[i][1] = QE_RCSR(i * 2); + sc->setup_pkt[i+8][1] = QE_RCSR(i * 2); sc->setup_pkt[i][2] = 0xff; - sc->setup_pkt[i+8][2] = QE_RCSR(i * 2); + sc->setup_pkt[i+8][2] = QE_RCSR(i * 2); for (j=3; j < 8; j++) { - sc->setup_pkt[i][j] = QE_RCSR(i * 2); - sc->setup_pkt[i+8][j] = QE_RCSR(i * 2); + sc->setup_pkt[i][j] = QE_RCSR(i * 2); + sc->setup_pkt[i+8][j] = QE_RCSR(i * 2); } - desc->myea[i] = QE_RCSR(i * 2); + eaddr[i] = QE_RCSR(i * 2); } bzero((caddr_t)sc->rring, sizeof(struct qe_ring)); - sc->rring->qe_buf_len = -64; - sc->rring->qe_addr_lo = (short)((int)sc->setup_pkt); - sc->rring->qe_addr_hi = (short)((int)sc->setup_pkt >> 16); + sc->rring->qe_buf_len = -64; + sc->rring->qe_addr_lo = (short)((int)sc->setup_pkt); + sc->rring->qe_addr_hi = (short)((int)sc->setup_pkt >> 16); bzero((caddr_t)sc->tring, sizeof(struct qe_ring)); - sc->tring->qe_buf_len = -64; - sc->tring->qe_addr_lo = (short)((int)sc->setup_pkt); - sc->tring->qe_addr_hi = (short)((int)sc->setup_pkt >> 16); + sc->tring->qe_buf_len = -64; + sc->tring->qe_addr_lo = (short)((int)sc->setup_pkt); + sc->tring->qe_addr_hi = (short)((int)sc->setup_pkt >> 16); - sc->rring[0].qe_flag = sc->rring[0].qe_status1 = QE_NOTYET; + sc->rring[0].qe_flag = sc->rring[0].qe_status1 = QE_NOTYET; sc->rring->qe_addr_hi |= QE_VALID; - sc->tring[0].qe_flag = sc->tring[0].qe_status1 = QE_NOTYET; + sc->tring[0].qe_flag = sc->tring[0].qe_status1 = QE_NOTYET; sc->tring->qe_addr_hi |= QE_VALID | QE_SETUP | QE_EOMSG; QE_WCSR(QE_CSR_CSR, QE_XMIT_INT | QE_RCV_INT); @@ -164,8 +151,8 @@ qe_init(desc, machdep_hint) QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~(QE_INT_ENABLE|QE_ELOOP)); QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) | QE_ILOOP); - sc->rring[0].qe_addr_lo = (short)((int)sc->qein & 0xffff); - sc->rring[0].qe_addr_hi = (short)((int)sc->qein >> 16); + sc->rring[0].qe_addr_lo = (short)((int)sc->qein & 0xffff); + sc->rring[0].qe_addr_hi = (short)((int)sc->qein >> 16); sc->rring[0].qe_buf_len=-MAXPACKETSIZE/2; sc->rring[0].qe_addr_hi |= QE_VALID; sc->rring[0].qe_flag=sc->rring[0].qe_status1=QE_NOTYET; @@ -176,8 +163,8 @@ qe_init(desc, machdep_hint) sc->rring[1].qe_flag=sc->rring[1].qe_status1=QE_NOTYET; sc->rring[1].qe_status2=1; - sc->tring[0].qe_addr_lo = (short)((int)sc->qeout & 0xffff); - sc->tring[0].qe_addr_hi = (short)((int)sc->qeout >> 16); + sc->tring[0].qe_addr_lo = (short)((int)sc->qeout & 0xffff); + sc->tring[0].qe_addr_hi = (short)((int)sc->qeout >> 16); sc->tring[0].qe_buf_len=0; sc->tring[0].qe_flag=sc->tring[0].qe_status1=QE_NOTYET; sc->tring[0].qe_addr_hi |= QE_EOMSG|QE_VALID; @@ -192,12 +179,7 @@ qe_init(desc, machdep_hint) } int -qe_get(desc, pkt, maxlen, timeout) - struct iodesc *desc; - void *pkt; - int maxlen; - time_t timeout; -{ +qe_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timeout) { int len, j; retry: @@ -215,10 +197,10 @@ retry: if (sc->rring[0].qe_status1 & 0xc000) goto fail; - if (len == 0) + if (len == 0) goto retry; - bcopy((void *)sc->qein,pkt,len); + bcopy((void*)sc->qein,pkt,len); end: @@ -236,17 +218,13 @@ fail: len = -1; } int -qe_put(desc, pkt, len) - struct iodesc *desc; - void *pkt; - int len; -{ +qe_put(struct iodesc *desc, void *pkt, size_t len) { int j; - bcopy(pkt,sc->qeout,len); - sc->tring[0].qe_buf_len=-len/2; - sc->tring[0].qe_flag=sc->tring[0].qe_status1=QE_NOTYET; - sc->tring[1].qe_flag=sc->tring[1].qe_status1=QE_NOTYET; + bcopy(pkt, (char *)sc->qeout, len); + sc->tring[0].qe_buf_len=-len/2; + sc->tring[0].qe_flag=sc->tring[0].qe_status1=QE_NOTYET; + sc->tring[1].qe_flag=sc->tring[1].qe_status1=QE_NOTYET; QE_WCSR(QE_CSR_XMTL, LOWORD(sc->tring)); QE_WCSR(QE_CSR_XMTH, HIWORD(sc->tring)); @@ -255,22 +233,27 @@ qe_put(desc, pkt, len) ; if ((QE_RCSR(QE_CSR_CSR) & QE_XMIT_INT) == 0) { - qe_init(desc,0); + char eaddr[6]; + + qe_init(eaddr); return -1; } QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~QE_RCV_INT); if (sc->tring[0].qe_status1 & 0xc000) { - qe_init(desc,0); + char eaddr[6]; + + qe_init(eaddr); return -1; } return len; } -void -qe_end(nif) - struct netif *nif; +int +qeclose(struct open_file *nif) { QE_WCSR(QE_CSR_CSR, QE_RESET); QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~QE_RESET); + + return 0; } diff --git a/sys/arch/vax/boot/boot/if_ze.c b/sys/arch/vax/boot/boot/if_ze.c index 3f88decb7c6..a58081d38d0 100644 --- a/sys/arch/vax/boot/boot/if_ze.c +++ b/sys/arch/vax/boot/boot/if_ze.c @@ -1,5 +1,5 @@ -/* $OpenBSD: if_ze.c,v 1.3 2002/03/31 01:10:36 hugh Exp $ */ -/* $NetBSD: if_ze.c,v 1.5 1999/08/23 19:09:27 ragge Exp $ */ +/* $OpenBSD: if_ze.c,v 1.4 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: if_ze.c,v 1.12 2002/05/27 16:54:18 ragge Exp $ */ /* * Copyright (c) 1998 James R. Maynard III. All rights reserved. * @@ -42,39 +42,33 @@ #include <netinet/in_systm.h> #include <netinet/if_ether.h> -#include <lib/libkern/libkern.h> #include <lib/libsa/netif.h> #include <lib/libsa/stand.h> +#include <lib/libsa/net.h> #include <arch/vax/if/sgecreg.h> #include "arch/vax/include/sid.h" +#include "arch/vax/include/rpb.h" -int ze_probe(), ze_match(), ze_get(), ze_put(); -void ze_init(), ze_end(); +#include "vaxstand.h" -struct netif_stats ze_stats; - -struct netif_dif ze_ifs[] = { -/* dif_unit dif_nsel dif_stats dif_private */ -{ 0, 1, &ze_stats, }, -}; - -struct netif_stats ze_stats; +static int ze_get(struct iodesc *, void *, size_t, time_t); +static int ze_put(struct iodesc *, void *, size_t); #define ETHER_MIN_LEN 64 #define ETHER_MAX_LEN 1518 struct netif_driver ze_driver = { - "ze", ze_match, ze_probe, ze_init, ze_get, ze_put, ze_end, ze_ifs, 1, + 0, 0, 0, 0, ze_get, ze_put, }; #define NRCV 8 /* allocate 8 receive descriptors */ -#define NXMT 5 /* and 5 transmit - must be >1 */ +#define NXMT 4 /* and 4 transmit - must be >1 */ #define SETUP_FRAME_LEN 128 /* length of the setup frame */ /* allocate a buffer on an octaword boundary */ -#define OW_ALLOC(x) ((void *)((int)(alloc((x) + 15) + 15) & ~15)) +#define OW_ALLOC(x) ((void *)((int)((int)alloc((x) + 15) + 15) & ~15)) static volatile struct zedevice *addr; @@ -83,33 +77,17 @@ struct ze_rdes *ze_rdes_list; /* and receive desc list */ u_char ze_myaddr[ETHER_ADDR_LEN]; /* my Ethernet address */ int -ze_match(nif, machdep_hint) - struct netif *nif; - void *machdep_hint; -{ - return strcmp(machdep_hint, "ze") == 0; -} - -int -ze_probe(nif, machdep_hint) - struct netif *nif; - void *machdep_hint; -{ - return 0; -} - -void -ze_init(desc, machdep_hint) - struct iodesc *desc; - void *machdep_hint; +zeopen(struct open_file *f, int adapt, int ctlr, int unit, int part) { u_long nicsr0_work, *nisa_rom; - int i; - u_char *saved_buf; struct ze_tdes *ze_setup_tdes_list; + int i; /* point to the device in memory */ - addr = (struct zedevice *)0x20008000; + if (askname == 0) /* Override if autoboot */ + addr = (struct zedevice *)bootrpb.csrphy; + else + addr = (struct zedevice *)0x20008000; /* reset the device and wait for completion */ addr->ze_nicsr6 = ZE_NICSR6_MBO | ZE_NICSR6_RE; @@ -117,6 +95,7 @@ ze_init(desc, machdep_hint) ; if (addr->ze_nicsr5 & ZE_NICSR5_SF) { printf("SGEC self-test failed...\n"); + return 1; } /* Get our Ethernet address */ @@ -124,6 +103,10 @@ ze_init(desc, machdep_hint) nisa_rom = (u_long *)0x27800000; for (i=0; i<ETHER_ADDR_LEN; i++) ze_myaddr[i] = nisa_rom[i] & 0377; + } else if (vax_boardtype == VAX_BTYP_VXT) { + nisa_rom = (u_long *)0x200c4000; + for (i=0; i<ETHER_ADDR_LEN; i++) + ze_myaddr[i] = nisa_rom[i] & 0xff; } else { nisa_rom = (u_long *)0x20084000; for (i=0; i<ETHER_ADDR_LEN; i++) @@ -132,7 +115,7 @@ ze_init(desc, machdep_hint) else ze_myaddr[i] = (nisa_rom[i] & 0x0000ff00) >> 8; } - bcopy(ze_myaddr,desc->myea,ETHER_ADDR_LEN); + printf("SGEC: Ethernet address %s\n", ether_sprintf(ze_myaddr)); /* initialize SGEC operating mode */ /* disable interrupts here */ @@ -198,13 +181,16 @@ ze_init(desc, machdep_hint) addr->ze_nicsr6 |= ZE_NICSR6_SR; /* And away-y-y we go! */ + + net_devinit(f, &ze_driver, ze_myaddr); + return 0; } int ze_get(desc, pkt, maxlen, timeout) struct iodesc *desc; void *pkt; - int maxlen; + size_t maxlen; time_t timeout; { int timeout_ctr=100000*timeout, len, rdes; @@ -260,7 +246,7 @@ int ze_put(desc, pkt, len) struct iodesc *desc; void *pkt; - int len; + size_t len; { int timeout=100000; @@ -289,7 +275,7 @@ ze_put(desc, pkt, len) /* Wait for the frame to be sent, but not too long. */ timeout = 100000; - while ((addr->ze_nicsr5 & ZE_NICSR5_TI == 0) && (--timeout>0)) + while (((addr->ze_nicsr5 & ZE_NICSR5_TI) == 0) && (--timeout>0)) ; /* Reset the transmitter interrupt pending flag. */ @@ -300,8 +286,10 @@ ze_put(desc, pkt, len) return -1; } -void -ze_end() +int +zeclose(struct open_file *f) { addr->ze_nicsr6 = ZE_NICSR6_RE; + + return 0; } diff --git a/sys/arch/vax/boot/boot/mfm.c b/sys/arch/vax/boot/boot/mfm.c index 2e22bda7139..761104bd8c1 100644 --- a/sys/arch/vax/boot/boot/mfm.c +++ b/sys/arch/vax/boot/boot/mfm.c @@ -1,5 +1,5 @@ -/* $OpenBSD: mfm.c,v 1.2 2002/03/14 03:16:02 millert Exp $ */ -/* $NetBSD: mfm.c,v 1.2 1997/03/15 13:04:28 ragge Exp $ */ +/* $OpenBSD: mfm.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: mfm.c,v 1.4 2001/07/26 22:55:13 wiz Exp $ */ /* * Copyright (c) 1996 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -69,29 +69,36 @@ struct mfm_softc { int unit; }; -int mfmstrategy(), mfmopen(); -struct disklabel mfmlabel; -struct mfm_softc mfm_softc; -char io_buf[DEV_BSIZE]; +static struct disklabel mfmlabel; +static struct mfm_softc mfm_softc; +static char io_buf[DEV_BSIZE]; /* * These should probably be somewhere else, but ka410 is the only * one with mfm disks anyway... */ -volatile unsigned char *ka410_intreq = (void *)0x2008000f; -volatile unsigned char *ka410_intclr = (void *)0x2008000f; -volatile unsigned char *ka410_intmsk = (void *)0x2008000c; +volatile unsigned char *ka410_intreq = (void*)0x2008000f; +volatile unsigned char *ka410_intclr = (void*)0x2008000f; +volatile unsigned char *ka410_intmsk = (void*)0x2008000c; static volatile struct hdc9224_DKCreg *dkc = (void *) 0x200c0000; static volatile struct hdc9224_UDCreg sreg; /* input */ static volatile struct hdc9224_UDCreg creg; /* output */ +static void sreg_read(void); +static void creg_write(void); +static int mfm_rxprepare(void); +static int mfm_command(int cmd); +static int mfm_rxselect(int unit); +static int mfm_rdselect(int unit); +static int mfm_rxstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize); +static int mfm_rdstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize); /* * we have to wait 0.7 usec between two accesses to any of the * dkc-registers, on a VS2000 with 1 MIPS, this is roughly one * instruction. Thus the loop-overhead will be enough... */ -static int +static void sreg_read() { int i; @@ -103,7 +110,7 @@ sreg_read() *p++ = dkc->dkc_reg; /* dkc_reg auto-increments */ } -static int +static void creg_write() { int i; @@ -120,7 +127,7 @@ creg_write() * * before reading/writing a sector from/to floppy, we use the SEEK/READ_ID * command to place the head at the desired location. Then we wait some - * time before issueing the real command in order to let the drive become + * time before issuing the real command in order to let the drive become * ready... */ int @@ -138,8 +145,7 @@ mfm_rxprepare() } int -mfm_rxselect(unit) - int unit; +mfm_rxselect(int unit) { int error; @@ -164,12 +170,12 @@ mfm_rxselect(unit) */ error = mfm_command(DKC_CMD_DRSEL_RX33 | unit); - if ((error != 0) || (sreg.udc_dstat & UDC_DS_READY == 0)) { + if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) { printf("\nfloppy-drive not ready (new floppy inserted?)\n\n"); creg.udc_rtcnt &= ~UDC_RC_INVRDY; /* clear INVRDY-flag */ error = mfm_command(DKC_CMD_DRSEL_RX33 | unit); - if ((error != 0) || (sreg.udc_dstat & UDC_DS_READY == 0)) { + if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) { printf("diskette not ready(1): %x/%x\n", error, sreg.udc_dstat); printf("floppy-drive offline?\n"); @@ -184,14 +190,14 @@ mfm_rxselect(unit) * now ready should be 0, cause INVRDY is not set * (retrying a command makes this fail...) */ - if ((error != 0) || (sreg.udc_dstat & UDC_DS_READY == 1)) { + if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 1)) { printf("diskette not ready(2): %x/%x\n", error, sreg.udc_dstat); } creg.udc_rtcnt |= UDC_RC_INVRDY; error = mfm_command(DKC_CMD_DRSEL_RX33 | unit); - if ((error != 0) || (sreg.udc_dstat & UDC_DS_READY == 0)) { + if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) { printf("diskette not ready(3): %x/%x\n", error, sreg.udc_dstat); printf("no floppy inserted or floppy-door open\n"); @@ -203,8 +209,7 @@ mfm_rxselect(unit) } int -mfm_rdselect(unit) - int unit; +mfm_rdselect(int unit) { int error; @@ -232,8 +237,7 @@ mfm_rdselect(unit) static int mfm_retry = 0; int -mfm_command(cmd) - int cmd; +mfm_command(int cmd) { int termcode, ready, i; @@ -354,14 +358,16 @@ display_xbn(p) } #endif +int mfmopen(f, adapt, ctlr, unit, part) struct open_file *f; int ctlr, unit, part; { char *msg; struct disklabel *lp = &mfmlabel; - volatile struct mfm_softc *msc = &mfm_softc; - int i, err; + struct mfm_softc *msc = &mfm_softc; + int err; + size_t i; bzero(lp, sizeof(struct disklabel)); msc->unit = unit; @@ -379,12 +385,14 @@ mfmopen(f, adapt, ctlr, unit, part) f->f_devdata = (void *) msc; { +#ifdef verbose int k; unsigned char *ucp; struct mfm_xbn *xp; +#endif /* mfmstrategy(msc, F_READ, -16, 8192, io_buf, &i); */ - mfmstrategy(msc, F_READ, -16, DEV_BSIZE, io_buf, &i); + mfmstrategy(msc, F_READ, -16, 512, io_buf, &i); #ifdef verbose printf("dumping raw disk-block #0:\n"); ucp = io_buf; @@ -446,15 +454,11 @@ mfmopen(f, adapt, ctlr, unit, part) return (0); } -mfm_rxstrategy(msc, func, dblk, size, buf, rsize) - struct mfm_softc *msc; - int func; - daddr_t dblk; - char *buf; - int size, *rsize; -{ +int +mfm_rxstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize) { + struct mfm_softc *msc = f; struct disklabel *lp; - int block, sect, head, cyl, scount, i, cmd, res, sval; + int block, sect, head, cyl, scount, res; lp = &mfmlabel; block = (dblk < 0 ? 0 : dblk + lp->d_partitions[msc->part].p_offset); @@ -484,7 +488,7 @@ mfm_rxstrategy(msc, func, dblk, size, buf, rsize) sect = sect % lp->d_nsectors; /* - * *rsize = 512; /* one sector after the other + * *rsize = 512; one sector after the other * ... */ *rsize = 512 * min(scount, lp->d_nsectors - sect); @@ -528,22 +532,18 @@ mfm_rxstrategy(msc, func, dblk, size, buf, rsize) scount -= *rsize / 512; block += *rsize / 512; - buf += *rsize; + (char *)buf += *rsize; } *rsize = size; return 0; } -mfm_rdstrategy(msc, func, dblk, size, buf, rsize) - struct mfm_softc *msc; - int func; - daddr_t dblk; - char *buf; - int size, *rsize; -{ +int +mfm_rdstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize) { + struct mfm_softc *msc = f; struct disklabel *lp; - int block, sect, head, cyl, scount, i, cmd, res, sval; + int block, sect, head, cyl, scount, cmd, res; lp = &mfmlabel; block = (dblk < 0 ? 0 : dblk + lp->d_partitions[msc->part].p_offset); @@ -618,7 +618,7 @@ mfm_rdstrategy(msc, func, dblk, size, buf, rsize) scount -= *rsize / 512; block += *rsize / 512; - buf += *rsize; + (char *)buf += *rsize; } /* @@ -631,25 +631,26 @@ mfm_rdstrategy(msc, func, dblk, size, buf, rsize) } int -mfmstrategy(msc, func, dblk, size, buf, rsize) - struct mfm_softc *msc; +mfmstrategy(f, func, dblk, size, buf, rsize) + void *f; int func; daddr_t dblk; - char *buf; - int size, *rsize; + void *buf; + size_t size, *rsize; { + struct mfm_softc *msc = f; int res = -1; switch (msc->unit) { case 0: case 1: - res = mfm_rdstrategy(msc, func, dblk, size, buf, rsize); + res = mfm_rdstrategy(f, func, dblk, size, buf, rsize); break; case 2: - res = mfm_rxstrategy(msc, func, dblk, size, buf, rsize); + res = mfm_rxstrategy(f, func, dblk, size, buf, rsize); break; default: - printf("invalid unit %d in mfmstrategy()\n"); + printf("invalid unit %d in mfmstrategy()\n", msc->unit); } return (res); } diff --git a/sys/arch/vax/boot/boot/netio.c b/sys/arch/vax/boot/boot/netio.c index 116e28f2c9c..8a3f5e798c9 100644 --- a/sys/arch/vax/boot/boot/netio.c +++ b/sys/arch/vax/boot/boot/netio.c @@ -1,5 +1,5 @@ -/* $OpenBSD: netio.c,v 1.3 2002/03/14 01:26:47 millert Exp $ */ -/* $NetBSD: netio.c,v 1.4 1999/06/30 18:38:03 ragge Exp $ */ +/* $OpenBSD: netio.c,v 1.4 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: netio.c,v 1.6 2000/05/26 20:16:46 ragge Exp $ */ /*- * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. @@ -53,7 +53,7 @@ * derived from this software without specific prior written permission. * 4. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by Gordon W. Ross + * This product includes software developed by Gordon W. Ross * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -69,7 +69,7 @@ /* * This module implements a "raw device" interface suitable for - * use by the stand-alone I/O library NFS code. This interface + * use by the stand-alone I/O library NFS code. This interface * does not support any "block" access, and exists only for the * purpose of initializing the network interface, getting boot * parameters, and performing the NFS mount. @@ -79,7 +79,7 @@ * find interface - netif_open() * RARP for IP address - rarp_getipaddress() * RPC/bootparams - callrpc(d, RPC_BOOTPARAMS, ...) - * RPC/mountd - nfs_mount(sock, ip, path) + * RPC/mountd - nfs_mount(sock, ip, path) * * the root file handle from mountd is saved in a global * for use by the NFS open code (NFS/lookup). @@ -97,133 +97,34 @@ #include "lib/libsa/netif.h" #include "lib/libsa/bootparam.h" #include "lib/libsa/nfs.h" +#include "lib/libsa/bootp.h" -extern int nfs_root_node[]; /* XXX - get from nfs_mount() */ +#include "vaxstand.h" -struct in_addr myip, rootip, gateip; -n_long netmask; -char rootpath[FNAME_SIZE]; +static struct iodesc desc; +static int inited = 0; -int netdev_sock = -1; -static int open_count; - -int netio_ask = 0; /* default to bootparam, can override */ - -static char input_line[100]; - -int netmountroot(struct open_file *, char *); - -/* - * Called by devopen after it sets f->f_dev to our devsw entry. - * This opens the low-level device and sets f->f_devdata. - */ -int -netopen(f, devname) - struct open_file *f; - char *devname; /* Device part of file name (or NULL). */ -{ - int error = 0; - - /* On first open, do netif open, mount, etc. */ - if (open_count == 0) { - /* Find network interface. */ - if ((netdev_sock = netif_open(devname)) < 0) - return (error=ENXIO); - if ((error = netmountroot(f, devname)) != 0) - return (error); - } - open_count++; - f->f_devdata = nfs_root_node; - return (error); -} - -int -netclose(f) - struct open_file *f; -{ - if(--open_count == 0) - netif_close(netdev_sock); - f->f_devdata = NULL; - return 0; -} - -int -netstrategy(devdata, func, dblk, size, v_buf, rsize) - void *devdata; - int func; - daddr_t dblk; - size_t size; - void *v_buf; - size_t *rsize; +struct iodesc * +socktodesc(sock) { - - *rsize = size; - return EIO; + return &desc; } int -netmountroot(f, devname) - struct open_file *f; - char *devname; /* Device part of file name (or NULL). */ -{ - int error; - struct iodesc *d; - - if (netio_ask) { - get_my_ip: - printf("My IP address? "); - bzero(input_line, sizeof(input_line)); - gets(input_line); - if ((myip.s_addr = inet_addr(input_line)) == - htonl(INADDR_NONE)) { - printf("invalid IP address: %s\n", input_line); - goto get_my_ip; - } - - get_my_netmask: - printf("My netmask? "); - bzero(input_line, sizeof(input_line)); - gets(input_line); - if ((netmask = inet_addr(input_line)) == - htonl(INADDR_NONE)) { - printf("invalid netmask: %s\n", input_line); - goto get_my_netmask; - } +net_devinit(struct open_file *f, struct netif_driver *drv, u_char *eaddr) { + static struct netif best_if; + struct iodesc *s; + int r; - get_my_gateway: - printf("My gateway? "); - bzero(input_line, sizeof(input_line)); - gets(input_line); - if ((gateip.s_addr = inet_addr(input_line)) == - htonl(INADDR_NONE)) { - printf("invalid IP address: %s\n", input_line); - goto get_my_gateway; - } + if (inited) + return 0; + /* find a free socket */ + s = &desc; - get_server_ip: - printf("Server IP address? "); - bzero(input_line, sizeof(input_line)); - gets(input_line); - if ((rootip.s_addr = inet_addr(input_line)) == - htonl(INADDR_NONE)) { - printf("invalid IP address: %s\n", input_line); - goto get_server_ip; - } - - get_server_path: - printf("Server path? "); - bzero(rootpath, sizeof(rootpath)); - gets(rootpath); - if (rootpath[0] == '\0' || rootpath[0] == '\n') - goto get_server_path; - - if ((d = socktodesc(netdev_sock)) == NULL) - return (EMFILE); - - d->myip = myip; - - goto do_nfs_mount; - } + bzero(s, sizeof(*s)); + best_if.nif_driver = drv; + s->io_netif = &best_if; + bcopy(eaddr, s->myea, 6); /* * Get info for NFS boot: our IP address, our hostname, @@ -236,17 +137,12 @@ netmountroot(f, devname) /* Get boot info using BOOTP way. (RFC951, RFC1048) */ printf("Trying BOOTP\n"); - bootp(netdev_sock); + bootp(0); if (myip.s_addr) { printf("Using IP address: %s\n", inet_ntoa(myip)); - printf("myip: %s (%s)", hostname, inet_ntoa(myip)); - if (gateip.s_addr) - printf(", gateip: %s", inet_ntoa(gateip)); - if (netmask) - printf(", mask: %s", intoa(netmask)); - printf("\n"); + printf("myip: %s (%s)\n", hostname, inet_ntoa(myip)); } else #endif /* SUPPORT_BOOTP */ @@ -255,28 +151,43 @@ netmountroot(f, devname) /* Get boot info using RARP and Sun bootparams. */ printf("Trying BOOTPARAMS\n"); - /* Get our IP address. (rarp.c) */ - if (rarp_getipaddress(netdev_sock) == -1) + /* Get our IP address. (rarp.c) */ + if (rarp_getipaddress(0) == -1) return (errno); printf("boot: client IP address: %s\n", inet_ntoa(myip)); /* Get our hostname, server IP address. */ - if (bp_whoami(netdev_sock)) + if (bp_whoami(0)) return (errno); printf("boot: client name: %s\n", hostname); /* Get the root pathname. */ - if (bp_getfile(netdev_sock, "root", &rootip, rootpath)) + if (bp_getfile(0, "root", &rootip, rootpath)) return (errno); #endif } printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath); + f->f_devdata = s; - do_nfs_mount: /* Get the NFS file handle (mount). */ - error = nfs_mount(netdev_sock, rootip, rootpath); + r = nfs_mount(0, rootip, rootpath); + if (r) + return r; + + inited = 1; + return 0; +} - return (error); +ssize_t +netif_put(struct iodesc *desc, void *pkt, size_t len) +{ + return (*desc->io_netif->nif_driver->netif_put)(desc, pkt, len); +} + +ssize_t +netif_get(struct iodesc *desc, void *pkt, size_t len, time_t timo) +{ + return (*desc->io_netif->nif_driver->netif_get)(desc, pkt, len, timo); } diff --git a/sys/arch/vax/boot/boot/ra.c b/sys/arch/vax/boot/boot/ra.c index a0eeaa4cfb0..0bb3f748b21 100644 --- a/sys/arch/vax/boot/boot/ra.c +++ b/sys/arch/vax/boot/boot/ra.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ra.c,v 1.2 2002/03/14 03:16:02 millert Exp $ */ -/* $NetBSD: ra.c,v 1.4 1999/08/07 11:19:04 ragge Exp $ */ +/* $OpenBSD: ra.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: ra.c,v 1.11 2002/06/04 15:13:55 ragge Exp $ */ /* * Copyright (c) 1995 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -41,7 +41,7 @@ #include "lib/libsa/stand.h" #include "../include/pte.h" -#include "../include/sid.h" +#include "../include/rpb.h" #include "arch/vax/mscp/mscp.h" #include "arch/vax/mscp/mscpreg.h" @@ -51,9 +51,7 @@ #include "vaxstand.h" -static command(int); - - +static void command(int, int); /* * These routines for RA disk standalone boot is wery simple, @@ -63,70 +61,80 @@ static command(int); * But it works :) */ -struct ra_softc { - int udaddr; - int ubaddr; - int part; - int unit; - unsigned short *ra_ip; - unsigned short *ra_sa; - unsigned short *ra_sw; -}; - -volatile struct uda { - struct mscp_1ca uda_ca; /* communications area */ - struct mscp uda_rsp; /* response packets */ - struct mscp uda_cmd; /* command packets */ +static volatile struct uda { + struct mscp_1ca uda_ca; /* communications area */ + struct mscp uda_rsp; /* response packets */ + struct mscp uda_cmd; /* command packets */ } uda; -volatile struct uda *ubauda; -struct disklabel ralabel; -struct ra_softc ra_softc; -char io_buf[DEV_BSIZE]; +static struct disklabel ralabel; +static char io_buf[DEV_BSIZE]; +static int dpart, dunit, remap, is_tmscp, curblock; +static volatile u_short *ra_ip, *ra_sa, *ra_sw; +static volatile u_int *mapregs; -raopen(f, adapt, ctlr, unit, part) - struct open_file *f; - int ctlr, unit, part; +int +raopen(struct open_file *f, int adapt, int ctlr, int unit, int part) { - char *msg; - struct disklabel *lp = &ralabel; - volatile struct ra_softc *ra = &ra_softc; - volatile u_int *nisse; + static volatile struct uda *ubauda; unsigned short johan, johan2; - int i,err, udacsr; + size_t i; + int err; + char *msg; #ifdef DEV_DEBUG printf("raopen: adapter %d ctlr %d unit %d part %d\n", adapt, ctlr, unit, part); + printf("raopen: csrbase %x nexaddr %x\n", csrbase, nexaddr); #endif - bzero(lp, sizeof(struct disklabel)); - ra->unit = unit; - ra->part = part; - if (vax_cputype != VAX_8200) { - if (adapt > nuba) - return(EADAPT); - if (ctlr > nuda) - return(ECTLR); - nisse = ((u_int *)ubaaddr[adapt]) + 512; - nisse[494] = PG_V | (((u_int)&uda) >> 9); - nisse[495] = nisse[494] + 1; - udacsr = (int)uioaddr[adapt] + udaaddr[ctlr]; - ubauda = (void *)0x3dc00 + (((u_int)(&uda))&0x1ff); + bzero(&ralabel, sizeof(struct disklabel)); + bzero((void *)&uda, sizeof(struct uda)); + if (bootrpb.devtyp == BDEV_TK) + is_tmscp = 1; + dunit = unit; + dpart = part; + if (ctlr < 0) + ctlr = 0; + remap = csrbase && nexaddr; + curblock = 0; + if (csrbase) { /* On a uda-alike adapter */ + if (askname == 0) { + csrbase = bootrpb.csrphy; + dunit = bootrpb.unit; + nexaddr = bootrpb.adpphy; + } else + csrbase += (ctlr ? 000334 : 012150); + ra_ip = (short *)csrbase; + ra_sa = ra_sw = (short *)csrbase + 1; + if (nexaddr) { /* have map registers */ + mapregs = (int *)nexaddr + 512; + mapregs[494] = PG_V | (((u_int)&uda) >> 9); + mapregs[495] = mapregs[494] + 1; + (char *)ubauda = (char *)0x3dc00 + + (((u_int)(&uda))&0x1ff); + } else + ubauda = &uda; johan = (((u_int)ubauda) & 0xffff) + 8; - johan2 = 3; - ra->ra_ip = (short *)udacsr; - ra->ra_sa = ra->ra_sw = (short *)udacsr + 1; - ra->udaddr = uioaddr[adapt] + udaaddr[ctlr]; - ra->ubaddr = (int)ubaaddr[adapt]; - *ra->ra_ip = 0; /* Start init */ + johan2 = (((u_int)ubauda) >> 16) & 077; + *ra_ip = 0; /* Start init */ + bootrpb.csrphy = csrbase; } else { - paddr_t kdaddr = (paddr_t)biaddr[adapt] + BI_NODE(ctlr); + paddr_t kdaddr; volatile int *w; volatile int i = 10000; - ra->ra_ip = (short *)(kdaddr + KDB_IP); - ra->ra_sa = (short *)(kdaddr + KDB_SA); - ra->ra_sw = (short *)(kdaddr + KDB_SW); + if (askname == 0) { + nexaddr = bootrpb.csrphy; + dunit = bootrpb.unit; + } else { + nexaddr = (bootrpb.csrphy & ~(BI_NODESIZE - 1)) + KDB_IP; + bootrpb.csrphy = nexaddr; + } + + kdaddr = nexaddr & ~(BI_NODESIZE - 1); + ra_ip = (short *)(kdaddr + KDB_IP); + ra_sa = (short *)(kdaddr + KDB_SA); + ra_sw = (short *)(kdaddr + KDB_SW); johan = ((u_int)&uda.uda_ca.ca_rspdsc) & 0xffff; johan2 = (((u_int)&uda.uda_ca.ca_rspdsc) & 0xffff0000) >> 16; w = (int *)(kdaddr + BIREG_VAXBICSR); @@ -138,45 +146,70 @@ raopen(f, adapt, ctlr, unit, part) ubauda = &uda; } +#ifdef DEV_DEBUG + printf("start init\n"); +#endif /* Init of this uda */ - while ((*ra->ra_sa & MP_STEP1) == 0) + while ((*ra_sa & MP_STEP1) == 0) ; #ifdef DEV_DEBUG printf("MP_STEP1..."); #endif - *ra->ra_sw = 0x8000; - while ((*ra->ra_sa & MP_STEP2) == 0) + *ra_sw = 0x8000; + while ((*ra_sa & MP_STEP2) == 0) ; #ifdef DEV_DEBUG printf("MP_STEP2..."); #endif - *ra->ra_sw = johan; - while ((*ra->ra_sa & MP_STEP3) == 0) + *ra_sw = johan; + while ((*ra_sa & MP_STEP3) == 0) ; #ifdef DEV_DEBUG printf("MP_STEP3..."); #endif - *ra->ra_sw = johan2; - while ((*ra->ra_sa & MP_STEP4) == 0) + *ra_sw = johan2; + while ((*ra_sa & MP_STEP4) == 0) ; #ifdef DEV_DEBUG printf("MP_STEP4\n"); #endif - *ra->ra_sw = 0x0001; + *ra_sw = 0x0001; uda.uda_ca.ca_rspdsc = (int)&ubauda->uda_rsp.mscp_cmdref; uda.uda_ca.ca_cmddsc = (int)&ubauda->uda_cmd.mscp_cmdref; + if (is_tmscp) { + uda.uda_cmd.mscp_un.un_seq.seq_addr = + (long *)&uda.uda_ca.ca_cmddsc; + uda.uda_rsp.mscp_un.un_seq.seq_addr = + (long *)&uda.uda_ca.ca_rspdsc; + uda.uda_cmd.mscp_vcid = 1; + uda.uda_cmd.mscp_un.un_sccc.sccc_ctlrflags = 0; + } - command(M_OP_SETCTLRC); - uda.uda_cmd.mscp_unit = ra->unit; - command(M_OP_ONLINE); + command(M_OP_SETCTLRC, 0); + uda.uda_cmd.mscp_unit = dunit; + command(M_OP_ONLINE, 0); + if (is_tmscp) { + if (part) { +#ifdef DEV_DEBUG + printf("Repos of tape..."); +#endif + uda.uda_cmd.mscp_un.un_seq.seq_buffer = part; + command(M_OP_POS, 0); + uda.uda_cmd.mscp_un.un_seq.seq_buffer = 0; +#ifdef DEV_DEBUG + printf("Done!\n"); +#endif + } + return 0; + } #ifdef DEV_DEBUG printf("reading disklabel\n"); #endif - err = rastrategy(ra,F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i); + err = rastrategy(0, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i); if(err){ printf("reading disklabel: %s\n",strerror(err)); return 0; @@ -185,19 +218,21 @@ raopen(f, adapt, ctlr, unit, part) #ifdef DEV_DEBUG printf("getting disklabel\n"); #endif - msg = getdisklabel(io_buf+LABELOFFSET, lp); + msg = getdisklabel(io_buf+LABELOFFSET, &ralabel); if (msg) printf("getdisklabel: %s\n", msg); - f->f_devdata = (void *)ra; return(0); } -static -command(cmd) +static void +command(int cmd, int arg) { - volatile int hej; + volatile short hej; + int to; + +igen: uda.uda_cmd.mscp_opcode = cmd; + uda.uda_cmd.mscp_modifier = arg; - uda.uda_cmd.mscp_opcode = cmd; uda.uda_cmd.mscp_msglen = MSCP_MSGLEN; uda.uda_rsp.mscp_msglen = MSCP_MSGLEN; uda.uda_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT; @@ -205,51 +240,87 @@ command(cmd) #ifdef DEV_DEBUG printf("sending cmd %x...", cmd); #endif - hej = *ra_softc.ra_ip; - while(uda.uda_ca.ca_rspdsc<0) - ; + hej = *ra_ip; + to = 10000000; + while (uda.uda_ca.ca_rspdsc < 0) { +// if (uda.uda_ca.ca_cmdint) +// uda.uda_ca.ca_cmdint = 0; + if (--to < 0) { +#ifdef DEV_DEBUG + printf("timing out, retry\n"); +#endif + goto igen; + } + } #ifdef DEV_DEBUG printf("sent.\n"); #endif } -rastrategy(ra, func, dblk, size, buf, rsize) - struct ra_softc *ra; - int func; - daddr_t dblk; - char *buf; - u_int size, *rsize; +int +rastrategy(void *f, int func, daddr_t dblk, + size_t size, void *buf, size_t *rsize) { - volatile u_int *ptmapp; - struct disklabel *lp; - u_int i, j, pfnum, mapnr, nsize; - volatile int hej; - - if (vax_cputype != VAX_8200) { - ptmapp = ((u_int *)ra->ubaddr) + 512; + u_int pfnum, mapnr, nsize; +#ifdef DEV_DEBUG + printf("rastrategy: buf %p remap %d is_tmscp %d\n", + buf, remap, is_tmscp); +#endif + if (remap) { pfnum = (u_int)buf >> VAX_PGSHIFT; for(mapnr = 0, nsize = size; (nsize + VAX_NBPG) > 0; nsize -= VAX_NBPG) - ptmapp[mapnr++] = PG_V | pfnum++; + mapregs[mapnr++] = PG_V | pfnum++; uda.uda_cmd.mscp_seq.seq_buffer = ((u_int)buf) & 0x1ff; } else uda.uda_cmd.mscp_seq.seq_buffer = ((u_int)buf); - lp = &ralabel; - uda.uda_cmd.mscp_seq.seq_lbn = - dblk + lp->d_partitions[ra->part].p_offset; - uda.uda_cmd.mscp_seq.seq_bytecount = size; - uda.uda_cmd.mscp_unit = ra->unit; + if (is_tmscp) { + int i; + + /* + * First position tape. Remember where we are. + */ + if (dblk < curblock) { + uda.uda_cmd.mscp_seq.seq_bytecount = curblock - dblk; + command(M_OP_POS, 12); /* 12 == step block backward */ + } else { + uda.uda_cmd.mscp_seq.seq_bytecount = dblk - curblock; + command(M_OP_POS, 4); /* 4 == step block forward */ + } + curblock = size/512 + dblk; + + /* + * Read in the number of blocks we need. + * Why doesn't read of multiple blocks work????? + */ + for (i = 0 ; i < size/512 ; i++) { + uda.uda_cmd.mscp_seq.seq_lbn = 1; + uda.uda_cmd.mscp_seq.seq_bytecount = 512; + uda.uda_cmd.mscp_seq.seq_buffer = + (((u_int)buf) & 0x1ff) + i * 512; + uda.uda_cmd.mscp_unit = dunit; + command(M_OP_READ, 0); + } + } else { + + uda.uda_cmd.mscp_seq.seq_lbn = + dblk + ralabel.d_partitions[dpart].p_offset; + uda.uda_cmd.mscp_seq.seq_bytecount = size; + uda.uda_cmd.mscp_unit = dunit; #ifdef DEV_DEBUG - printf("rastrategy: blk 0x%lx count %lx unit %lx\n", - uda.uda_cmd.mscp_seq.seq_lbn, size, ra->unit); + printf("rastrategy: blk 0x%lx count %lx unit %x\n", + uda.uda_cmd.mscp_seq.seq_lbn, size, dunit); +#endif +#ifdef notdef + if (func == F_WRITE) + command(M_OP_WRITE, 0); + else #endif - if (func == F_WRITE) - command(M_OP_WRITE); - else - command(M_OP_READ); + command(M_OP_READ, 0); + } *rsize = size; return 0; diff --git a/sys/arch/vax/boot/boot/rom.c b/sys/arch/vax/boot/boot/rom.c index 2d3f0c3a6b5..f6fb3a7b271 100644 --- a/sys/arch/vax/boot/boot/rom.c +++ b/sys/arch/vax/boot/boot/rom.c @@ -1,5 +1,5 @@ -/* $OpenBSD: rom.c,v 1.3 2002/03/14 03:16:02 millert Exp $ */ -/* $NetBSD: rom.c,v 1.1 1996/08/02 11:22:21 ragge Exp $ */ +/* $OpenBSD: rom.c,v 1.4 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: rom.c,v 1.3 2000/07/19 00:58:25 matt Exp $ */ /* * Copyright (c) 1996 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -50,42 +50,32 @@ #include "data.h" #include "vaxstand.h" -extern unsigned *bootregs; -extern struct rpb *rpb; +static struct disklabel romlabel; +static char io_buf[DEV_BSIZE]; +static struct bqo *bqo; +static int dpart, dunit; -struct rom_softc { - int part; - int unit; -}; - -int romstrategy(), romopen(); -struct disklabel romlabel; -struct rom_softc rom_softc; -char io_buf[DEV_BSIZE]; - -romopen(f, adapt, ctlr, unit, part) - struct open_file *f; - int ctlr, unit, part; +int +romopen(struct open_file *f, int adapt, int ctlr, int unit, int part) { char *msg; struct disklabel *lp = &romlabel; - volatile struct rom_softc *rsc = &rom_softc; - int i,err; + size_t i; + int err; - bootregs[11] = XXRPB; - bqo = (void *)rpb->iovec; + bqo = (void *)bootrpb.iovec; - if (rpb->unit > 0 && (rpb->unit % 100) == 0) { - printf ("changing rpb->unit from %d ", rpb->unit); - rpb->unit /= 100; - printf ("to %d\n", rpb->unit); + if (bootrpb.unit > 0 && (bootrpb.unit % 100) == 0) { + printf ("changing bootrpb.unit from %d ", bootrpb.unit); + bootrpb.unit /= 100; + printf ("to %d\n", bootrpb.unit); } bzero(lp, sizeof(struct disklabel)); - rsc->unit = unit; - rsc->part = part; + dunit = unit; + dpart = part; - err = romstrategy(rsc, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i); + err = romstrategy(0, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i); if (err) { printf("reading disklabel: %s\n",strerror(err)); return 0; @@ -93,29 +83,33 @@ romopen(f, adapt, ctlr, unit, part) msg = getdisklabel(io_buf+LABELOFFSET, lp); if (msg) printf("getdisklabel: %s\n",msg); - f->f_devdata = (void *)rsc; return(0); } -romstrategy (rsc, func, dblk, size, buf, rsize) - struct rom_softc *rsc; - int func; +int romwrite_uvax(int, int, void *, struct rpb *); +int romread_uvax(int, int, void *, struct rpb *); + +int +romstrategy (f, func, dblk, size, buf, rsize) + void *f; + int func; daddr_t dblk; - char *buf; - int size, *rsize; + size_t size; + void *buf; + size_t *rsize; { struct disklabel *lp; int block; lp = &romlabel; - block = dblk + lp->d_partitions[rsc->part].p_offset; - if (rsc->unit >= 0 && rsc->unit < 10) - rpb->unit = rsc->unit; + block = dblk + lp->d_partitions[dpart].p_offset; + if (dunit >= 0 && dunit < 10) + bootrpb.unit = dunit; if (func == F_WRITE) - romwrite_uvax(block, size, buf, bootregs); + romwrite_uvax(block, size, buf, &bootrpb); else - romread_uvax(block, size, buf, bootregs); + romread_uvax(block, size, buf, &bootrpb); *rsize = size; return 0; diff --git a/sys/arch/vax/boot/boot/tmscp.c b/sys/arch/vax/boot/boot/tmscp.c index ec0f185a01c..ff466c8c15b 100644 --- a/sys/arch/vax/boot/boot/tmscp.c +++ b/sys/arch/vax/boot/boot/tmscp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tmscp.c,v 1.2 2002/03/14 03:16:02 millert Exp $ */ +/* $OpenBSD: tmscp.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */ /* $NetBSD: tmscp.c,v 1.3 1999/06/30 18:19:26 ragge Exp $ */ /* * Copyright (c) 1995 Ludd, University of Lule}, Sweden. @@ -95,11 +95,11 @@ tmscpopen(f, adapt, ctlr, unit, part) ra->udaddr=uioaddr[adapt]+tmsaddr; ra->ubaddr=(int)ubaaddr[adapt]; ra->unit=unit; - udacsr=(void *)ra->udaddr; + udacsr=(void*)ra->udaddr; nisse=((u_int *)ubaaddr[adapt]) + 512; nisse[494]=PG_V|(((u_int)&uda)>>9); nisse[495]=nisse[494]+1; - ubauda=(void *)0x3dc00+(((u_int)(&uda))&0x1ff); + ubauda=(void*)0x3dc00+(((u_int)(&uda))&0x1ff); /* * Init of this tmscp ctlr. @@ -165,7 +165,7 @@ tmscpstrategy(ra, func, dblk, size, buf, rsize) u_int size, *rsize; { u_int i,j,pfnum, mapnr, nsize, bn, cn, sn, tn; - volatile struct udadevice *udadev=(void *)ra->udaddr; + volatile struct udadevice *udadev=(void*)ra->udaddr; volatile u_int *ptmapp = (u_int *)ra->ubaddr + 512; volatile int hej; diff --git a/sys/arch/vax/boot/boot/vaxstand.h b/sys/arch/vax/boot/boot/vaxstand.h new file mode 100644 index 00000000000..8d48a376189 --- /dev/null +++ b/sys/arch/vax/boot/boot/vaxstand.h @@ -0,0 +1,85 @@ +/* $OpenBSD: vaxstand.h,v 1.1 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: vaxstand.h,v 1.5 2000/06/15 19:53:23 ragge Exp $ */ +/* + * Copyright (c) 1994 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}. + * 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. + */ + +/* Variables used in autoconf */ +extern int askname; +extern struct rpb bootrpb; +extern int csrbase, nexaddr; + +/* devsw type definitions, used in bootxx and conf */ +#define SADEV(name,strategy,open,close,ioctl) \ + { (char *)name, \ + (int(*)(void *, int ,daddr_t , size_t, void *, size_t *))strategy, \ + (int(*)(struct open_file *, ...))open, \ + (int(*)(struct open_file *))close, \ + (int(*)(struct open_file *,u_long, void *))ioctl} + +#define SDELAY(count) {volatile int i; for (i = count; i; i--);} +/* + * Easy-to-use definitions + */ +#ifndef min +#define min(x,y) (x < y ? x : y) +#endif /* min */ + +struct netif_driver; + +char *index(char *, int); +int net_devinit(struct open_file *f, struct netif_driver *drv, u_char *eaddr); + +/* device calls */ +int raopen(struct open_file *, int, int, int, int), + rastrategy(void *, int, daddr_t, size_t, void *, size_t *); +int hpopen(struct open_file *, int, int, int, int), + hpstrategy(void *, int, daddr_t, size_t, void *, size_t *); +int ctuopen(struct open_file *, int, int, int, int), + ctustrategy(void *, int, daddr_t, size_t, void *, size_t *); +int tmscpopen(struct open_file *, int, int, int, int), + tmscpstrategy(void *, int, daddr_t, size_t, void *, size_t *); +int romopen(struct open_file *, int, int, int, int), + romstrategy(void *, int, daddr_t, size_t, void *, size_t *); +int mfmopen(struct open_file *, int, int, int, int), + mfmstrategy(void *, int, daddr_t, size_t, void *, size_t *); +int sdopen(struct open_file *), + sdstrategy(void *, int, daddr_t, size_t, void *, size_t *); +int leopen(struct open_file *, int, int, int, int), + leclose(struct open_file *); +int qeopen(struct open_file *, int, int, int, int), + qeclose(struct open_file *); +int zeopen(struct open_file *, int, int, int, int), + zeclose(struct open_file *); +int deopen(struct open_file *, int, int, int, int), + declose(struct open_file *); +int niopen(struct open_file *, int, int, int, int), + niclose(struct open_file *); +int netopen(struct open_file *), netclose(struct open_file *); + diff --git a/sys/arch/vax/boot/boot/version b/sys/arch/vax/boot/boot/version new file mode 100644 index 00000000000..4e5f4b0b4c1 --- /dev/null +++ b/sys/arch/vax/boot/boot/version @@ -0,0 +1,31 @@ +$OpenBSD: version,v 1.1 2002/06/11 09:36:23 hugh Exp $ +$NetBSD: version,v 1.4 2001/11/09 19:53:15 scw Exp $ + +NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this +file is important - make sure the entries are appended on end, last item +is taken as the current. + +1.0: Initial import. +1.1: Bunch of small fixes to make boot work on most VAXen. +1.2: Use common routines to identify cpu type. + Set up a SCB to be able to handle clock interrupts in the boot program. + Now timer countdown should work on all types of vaxen. +1.3: Unify the ra and tmscp driver. + Standalone driver for the Digital Equipment Unibus Network Adapter + (DEUNA). This allows 11/750 owners to install from a single TU58 + cassette. + Adopt to the RPB changes. Complete change of how network devices are + handled. No more hacks to find bus addresses. +1.5: Standalone device driver for DEBNx (ni) ethernet controllers. +1.6: Add support for VAX 6000 + VAX 8000. Tweak console routines. + Create a fake RPB if either netbooted (on machine without RPB) or + loaded from console storage (without VMB intervention). +1.7: Add support for loading a 2nd stage boot in either a.out or ELF. + Add support for loading a 2nd stage boot directly to it's desired + address if possible. + Cleanup use of u_int/size_t. +1.8: Switch to loadfile instead of exec. Now we can load a.out or ELF + kernels. +1.9: Support verbose/quiet boot. +1.10: loadfile() update: ELF symbols no longer need backward seeks. +1.11: loadfile() update to avoid backwards seeks for ELF Program Headers. diff --git a/sys/arch/vax/boot/common/romread.s b/sys/arch/vax/boot/common/romread.S index 749a70bae2d..4de1e0a90f8 100644 --- a/sys/arch/vax/boot/common/romread.s +++ b/sys/arch/vax/boot/common/romread.S @@ -1,5 +1,5 @@ -/* $OpenBSD: romread.s,v 1.1 2000/04/27 02:26:26 bjc Exp $ */ -/* $NetBSD: romread.s,v 1.4 1996/08/02 11:22:24 ragge Exp $ */ +/* $OpenBSD: romread.S,v 1.1 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: romread.S,v 1.1 2002/02/24 01:04:25 matt Exp $ */ /* * Copyright (c) 1995 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -59,36 +59,34 @@ ENTRY(read750, 0xFFE) ret /* - * romread_uvax (int lbn, int size, void *buf, int *regs) + * romread_uvax (int lbn, int size, void *buf, struct rpb *rpb) */ ENTRY(romread_uvax, 0xFFE) - movl 16(ap), r11 # array of bootregs - movl 44(r11), r11 # restore boot-contents of r11 (rpb) - movl 52(r11), r7 # load iovec/bqo into r7 - addl3 (r7), r7, r6 # load qio into r6 - pushl r11 # base of rpb - pushl $0 # virtual-flag - pushl $33 # read-logical-block - pushl 4(ap) # lbn to start reading - pushl 8(ap) # number of bytes to read - pushl 12(ap) # buffer-address + movl 16(ap),r11 # restore boot-contents of %r11 (rpb) + movl 52(r11), r7 # load iovec/bqo into %r7 + addl3 (r7), r7, r6 # load qio into %r6 + pushl r11 # base of rpb + pushl $0 # virtual-flag + pushl $33 # read-logical-block + pushl 4(ap) # lbn to start reading + pushl 8(ap) # number of bytes to read + pushl 12(ap) # buffer-address calls $6, (r6) # call the qio-routine - ret # r0 holds the result + ret # %r0 holds the result /* - * romwrite_uvax (int lbn, int size, void *buf, int *regs) + * romwrite_uvax (int lbn, int size, void *buf, struct rpb *rpb) */ ENTRY(romwrite_uvax, 0xFFE) - movl 16(ap), r11 # array of bootregs - movl 44(r11), r11 # restore boot-contents of r11 (rpb) - movl 52(r11), r7 # load iovec/bqo into r7 - addl3 (r7), r7, r6 # load qio into r6 - pushl r11 # base of rpb - pushl $0 # virtual-flag - pushl $32 # write-logical-block - pushl 4(ap) # lbn to start reading - pushl 8(ap) # number of bytes to read - pushl 12(ap) # buffer-address + movl 16(ap), r11 # restore boot-contents of %r11 (rpb) + movl 52(r11), r7 # load iovec/bqo into %r7 + addl3 (r7), r7, r6 # load qio into %r6 + pushl r11 # base of rpb + pushl $0 # virtual-flag + pushl $32 # write-logical-block + pushl 4(ap) # lbn to start reading + pushl 8(ap) # number of bytes to read + pushl 12(ap) # buffer-address calls $6, (r6) # call the qio-routine - ret # r0 holds the result + ret # %r0 holds the result diff --git a/sys/arch/vax/boot/common/srt0.s b/sys/arch/vax/boot/common/srt0.S index fb5dabecf6d..8ff71c5a35c 100644 --- a/sys/arch/vax/boot/common/srt0.s +++ b/sys/arch/vax/boot/common/srt0.S @@ -1,5 +1,5 @@ -/* $OpenBSD: srt0.s,v 1.2 2000/10/04 04:09:01 bjc Exp $ */ -/* $NetBSD: srt0.s,v 1.2 1999/05/23 21:58:19 ragge Exp $ */ +/* $OpenBSD: srt0.S,v 1.1 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: srt0.S,v 1.2 2002/03/31 00:11:14 matt Exp $ */ /* * Copyright (c) 1994 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -33,6 +33,7 @@ /* All bugs are subject to removal without further notice */ #include "../include/asm.h" + /* * Auto-moving startup code for standalone programs. Can be loaded * (almost) anywhere in memory but moves itself to the position @@ -41,45 +42,44 @@ * position set in a.out header. */ -nisse: .set nisse,0 # pass -e nisse to ld gives OK start addr - .globl nisse - -_start: .globl _start - nop;nop; # If we get called by calls, or something - - movl r8, _memsz # If we come from disk, save memsize - ashl $9,76(r11),_memsz # got memsize from rpb - movzwl 48(r11), r10 # Get howto + .globl nisse # pass -e nisse to ld gives OK start addr + .set nisse,0 -2: movl $_start, sp # Probably safe place for stack - pushr $0x1fff +ALTENTRY(start) + nop;nop; + movl $_C_LABEL(start), sp # Probably safe place for stack + pushr $0x1fff # save for later usage - subl3 $_start, $_edata, r0 - movab _start, r1 - movl $_start, r3 - movc3 r0,(r1),(r3) # Kopiera text + data - subl3 $_edata, $_end, r2 - movc5 $0,(r3),$0,r2,(r3) # Nolla bss också. + subl3 $_C_LABEL(start), $_C_LABEL(edata), r0 + movab _C_LABEL(start), r1 # get where we are + movl $_C_LABEL(start), r3 # get where we want to be + cmpl r1,r3 # are we where we want to be? + beql relocated # already relocated, skip copy + movc3 r0,(r1),(r3) # copy + subl3 $_C_LABEL(edata), $_C_LABEL(end), r2 + movc5 $0,(r3),$0,r2,(r3) # Zero bss - jsb 1f -1: movl $relocated, (sp) # return-address on top of stack - rsb # can be replaced with new address -relocated: # now relocation is done !!! - movl r10,_howto # howto also... - movl sp, _bootregs - calls $0, _Xmain # Were here! + movpsl -(sp) + pushl $relocated + rei +relocated: # now relocation is done !!! + movl sp,_C_LABEL(bootregs) # *bootregs + calls $0, _C_LABEL(Xmain) # Were here! halt # no return ENTRY(machdep_start, 0) + calls $0,_C_LABEL(niclose) # Evil hack to shutdown DEBNA. mtpr $0x1f,$0x12 # Block all interrupts mtpr $0,$0x18 # stop real time interrupt clock movl 4(ap), r6 - movl _howto, r11 - movl _opendev, r10 - movl 20(ap), r9 - movl _memsz, r8 - calls $0,(r6) - ret + movl 20(ap), r9 # end of symbol table + pushl 8(ap) # number of symbols + pushl 16(ap) # start of symbols + movab _C_LABEL(bootrpb),r10 # get RPB address + pushl r10 # argument for new boot + ashl $9,76(r10),r8 # memory size (COMPAT) + movl $3,r11 # ask boot (COMPAT) + clrl r10 # no boot dev (COMPAT) - .globl _memsz -_memsz: .long 0x0 + calls $3,(r6) + halt diff --git a/sys/arch/vax/stand/common/str.s b/sys/arch/vax/boot/common/str.S index e45ab28ea67..e88cb9ca9ce 100644 --- a/sys/arch/vax/stand/common/str.s +++ b/sys/arch/vax/boot/common/str.S @@ -1,5 +1,5 @@ -/* $OpenBSD: str.s,v 1.2 2000/05/01 00:12:02 bjc Exp $ */ -/* $NetBSD: str.s,v 1.1 1999/03/06 16:36:06 ragge Exp $ */ +/* $OpenBSD: str.S,v 1.1 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: str.S,v 1.1 2002/02/24 01:04:25 matt Exp $ */ /* * Copyright (c) 1996 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -41,7 +41,7 @@ /* * atoi() used in devopen. */ -ENTRY(atoi, 0); +ENTRY(atoi, 0) movl 4(ap),r1 clrl r0 @@ -60,7 +60,7 @@ ENTRY(atoi, 0); * index() small and easy. * doesnt work if we search for null. */ -ENTRY(index, 0); +ENTRY(index, 0) movq 4(ap),r0 1: cmpb (r0), r1 beql 2f @@ -72,7 +72,7 @@ ENTRY(index, 0); /* * cmpc3 is emulated on MVII. */ -ENTRY(bcmp, 0); +ENTRY(bcmp, 0) movl 4(ap), r2 movl 8(ap), r1 movl 12(ap), r0 @@ -85,15 +85,15 @@ ENTRY(bcmp, 0); /* * Is movc3/movc5 emulated on any CPU? I dont think so; use them here. */ -ENTRY(bzero,0); +ENTRY(bzero,0) movc5 $0,*4(ap),$0,8(ap),*4(ap) ret -ENTRY(bcopy,0); +ENTRY(bcopy,0) movc3 12(ap), *4(ap), *8(ap) ret -ENTRY(strlen, 0); +ENTRY(strlen, 0) movl 4(ap), r0 1: tstb (r0)+ bneq 1b @@ -139,7 +139,7 @@ ENTRY(strncpy, 0) ENTRY(strcat, 0) pushl 4(ap) - calls $1,_strlen + calls $1,_C_LABEL(strlen) addl2 4(ap),r0 movl 8(ap),r1 1: movb (r1)+,(r0)+ @@ -147,18 +147,19 @@ ENTRY(strcat, 0) ret ENTRY(setjmp, 0) - movl 4(ap), r0 - movl 8(fp), (r0) - movl 12(fp), 4(r0) - movl 16(fp), 8(r0) - addl3 fp,$28,12(r0) - clrl r0 - ret + movl 4(ap), r0 + movl 8(fp), (r0) + movl 12(fp), 4(r0) + movl 16(fp), 8(r0) + addl3 fp,$28,12(r0) + clrl r0 + ret ENTRY(longjmp, 0) - movl 4(ap), r1 - movl 8(ap), r0 - movl (r1), ap - movl 4(r1), fp - movl 12(r1), sp - jmp *8(r1) + movl 4(ap), r1 + movl 8(ap), r0 + movl (r1), ap + movl 4(r1), fp + movl 12(r1), sp + jmp *8(r1) + diff --git a/sys/arch/vax/boot/xxboot/Makefile b/sys/arch/vax/boot/xxboot/Makefile index 9c69452e26c..d3aac85b173 100644 --- a/sys/arch/vax/boot/xxboot/Makefile +++ b/sys/arch/vax/boot/xxboot/Makefile @@ -1,37 +1,57 @@ -# $OpenBSD: Makefile,v 1.3 2002/03/10 06:52:16 hugh Exp $ -# $NetBSD: Makefile,v 1.2 1999/10/23 14:40:39 ragge Exp $ +# $OpenBSD: Makefile,v 1.4 2002/06/11 09:36:24 hugh Exp $ +# $NetBSD: Makefile,v 1.12 2002/02/24 01:04:25 matt Exp $ -S=${.CURDIR}/../../../../ +S= ${.CURDIR}/../../../../ PROG= xxboot LINKS= ${BINDIR}/xxboot ${BINDIR}/raboot LINKS+= ${BINDIR}/xxboot ${BINDIR}/hdboot LINKS+= ${BINDIR}/xxboot ${BINDIR}/sdboot LINKS+= ${BINDIR}/xxboot ${BINDIR}/hpboot +WARNS?= 1 -SRCS= start.s bootxx.c romread.s urem.s udiv.s str.s +SRCS= start.S bootxx.c romread.S str.S urem.s udiv.s STRIPFLAG= CPPFLAGS+=-D_STANDALONE -DLIBSA_NO_FD_CHECKING -DLIBSA_NO_RAW_ACCESS \ -DLIBSA_NO_TWIDDLE -DLIBSA_SINGLE_DEVICE=rom \ - -DLIBSA_SINGLE_FILESYSTEM=ufs + -DLIBSA_NO_COMPAT_UFS \ + -DLIBSA_NO_FS_SYMLINK -DLIBSA_NO_FS_CLOSE \ + -DLIBSA_NO_FS_WRITE -DLIBSA_NO_FS_SEEK \ + -DNEED_UFS BINDIR= /usr/mdec -NOMAN= 1 +NOMAN= # defined + +CFLAGS= -Os SAREL= SA_AS= library .include "${S}/lib/libsa/Makefile.inc" LIBSA= ${SALIB} -${PROG}: ${OBJS} ${LIBSA} - ld -N -Ttext 100000 -o a.out ${OBJS} ${LIBSA} - strip a.out - size a.out - dd if=a.out of=${PROG} bs=32 skip=1 -# rm -f a.out +#KERN_AS=library +#.include "${S}/lib/libkern/Makefile.inc" +#LIBKERN=${KERNLIB} + +.if ${MACHINE} == "vax" +.PHONY: machine-links +beforedepend: machine-links +machine-links: + @[ -h machine ] || ln -s ${S}/arch/${MACHINE}/include machine + @[ -h ${MACHINE_ARCH} ] || ln -s ${S}/arch/${MACHINE_ARCH}/include ${MACHINE_ARCH} +.NOPATH: machine ${MACHINE_ARCH} +CLEANFILES+= machine ${MACHINE_ARCH} +.endif + +${PROG}: ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN} +${PROG}: ${OBJS} ${LIBSA} ${LIBKERN} + ${LD} -N -Ttext 100000 -o ${PROG}.out ${OBJS} ${LIBSA} ${LIBKERN} + /usr/bin/strip ${PROG}.out + /usr/bin/size ${PROG}.out + /bin/dd if=${PROG}.out of=${PROG} bs=32 skip=1 clean:: rm -f a.out [Ee]rrs mklog core *.core ${PROG} ${OBJS} ${LOBJS} \ - ${CLEANFILES} + ${CLEANFILES} .include <bsd.prog.mk> diff --git a/sys/arch/vax/boot/xxboot/bootxx.c b/sys/arch/vax/boot/xxboot/bootxx.c index 30007379ea1..7c57b7267fa 100644 --- a/sys/arch/vax/boot/xxboot/bootxx.c +++ b/sys/arch/vax/boot/xxboot/bootxx.c @@ -1,5 +1,6 @@ -/* $OpenBSD: bootxx.c,v 1.4 2002/03/14 03:16:02 millert Exp $ */ -/* $NetBSD: bootxx.c,v 1.2 1999/10/23 14:40:38 ragge Exp $ */ +/* $OpenBSD: bootxx.c,v 1.5 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: bootxx.c,v 1.16 2002/03/29 05:45:08 matt Exp $ */ + /*- * Copyright (c) 1982, 1986 The Regents of the University of California. * All rights reserved. @@ -38,167 +39,149 @@ #include "sys/param.h" #include "sys/reboot.h" #include "sys/disklabel.h" +#include "sys/exec.h" +#include "sys/exec_elf.h" #include "lib/libsa/stand.h" #include "lib/libsa/ufs.h" +#include "lib/libsa/cd9660.h" -#include "../include/pte.h" -#include "../include/sid.h" -#include "../include/mtpr.h" -#include "../include/reg.h" -#include "../include/rpb.h" +#include "machine/pte.h" +#include "machine/sid.h" +#include "machine/mtpr.h" +#include "machine/reg.h" +#include "machine/rpb.h" +#include "../vax/gencons.h" #include "../mba/mbareg.h" #include "../mba/hpreg.h" #define NRSP 1 /* Kludge */ #define NCMD 1 /* Kludge */ +#define LIBSA_TOO_OLD -#include "../mscp/mscp.h" -#include "../mscp/mscpreg.h" - -#include "vaxstand.h" +#include "arch/vax/mscp/mscp.h" +#include "arch/vax/mscp/mscpreg.h" -struct rom_softc { - int part; - int unit; -} rom_softc; +#include "../boot/data.h" -int romstrategy(void *, int, daddr_t, size_t, void *, size_t *); -int romopen(struct open_file *, int, int, int, int); - -struct fs_ops file_system[] = { - { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat } -}; -int nfsys = (sizeof(file_system) / sizeof(struct fs_ops)); - -struct devsw devsw[] = { - SADEV("rom", romstrategy, romopen, nullsys, noioctl), -}; -int ndevs = (sizeof(devsw)/sizeof(devsw[0])); - -int command(int cmd, int arg); - -/* - * Boot program... argume passed in r10 and r11 determine whether boot - * stops to ask for system name and which device boot comes from. - */ +#define RF_PROTECTED_SECTORS 64 /* XXX refer to <.../rf_optnames.h> */ -volatile dev_t devtype, bootdev; -unsigned opendev, boothowto, bootset, memsz; +void Xmain(void); +void hoppabort(int); +void romread_uvax(int lbn, int size, void *buf, struct rpb *rpb); +void hpread(int block); +int read750(int block, int *regs); +int unit_init(int, struct rpb *, int); struct open_file file; unsigned *bootregs; struct rpb *rpb; +struct bqo *bqo; int vax_cputype; +int vax_load_failure; +struct udadevice {u_short udaip;u_short udasa;}; +volatile struct udadevice *csr; +static int moved; + +extern int from; +#define FROM750 1 +#define FROMMV 2 +#define FROMVMB 4 /* * The boot block are used by 11/750, 8200, MicroVAX II/III, VS2000, * VS3100/??, VS4000 and VAX6000/???, and only when booting from disk. */ +void Xmain() { + union { + struct exec aout; + Elf32_Ehdr elf; + } hdr; int io; - char *scbb; - char *new, *bqo; - char *hej = "/boot"; + u_long entry; vax_cputype = (mfpr(PR_SID) >> 24) & 0xFF; - + moved = 0; /* */ - switch (vax_cputype) { - case VAX_TYP_UV2: - case VAX_TYP_CVAX: - case VAX_TYP_RIGEL: - case VAX_TYP_NVAX: - case VAX_TYP_MARIAH: - case VAX_TYP_SOC: + rpb = (void *)0xf0000; /* Safe address right now */ + bqo = (void *)0xf1000; + if (from == FROMMV) { /* * now relocate rpb/bqo (which are used by ROM-routines) */ - rpb = (void *)XXRPB; - bcopy ((void *)bootregs[11], rpb, 512); - rpb->rpb_base = rpb; - bqo = (void *)(512+(int)rpb); - bcopy ((void *)rpb->iovec, bqo, rpb->iovecsz); - rpb->iovec = (int)bqo; - bootregs[11] = (int)rpb; - bootdev = rpb->devtyp; - memsz = rpb->pfncnt << 9; - break; - case VAX_8200: - case VAX_750: - bootdev = bootregs[10]; - memsz = 0; - break; - default: - asm("halt"); - } - - bootset = getbootdev(); - io = open(hej, 0); - - read(io, (void *)0x10000, 0x10000); - bcopy((void *) 0x10000, 0, 0xffff); - hoppabort(32, XXRPB, bootset); - asm("halt"); -} - -getbootdev() -{ - int i, adaptor, controller, unit, partition, retval; - - adaptor = controller = unit = partition = 0; - - switch (vax_cputype) { - case VAX_TYP_UV2: - case VAX_TYP_CVAX: - case VAX_TYP_MARIAH: - case VAX_TYP_RIGEL: - if (rpb->devtyp == BDEV_SD || rpb->devtyp == BDEV_SDN) { - unit = rpb->unit / 100; - controller = (rpb->csrphy & 0x100 ? 1 : 0); - } else { - controller = ((rpb->csrphy & 017777) == 0xDC)?1:0; - unit = rpb->unit; /* DUC, DUD? */ + bcopy ((void *)bootregs[11], rpb, sizeof(struct rpb)); + bcopy ((void*)rpb->iovec, bqo, rpb->iovecsz); +#if 0 + if (rpb->devtyp == BDEV_SDN) + rpb->devtyp = BDEV_SD; /* XXX until driver fixed */ +#endif + } else { + bzero(rpb, sizeof(struct rpb)); + rpb->devtyp = bootregs[0]; + rpb->unit = bootregs[3]; + rpb->rpb_bootr5 = bootregs[5]; + rpb->csrphy = bootregs[2]; + rpb->adpphy = bootregs[1]; /* BI node on 8200 */ + if (rpb->devtyp != BDEV_HP && vax_cputype == VAX_TYP_750) + rpb->adpphy = + (bootregs[1] == 0xffe000 ? 0xf30000 : 0xf32000); + } + rpb->rpb_base = rpb; + rpb->iovec = (int)bqo; + + io = open("/boot.vax", 0); + if (io < 0) + io = open("/boot", 0); + if (io < 0) + asm("movl $0xbeef1, r0; halt"); + + read(io, (void *)&hdr.aout, sizeof(hdr.aout)); + if (N_GETMAGIC(hdr.aout) == OMAGIC && N_GETMID(hdr.aout) == MID_VAX) { + vax_load_failure++; + entry = hdr.aout.a_entry; + if (entry < sizeof(hdr.aout)) + entry = sizeof(hdr.aout); + read(io, (void *) entry, hdr.aout.a_text + hdr.aout.a_data); + memset((void *) (entry + hdr.aout.a_text + hdr.aout.a_data), + 0, hdr.aout.a_bss); + } else if (memcmp(hdr.elf.e_ident, ELFMAG, SELFMAG) == 0) { + Elf32_Phdr ph; + size_t off = sizeof(hdr.elf); + vax_load_failure += 2; + read(io, (caddr_t)(&hdr.elf) + sizeof(hdr.aout), + sizeof(hdr.elf) - sizeof(hdr.aout)); + if (hdr.elf.e_machine != EM_VAX || hdr.elf.e_type != ET_EXEC + || hdr.elf.e_phnum != 1) + goto die; + vax_load_failure++; + entry = hdr.elf.e_entry; + if (hdr.elf.e_phoff != sizeof(hdr.elf)) + goto die; + vax_load_failure++; + read(io, &ph, sizeof(ph)); + off += sizeof(ph); + if (ph.p_type != PT_LOAD) + goto die; + vax_load_failure++; + while (off < ph.p_offset) { + u_int32_t tmp; + read(io, &tmp, sizeof(tmp)); + off += sizeof(tmp); } - break; - - case VAX_TYP_8SS: - case VAX_TYP_750: - controller = bootregs[1]; - unit = bootregs[3]; - break; + read(io, (void *) ph.p_paddr, ph.p_filesz); + memset((void *) (ph.p_paddr + ph.p_filesz), 0, + ph.p_memsz - ph.p_filesz); + } else { + goto die; } - - switch (B_TYPE(bootdev)) { - case BDEV_HP: /* massbuss boot */ - adaptor = (bootregs[1] & 0x6000) >> 17; - break; - - case BDEV_UDA: /* UDA50 boot */ - if (vax_cputype == VAX_750) - adaptor = (bootregs[1] & 0x40000 ? 0 : 1); - break; - - case BDEV_TK: /* TK50 boot */ - case BDEV_CNSL: /* Console storage boot */ - case BDEV_RD: /* RD/RX on HDC9224 (MV2000) */ - case BDEV_ST: /* SCSI-tape on NCR5380 (MV2000) */ - case BDEV_SD: /* SCSI-disk on NCR5380 (3100/76) */ - case BDEV_SDN: /* SCSI disk on NCR53C94 */ - break; - - case BDEV_KDB: /* DSA disk on KDB50 (VAXBI VAXen) */ - bootdev = (bootdev & ~B_TYPEMASK) | BDEV_UDA; - break; - - default: - boothowto |= (RB_SINGLE | RB_ASKNAME); - } - return MAKEBOOTDEV(bootdev, adaptor, controller, unit, partition); + hoppabort(entry); +die: + asm("movl $0xbeef2, r0; halt"); } /* @@ -207,6 +190,51 @@ getbootdev() * - Can only load file "boot". * - Must be the first file on tape. */ +struct fs_ops file_system[] = { +#ifdef NEED_UFS + { ufs_open, 0, ufs_read, 0, 0, ufs_stat }, +#endif +#ifdef NEED_CD9660 + { cd9660_open, 0, cd9660_read, 0, 0, cd9660_stat }, +#endif +#ifdef NEED_USTARFS + { ustarfs_open, 0, ustarfs_read, 0, 0, ustarfs_stat }, +#endif +}; + +int nfsys = (sizeof(file_system) / sizeof(struct fs_ops)); + +#ifdef LIBSA_TOO_OLD +#include "../boot/vaxstand.h" + +struct rom_softc { + int part; + int unit; +} rom_softc; + +int romstrategy(void *, int, daddr_t, size_t, void *, size_t *); +int romopen(struct open_file *, int, int, int, int); +struct devsw devsw[] = { + SADEV("rom", romstrategy, romopen, nullsys, noioctl), +}; +int ndevs = (sizeof(devsw)/sizeof(devsw[0])); + +int +romopen(f, adapt, ctlr, unit, part) + struct open_file *f; + int adapt, ctlr, unit, part; +{ + rom_softc.unit = unit; + rom_softc.part = part; + + f->f_devdata = (void *)&rom_softc; + + return 0; +} + +#endif + +#if 0 int tar_open(char *path, struct open_file *f); ssize_t tar_read(struct open_file *f, void *buf, size_t size, size_t *resid); @@ -233,101 +261,68 @@ tar_read(f, buf, size, resid) { romstrategy(0, 0, (8192+512), size, buf, 0); *resid = size; + return 0; /* XXX */ } +#endif -struct disklabel lp; -int part_off = 0; /* offset into partition holding /boot */ -char io_buf[DEV_BSIZE]; -volatile struct uda { - struct mscp_1ca uda_ca; /* communications area */ - struct mscp uda_rsp; /* response packets */ - struct mscp uda_cmd; /* command packets */ -} uda; -struct udadevice {u_short udaip;u_short udasa;}; -volatile struct udadevice *csr; +int devopen(f, fname, file) struct open_file *f; const char *fname; char **file; { - extern char start; - char *msg; - int i, err, off; - char line[64]; - struct devsw *dp; +#ifdef LIBSA_TOO_OLD + int i; + struct devsw *dp; f->f_dev = &devsw[0]; +#endif *file = (char *)fname; + if (from == FROM750) + return 0; /* - * On uVAX we need to init [T]MSCP ctlr to be able to use it. + * Reinit the VMB boot device. */ - if (vax_cputype == VAX_TYP_UV2 || vax_cputype == VAX_TYP_CVAX) { - switch (bootdev) { - case BDEV_UDA: /* MSCP */ - case BDEV_TK: /* TMSCP */ + if (bqo->unit_init && (moved++ == 0)) { + int initfn; + + initfn = rpb->iovec + bqo->unit_init; + if (rpb->devtyp == BDEV_UDA || rpb->devtyp == BDEV_TK) { + /* + * This reset do not seem to be done in the + * ROM routines, so we have to do it manually. + */ csr = (struct udadevice *)rpb->csrphy; - - csr->udaip = 0; /* Start init */ - while((csr->udasa & MP_STEP1) == 0); - csr->udasa = 0x8000; - while((csr->udasa & MP_STEP2) == 0); - csr->udasa = (short)(((u_int)&uda)&0xffff) + 8; - while((csr->udasa & MP_STEP3) == 0); - csr->udasa = 0x10; - while((csr->udasa & MP_STEP4) == 0); - csr->udasa = 0x0001; - - uda.uda_ca.ca_rspdsc = - (int) &uda.uda_rsp.mscp_cmdref; - uda.uda_ca.ca_cmddsc = - (int) &uda.uda_cmd.mscp_cmdref; - if (bootdev == BDEV_TK) - uda.uda_cmd.mscp_vcid = 1; - command(M_OP_SETCTLRC, 0); - uda.uda_cmd.mscp_unit = rpb->unit; - command(M_OP_ONLINE, 0); + csr->udaip = 0; + while ((csr->udasa & MP_STEP1) == 0) + ; } + /* + * AP (R12) have a pointer to the VMB argument list, + * wanted by bqo->unit_init. + */ + unit_init(initfn, rpb, bootregs[12]); } - - /* - * the disklabel _shall_ be at address LABELOFFSET + RELOC in - * phys memory now, no need at all to reread it again. - * Actually disklabel is only needed when using hp disks, - * but it doesn't hurt to always get it. - */ - getdisklabel(LABELOFFSET + &start, &lp); - - /* currently only one dev in devsw; this must change if we add more */ - dp = devsw; - i = 0; - if(dp != NULL && dp->dv_open != NULL) { - i = (*dp->dv_open)(f, B_ADAPTOR(bootdev), B_CONTROLLER(bootdev), - B_UNIT(bootdev), B_PARTITION(bootdev)); - } - - return i; -} - -command(cmd, arg) -{ - volatile int hej; - - uda.uda_cmd.mscp_opcode = cmd; - uda.uda_cmd.mscp_modifier = arg; - - uda.uda_cmd.mscp_msglen = MSCP_MSGLEN; - uda.uda_rsp.mscp_msglen = MSCP_MSGLEN; - uda.uda_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT; - uda.uda_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT; - hej = csr->udaip; - while (uda.uda_ca.ca_rspdsc < 0); - +#ifdef LIBSA_TOO_OLD_FOO + /* currently only one dev in devsw; this must change if we add more */ + dp = devsw; + i = 0; + if(dp != NULL && dp->dv_open != NULL) { + i = (*dp->dv_open)(f, B_ADAPTOR(bootdev), B_CONTROLLER(bootdev), + B_UNIT(bootdev), B_PARTITION(bootdev)); + } + + return i; +#else + return 0; +#endif } -int curblock = 0; +extern struct disklabel romlabel; +int romstrategy(sc, func, dblk, size, buf, rsize) void *sc; int func; @@ -336,77 +331,31 @@ romstrategy(sc, func, dblk, size, buf, rsize) void *buf; size_t *rsize; { - struct rom_softc *romsc = sc; - int i; int block = dblk; int nsize = size; - switch (vax_cputype) { - /* - * case VAX_TYP_UV2: - * case VAX_TYP_CVAX: - * case VAX_TYP_RIGEL: - */ - default: - switch (B_TYPE(bootdev)) { - - case BDEV_UDA: /* MSCP */ - uda.uda_cmd.mscp_seq.seq_lbn = dblk; - uda.uda_cmd.mscp_seq.seq_bytecount = size; - uda.uda_cmd.mscp_seq.seq_buffer = (int)buf; - uda.uda_cmd.mscp_unit = rpb->unit; - command(M_OP_READ, 0); - break; - - case BDEV_TK: /* TMSCP */ - if (dblk < curblock) { - uda.uda_cmd.mscp_seq.seq_bytecount = - curblock - dblk; - command(M_OP_POS, 12); - } else { - uda.uda_cmd.mscp_seq.seq_bytecount = - dblk - curblock; - command(M_OP_POS, 4); + if (romlabel.d_magic == DISKMAGIC && romlabel.d_magic2 == DISKMAGIC) { + if (romlabel.d_npartitions > 1) { + block += romlabel.d_partitions[0].p_offset; + if (romlabel.d_partitions[0].p_fstype == FS_RAID) { + block += RF_PROTECTED_SECTORS; } - curblock = size/512 + dblk; - for (i = 0 ; i < size/512 ; i++) { - uda.uda_cmd.mscp_seq.seq_lbn = 1; - uda.uda_cmd.mscp_seq.seq_bytecount = 512; - uda.uda_cmd.mscp_seq.seq_buffer = - (int)buf + i * 512; - uda.uda_cmd.mscp_unit = rpb->unit; - command(M_OP_READ, 0); - } - break; - - case BDEV_SDN: /* XXX others too eventually */ - case BDEV_SD: /* XXX others too eventually */ - if(romsc != NULL) - block += lp.d_partitions[romsc->part].p_offset; - case BDEV_RD: - case BDEV_ST: - - default: - romread_uvax(block, size, buf, bootregs); - break; + } + } + if (from == FROMMV) { + romread_uvax(block, size, buf, rpb); + } else /* if (from == FROM750) */ { + while (size > 0) { + if (rpb->devtyp == BDEV_HP) + hpread(block); + else + read750(block, bootregs); + bcopy(0, buf, 512); + size -= 512; + (char *)buf += 512; + block++; } - break; - - case VAX_8200: - case VAX_750: - if (bootdev != BDEV_HP) { - while (size > 0) { - while ((read750(block, bootregs) & 0x01) == 0){ - } - bcopy(0, buf, 512); - size -= 512; - buf += 512; - block++; - } - } else - hpread(block, size, buf); - break; } if (rsize) @@ -414,50 +363,66 @@ romstrategy(sc, func, dblk, size, buf, rsize) return 0; } -int -romopen(f, adapt, ctlr, unit, part) - struct open_file *f; - int adapt, ctlr, unit, part; -{ - rom_softc.unit = unit; - rom_softc.part = part; - - f->f_devdata = (void *)&rom_softc; - - return 0; -} +/* + * The 11/750 boot ROM for Massbus disks doesn't seen to have layout info + * for all RP disks (not RP07 at least) so therefore a very small and dumb + * device driver is used. It assumes that there is a label on the disk + * already that has valid layout info. If there is no label, we can't boot + * anyway. + */ + +#define MBA_WCSR(reg, val) \ + ((void)(*(volatile u_int32_t *)((adpadr) + (reg)) = (val))); +#define MBA_RCSR(reg) \ + (*(volatile u_int32_t *)((adpadr) + (reg))) +#define HP_WCSR(reg, val) \ + ((void)(*(volatile u_int32_t *)((unitadr) + (reg)) = (val))); +#define HP_RCSR(reg) \ + (*(volatile u_int32_t *)((unitadr) + (reg))) -hpread(block, size, buf) - char *buf; +void +hpread(int bn) { - volatile struct mba_regs *mr = (void *) bootregs[1]; - volatile struct hp_drv *hd = (void *)&mr->mba_md[bootregs[3]]; - struct disklabel *dp = &lp; - u_int pfnum, nsize, mapnr, bn, cn, sn, tn; - - pfnum = (u_int) buf >> PGSHIFT; - - for (mapnr = 0, nsize = size; (nsize + NBPG) > 0; nsize -= NBPG) - *(int *)&mr->mba_map[mapnr++] = PG_V | pfnum++; - mr->mba_var = ((u_int) buf & PGOFSET); - mr->mba_bc = (~size) + 1; - bn = block; + int adpadr = bootregs[1]; + int unitadr = adpadr + MUREG(bootregs[3], 0); + u_int cn, sn, tn; + struct disklabel *dp; + extern char start; + + dp = (struct disklabel *)(LABELOFFSET + &start); + MBA_WCSR(MAPREG(0), PG_V); + + MBA_WCSR(MBA_VAR, 0); + MBA_WCSR(MBA_BC, (~512) + 1); +#ifdef __GNUC__ + /* + * Avoid four subroutine calls by using hardware division. + */ + asm("clrl %r1;" + "movl %3,%r0;" + "ediv %4,%r0,%0,%1;" + "movl %1,%r0;" + "ediv %5,%r0,%2,%1" + : "=g"(cn),"=g"(sn),"=g"(tn) + : "g"(bn),"g"(dp->d_secpercyl),"g"(dp->d_nsectors) + : "r0","r1","cc"); +#else cn = bn / dp->d_secpercyl; sn = bn % dp->d_secpercyl; tn = sn / dp->d_nsectors; sn = sn % dp->d_nsectors; - hd->hp_dc = cn; - hd->hp_da = (tn << 8) | sn; - hd->hp_cs1 = HPCS_READ; - while (mr->mba_sr & MBASR_DTBUSY); - if (mr->mba_sr & MBACR_ABORT){ - return 1; - } - return 0; +#endif + HP_WCSR(HP_DC, cn); + HP_WCSR(HP_DA, (tn << 8) | sn); + HP_WCSR(HP_CS1, HPCS_READ); + + while (MBA_RCSR(MBA_SR) & MBASR_DTBUSY) + ; + return; } extern char end[]; -static char *top = (char *)end; +static char *top = (char*)end; void * alloc(size) @@ -481,3 +446,31 @@ romclose(f) { return 0; } + +#ifdef USE_PRINTF +void +putchar(int ch) +{ + /* + * On KA88 we may get C-S/C-Q from the console. + * Must obey it. + */ + while (mfpr(PR_RXCS) & GC_DON) { + if ((mfpr(PR_RXDB) & 0x7f) == 19) { + while (1) { + while ((mfpr(PR_RXCS) & GC_DON) == 0) + ; + if ((mfpr(PR_RXDB) & 0x7f) == 17) + break; + } + } + } + + while ((mfpr(PR_TXCS) & GC_RDY) == 0) + ; + mtpr(0, PR_TXCS); + mtpr(ch & 0377, PR_TXDB); + if (ch == 10) + putchar(13); +} +#endif diff --git a/sys/arch/vax/stand/xxboot/start.s b/sys/arch/vax/boot/xxboot/start.S index f39ecafab62..309b53f308e 100644 --- a/sys/arch/vax/stand/xxboot/start.s +++ b/sys/arch/vax/boot/xxboot/start.S @@ -1,5 +1,5 @@ -/* $OpenBSD: start.s,v 1.3 2000/11/25 21:33:08 hugh Exp $ */ -/* $NetBSD: start.s,v 1.2 1999/10/23 14:40:38 ragge Exp $ */ +/* $OpenBSD: start.S,v 1.1 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: start.S,v 1.1 2002/02/24 01:04:26 matt Exp $ */ /* * Copyright (c) 1995 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -17,8 +17,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 * @@ -37,15 +37,17 @@ /* All bugs are subject to removal without further notice */ -#define _LOCORE +#define _LOCORE #include "sys/disklabel.h" #include "../include/mtpr.h" #include "../include/asm.h" -_start: .globl _start # this is the symbolic name for the start - # of code to be relocated. We can use this +_C_LABEL(_start): +_C_LABEL(start): + .globl _C_LABEL(start) # this is the symbolic name for the start + .globl _C_LABEL(_start) # of code to be relocated. We can use this # to get the actual/real adress (pc-rel) # or to get the relocated address (abs). @@ -53,7 +55,7 @@ _start: .globl _start # this is the symbolic name for the start brb from_0x00 # continue behind dispatch-block .org 0x02 # information used by uVAX-ROM - .byte (LABELOFFSET + d_end_)/2 # offset in words to identification area + .byte 0xff # offset in words to identification area .byte 1 # this byte must be 1 .word 0 # logical block number (word swapped) .word 0 # of the secondary image @@ -61,38 +63,53 @@ _start: .globl _start # this is the symbolic name for the start .org 0x08 # brb from_0x08 # skip ... -.org 0x0A # uVAX booted from disk starts here - brb from_0x0A # skip ... - .org 0x0C # 11/750 & 8200 starts here + movzbl $1,_C_LABEL(from)# We booted from "old" rom. brw cont_750 from_0x00: # uVAX from TK50 -from_0x0A: # uVAX from disk - brw start_uvax # all(?) uVAXen continue there - -from_0x08: # What comes here??? - halt + brw start_uvax # all uVAXen continue there -.org LABELOFFSET - 6 -regmask: .word 0x0fff # using a variable saves 3 bytes !!! -bootinfo: .long 0x0 # another 3 bytes if within byte-offset +from_0x08: # Any machine from VMB + movzbl $4,_C_LABEL(from) # Booted from full VMB + brw start_vmb # the complete area reserved for label # must be empty (i.e. filled with zeroes). # disklabel(8) checks that before installing # the bootblocks over existing label. +.org LABELOFFSET + .globl _C_LABEL(romlabel) +_C_LABEL(romlabel): + .long 0 + +.org LABELOFFSET + d_end_ +start_vmb: + /* + * Read in block 1-15. + */ + movl 52(r11), r7 # load iovec/bqo into %r7 + addl3 (r7), r7, r6 # load qio into %r6 + pushl r11 # base of rpb + pushl $0 # virtual-flag + pushl $33 # read-logical-block + pushl $1 # lbn to start reading + pushl $7680 # number of bytes to read + pushab start_uvax # buffer-address + calls $6, (r6) # call the qio-routine + brw start_uvax + /* * Parameter block for uVAX boot. */ -#define VOLINFO 0 /* 1=single-sided 81=double-sided volumes */ -#define SISIZE 16 /* size in blocks of secondary image */ -#define SILOAD 0 /* load offset (usually 0) from the default */ -#define SIOFF 0x0A /* byte offset into secondary image */ +#define VOLINFO 0 /* 1=single-sided 81=double-sided volumes */ +#define SISIZE 16 /* size in blocks of secondary image */ +#define SILOAD 0 /* load offset (usually 0) from the default */ +#define SIOFF 0x260 /* byte offset into secondary image */ -.org LABELOFFSET + d_end_ +.org 0x1fe .byte 0x18 # must be 0x18 .byte 0x00 # must be 0x00 (MBZ) .byte 0x00 # any value @@ -106,15 +123,21 @@ bootinfo: .long 0x0 # another 3 bytes if within byte-offset .long SISIZE # size in blocks of secondary image .long SILOAD # load offset (usually 0) - .long SIOFF # byte offset into secondary image + .long SIOFF # byte offset into secondary image .long (SISIZE + SILOAD + SIOFF) # sum of previous 3 + + .align 2 + .globl _C_LABEL(from) +_C_LABEL(from): + .long 0 + /* * After bootblock (LBN0) has been loaded into the first page * of good memory by 11/750's ROM-code (transfer address * of bootblock-code is: base of good memory + 0x0C) registers * are initialized as: - * R0: type of boot-device + * R0: type of boot-device * 0: Massbus device * 1: RK06/RK07 * 2: RL02 @@ -123,35 +146,39 @@ bootinfo: .long 0x0 # another 3 bytes if within byte-offset * 64: TU58 * R1: (UBA) address of UNIBUS I/O-page * (MBA) address of boot device's adapter - * R2: (UBA) address of the boot device's CSR + * R2: (UBA) address of the boot device's CSR * (MBA) controller number of boot device * R6: address of driver subroutine in ROM * * cont_750 reads in LBN1-15 for further execution. */ - .align 2 cont_750: - movl r0,r10 - clrl r5 - clrl r4 - movl $_start,sp -1: incl r4 - movl r4,r8 - addl2 $0x200,r5 - cmpl $16,r4 - beql 2f - pushl r5 - jsb (r6) - blbs r0,1b -2: movl r10, r0 - movl r11, r5 - brw start_all - - .org 0x300 + movl $_C_LABEL(start), sp # move stack to avoid clobbering the code + pushr $0x131 # save clobbered registers + clrl r4 # %r4 == # of blocks transferred + movab _C_LABEL(start),r5 # %r5 have base address for next transfer + pushl r5 # ...on stack also (Why?) +1: incl r4 # increment block count + movl r4,r8 # LBN is in %r8 for rom routine + addl2 $0x200,r5 # Increase address for next read + cmpl $16,r4 # read 15 blocks? + beql 2f # Yep + movl r5,(sp) # move address to stack also + jsb (r6) # read 512 bytes + blbs r0,1b # jump if read succeeded + halt # otherwise die... +2: tstl (sp)+ # remove boring arg from stack + popr $0x131 # restore clobbered registers + brw start_all # Ok, continue... + +/* uVAX main entry is at the start of the second disk block. This is + * needed for multi-arch CD booting where multiple architecture need + * to shove stuff in boot block 0. + */ + .org 0x260 # uVAX booted from disk starts here start_uvax: - mtpr $0, $PR_MAPEN # Turn off MM, please. - movl $_start, sp + movzbl $2,_C_LABEL(from) # Booted from subset-VMB brb start_all /* @@ -159,20 +186,23 @@ start_uvax: * to RELOC and loads boot. */ start_all: + movl $_C_LABEL(start), sp # move stack to a better pushr $0x1fff # save all regs, used later. - subl3 $_start, $_edata, r0 # get size of text+data (w/o bss) - moval _start, r1 # get actual base-address of code - subl3 $_start, $_end, r2 # get complete size (incl. bss) - movl $_start, r3 # get relocated base-address of code + subl3 $_C_LABEL(start), $_C_LABEL(edata), r0 + # get size of text+data (w/o bss) + moval _C_LABEL(start), r1 # get actual base-address of code + subl3 $_C_LABEL(start), $_C_LABEL(end), r2 + # get complete size (incl. bss) + movl $_C_LABEL(start), r3 # get relocated base-address of code movc5 r0, (r1), $0, r2, (r3) # copy code to new location - jsb 1f -1: movl $relocated, (sp) # return-address on top of stack - rsb # can be replaced with new address + movpsl -(sp) + movl $relocated, -(sp) # return-address on top of stack + rei # can be replaced with new address relocated: # now relocation is done !!! - movl sp, _bootregs - calls $0, _Xmain # call Xmain (gcc workaround)which is + movl sp, _C_LABEL(bootregs) + calls $0, _C_LABEL(Xmain) # call Xmain (gcc workaround)which is halt # not intended to return ... /* @@ -180,20 +210,32 @@ relocated: # now relocation is done !!! */ ENTRY(hoppabort, 0) movl 4(ap),r6 - movl 8(ap),r11 - movl 0xc(ap),r10 - movl _memsz, r8 - mnegl $1, ap # Hack to figure out boot device. - jmp 2(r6) -# calls $0,(r6) + movl _C_LABEL(rpb),r11 + mnegl $1,ap # Hack to figure out boot device. + movpsl -(sp) + pushab 2(r6) + mnegl $1,_C_LABEL(vax_load_failure) + rei +# calls $0,(r6) halt +ENTRY(unit_init, R6|R7|R8|R9|R10|R11) + mfpr $17,r7 # Wanted bu KDB + movl 4(ap),r0 # init routine address + movl 8(ap),r9 # RPB in %r9 + movl 12(ap),r1 # VMB argument list + callg (r1),(r0) + ret + # A bunch of functions unwanted in boot blocks. ENTRY(getchar, 0) halt +#ifndef USE_PRINTF ENTRY(putchar, 0) ret +#endif + ENTRY(panic, 0) halt diff --git a/sys/arch/vax/conf/RAMDISK b/sys/arch/vax/conf/RAMDISK index 809e0236ef8..ffbe528c0c3 100644 --- a/sys/arch/vax/conf/RAMDISK +++ b/sys/arch/vax/conf/RAMDISK @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK,v 1.16 2002/05/11 09:54:08 hugh Exp $ +# $OpenBSD: RAMDISK,v 1.17 2002/06/11 09:36:24 hugh Exp $ machine vax # machine type @@ -8,6 +8,8 @@ makeoptions COPTS="-O2" option RAMDISK_HOOKS option MINIROOTSIZE=3072 +option COMPAT_VAX1K + # Here are all different supported CPU types listed. # One of these is required. #option VAX8600 diff --git a/sys/arch/vax/if/if_le.c b/sys/arch/vax/if/if_le.c index 991933230ba..2471ca846a2 100644 --- a/sys/arch/vax/if/if_le.c +++ b/sys/arch/vax/if/if_le.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_le.c,v 1.9 2002/03/14 01:26:48 millert Exp $ */ +/* $OpenBSD: if_le.c,v 1.10 2002/06/11 09:36:24 hugh Exp $ */ /* $NetBSD: if_le.c,v 1.14 1999/08/14 18:40:23 ragge Exp $ */ /*- @@ -225,14 +225,6 @@ le_ibus_attach(parent, self, aux) bcopy(self->dv_xname, sc->sc_am7990.sc_arpcom.ac_if.if_xname, IFNAMSIZ); am7990_config(&sc->sc_am7990); - - /* - * Register this device as boot device if we booted from it. - * This will fail if there are more than one le in a machine, - * fortunately there may be only one. - */ - if (B_TYPE(bootdev) == BDEV_LE) - booted_from = self; } /* diff --git a/sys/arch/vax/include/bus.h b/sys/arch/vax/include/bus.h index d66a7e7f881..bc1a6ecd3bc 100644 --- a/sys/arch/vax/include/bus.h +++ b/sys/arch/vax/include/bus.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bus.h,v 1.5 2002/03/14 01:26:48 millert Exp $ */ +/* $OpenBSD: bus.h,v 1.6 2002/06/11 09:36:24 hugh Exp $ */ /* $NetBSD: bus.h,v 1.14 2000/06/26 04:56:13 simonb Exp $ */ /*- @@ -922,6 +922,8 @@ struct vax_bus_dma_segment { }; typedef struct vax_bus_dma_segment bus_dma_segment_t; +struct proc; + /* * bus_dma_tag_t * diff --git a/sys/arch/vax/include/ka630.h b/sys/arch/vax/include/ka630.h index 79391ab5c8a..f25656bc280 100644 --- a/sys/arch/vax/include/ka630.h +++ b/sys/arch/vax/include/ka630.h @@ -1,5 +1,5 @@ -/* $OpenBSD: ka630.h,v 1.4 2000/04/26 03:08:41 bjc Exp $ */ -/* $NetBSD: ka630.h,v 1.4 2000/01/24 02:40:32 matt Exp $ */ +/* $OpenBSD: ka630.h,v 1.5 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: ka630.h,v 1.5 2000/07/19 01:01:58 matt Exp $ */ /*- * Copyright (c) 1986, 1988 The Regents of the University of California. * All rights reserved. @@ -41,6 +41,7 @@ #define UVAXIISID ((u_long *)0x20040004) #define UVAXIICPU ((struct uvaxIIcpu *)0x20080000) +#ifndef _LOCORE struct uvaxIIcpu { u_short uvaxII_bdr; u_short uvaxII_xxx; @@ -48,6 +49,7 @@ struct uvaxIIcpu { u_long uvaxII_cear; u_long uvaxII_dear; }; +#endif /* Memory system err reg. */ #define UVAXIIMSER_CD 0x00000300 @@ -121,5 +123,17 @@ struct ka630clock { }; #endif +#define KA630_NVR_ADRS 0x200B8024 +/* Definitions for various locations in the KA630 console page */ +#define KA630_PUTC_POLL 0x20 +#define KA630_PUTC 0x24 +#define KA630_GETC 0x1C +#define KA630_ROW 0x4C +#define KA630_MINROW 0x4D +#define KA630_MAXROW 0x4E +#define KA630_COL 0x50 +#define KA630_MINCOL 0x51 +#define KA630_MAXCOL 0x52 + #endif /* _VAX_INCLUDE_KA630_H_ */ diff --git a/sys/arch/vax/include/macros.h b/sys/arch/vax/include/macros.h index aeb2e365714..533935fd42b 100644 --- a/sys/arch/vax/include/macros.h +++ b/sys/arch/vax/include/macros.h @@ -1,8 +1,8 @@ -/* $OpenBSD: macros.h,v 1.9 2002/03/14 01:26:48 millert Exp $ */ -/* $NetBSD: macros.h,v 1.17 1998/11/07 17:22:58 ragge Exp $ */ +/* $OpenBSD: macros.h,v 1.10 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: macros.h,v 1.20 2000/07/19 01:02:52 matt Exp $ */ /* - * Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden. + * Copyright (c) 1994, 1998, 2000 Ludd, University of Lule}, Sweden. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -71,7 +71,7 @@ _insque(void *p, void *q) } static __inline__ void * -memcpy(void *toe, const void *from, u_int len) +memcpy(void *toe, const void *from, size_t len) { __asm__ __volatile ("movc3 %0,(%1),(%2)" : @@ -80,7 +80,7 @@ memcpy(void *toe, const void *from, u_int len) return toe; } static __inline__ void * -memmove(void *toe, const void *from, u_int len) +memmove(void *toe, const void *from, size_t len) { __asm__ __volatile ("movc3 %0,(%1),(%2)" : @@ -91,7 +91,7 @@ memmove(void *toe, const void *from, u_int len) #ifdef notnow static __inline__ void -bcopy(const void *from, void *toe, u_int len) +bcopy(const void *from, void *toe, size_t len) { __asm__ __volatile ("movc3 %0,(%1),(%2)" : @@ -100,7 +100,7 @@ bcopy(const void *from, void *toe, u_int len) } #endif -void blkclr(void *, u_int); +void blkclr __P((void *, size_t)); static __inline__ void * memset(void *block, int c, size_t len) @@ -117,7 +117,7 @@ memset(void *block, int c, size_t len) } static __inline__ void -bzero(void *block, u_int len) +bzero(void *block, size_t len) { if (len > 65535) blkclr(block, len); @@ -237,7 +237,7 @@ strcmp(const char *cp, const char *c2) /* End nya */ #if 0 /* unused, but no point in deleting it since it _is_ an instruction */ -static __inline__ int locc(int mask, char *cp,u_int size){ +static __inline__ int locc(int mask, char *cp, size_t size){ register ret; __asm__ __volatile("locc %1,%2,(%3);movl r0,%0" @@ -281,4 +281,62 @@ skpc(int mask, size_t size, u_char *cp) #define cpu_switch(p) \ __asm__ __volatile("movl %0,r0;movpsl -(sp);jsb Swtch" \ ::"g"(p):"r0","r1","r2","r3"); + +/* + * Interlock instructions. Used both in multiprocessor environments to + * lock between CPUs and in uniprocessor systems when locking is required + * between I/O devices and the master CPU. + */ +/* + * Insqti() locks and inserts an element into the end of a queue. + * Returns -1 if interlock failed, 1 if inserted OK and 0 if first in queue. + */ +static __inline__ int +insqti(void *entry, void *header) { + register int ret; + + __asm__ __volatile(" + mnegl $1,%0; + insqti (%1),(%2); + bcs 1f; # failed insert + beql 2f; # jump if first entry + movl $1,%0; + brb 1f; + 2: clrl %0; + 1:;" + : "=&g"(ret) + : "r"(entry), "r"(header) + : "memory"); + + return ret; +} + +/* + * Remqhi() removes an element from the head of the queue. + * Returns -1 if interlock failed, 0 if queue empty, address of the + * removed element otherwise. + */ +static __inline__ void * +remqhi(void *header) { + register void *ret; + + __asm__ __volatile(" + remqhi (%1),%0; + bcs 1f; # failed interlock + bvs 2f; # nothing was removed + brb 3f; + 1: mnegl $1,%0; + brb 3f; + 2: clrl %0; + 3:;" + : "=&g"(ret) + : "r"(header) + : "memory"); + + return ret; +} +#define ILCK_FAILED -1 /* Interlock failed */ +#define Q_EMPTY 0 /* Queue is/was empty */ +#define Q_OK 1 /* Inserted OK */ + #endif /* _VAX_MACROS_H_ */ diff --git a/sys/arch/vax/include/rpb.h b/sys/arch/vax/include/rpb.h index e1971e5371a..1f2ca79be23 100644 --- a/sys/arch/vax/include/rpb.h +++ b/sys/arch/vax/include/rpb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rpb.h,v 1.9 2002/03/15 01:20:04 millert Exp $ */ +/* $OpenBSD: rpb.h,v 1.10 2002/06/11 09:36:24 hugh Exp $ */ /* $NetBSD: rpb.h,v 1.6 1998/07/01 09:37:11 ragge Exp $ */ /* * Copyright (c) 1995 Ludd, University of Lule}, Sweden. @@ -125,5 +125,5 @@ struct rpb { /* size description */ #define BDEV_NET BDEV_QE /* first network BDEV */ #ifdef _KERNEL -extern struct rpb *rpb; +extern struct rpb rpb; #endif diff --git a/sys/arch/vax/include/types.h b/sys/arch/vax/include/types.h index f539c447eb7..0a2c66a1d3d 100644 --- a/sys/arch/vax/include/types.h +++ b/sys/arch/vax/include/types.h @@ -1,4 +1,4 @@ -/* $OpenBSD: types.h,v 1.10 2000/04/26 03:08:43 bjc Exp $ */ +/* $OpenBSD: types.h,v 1.11 2002/06/11 09:36:24 hugh Exp $ */ /* $NetBSD: types.h,v 1.14 1998/08/13 02:10:49 eeh Exp $ */ /*- @@ -77,4 +77,6 @@ typedef unsigned long long u_int64_t; typedef int32_t register_t; +#define __HAVE_DEVICE_REGISTER + #endif /* _MACHTYPES_H_ */ diff --git a/sys/arch/vax/mba/hpreg.h b/sys/arch/vax/mba/hpreg.h index f0255d329ca..76f6459923c 100644 --- a/sys/arch/vax/mba/hpreg.h +++ b/sys/arch/vax/mba/hpreg.h @@ -1,5 +1,5 @@ -/* $OpenBSD: hpreg.h,v 1.4 1997/05/29 00:04:59 niklas Exp $ */ -/* $NetBSD: hpreg.h,v 1.4 1996/02/11 13:19:35 ragge Exp $ */ +/* $OpenBSD: hpreg.h,v 1.5 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: hpreg.h,v 1.5 2000/06/04 18:04:39 ragge Exp $ */ /* * Copyright (c) 1994 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -30,6 +30,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifdef notdef struct hp_regs { int hp_cs1; int hp_ds; @@ -49,8 +50,24 @@ struct hp_regs { int hp_ec2; int utrymme[16]; }; +#endif -#define hp_drv hp_regs +#define HP_CS1 0 +#define HP_DS 4 +#define HP_ER1 8 +#define HP_MR1 12 +#define HP_AS 16 +#define HP_DA 20 +#define HP_DT 24 +#define HP_LA 28 +#define HP_SN 32 +#define HP_OF 36 +#define HP_DC 40 +#define HP_HR 44 +#define HP_MR2 48 +#define HP_ER2 52 +#define HP_EC1 56 +#define HP_EC2 60 #define HPCS_DVA 4000 /* Drive avail, in dual-port config */ #define HPCS_WRITE 061 /* Write data */ diff --git a/sys/arch/vax/mba/mbareg.h b/sys/arch/vax/mba/mbareg.h index e7a3fa6e4b3..427a7185edb 100644 --- a/sys/arch/vax/mba/mbareg.h +++ b/sys/arch/vax/mba/mbareg.h @@ -1,5 +1,5 @@ -/* $OpenBSD: mbareg.h,v 1.4 1997/05/29 00:05:00 niklas Exp $ */ -/* $NetBSD: mbareg.h,v 1.3 1996/02/11 13:19:38 ragge Exp $ */ +/* $OpenBSD: mbareg.h,v 1.5 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: mbareg.h,v 1.4 2000/06/04 18:04:39 ragge Exp $ */ /* * Copyright (c) 1994 Ludd, University of Lule}, Sweden * All rights reserved. @@ -30,6 +30,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifdef notdef struct mba_hack { u_int pad1; u_int md_ds; /* unit status */ @@ -53,6 +54,23 @@ struct mba_regs { struct mba_hack mba_md[8]; /* unit specific regs */ struct pte mba_map[256]; }; +#endif + +#define MBA_CSR 0 +#define MBA_CR 4 +#define MBA_SR 8 +#define MBA_VAR 12 +#define MBA_BC 16 +#define MBA_DR 20 +#define MBA_SMR 24 +#define MBA_CAR 28 + +#define MUREG(dev,reg) (1024+(dev)*128+(reg)) +#define MAPREG(nr) (2048+(nr)*4) + +#define MU_DS 4 /* unit status */ +#define MU_AS 16 /* attention summary */ +#define MU_DT 24 /* drive type */ /* * Different states which can be on massbus. diff --git a/sys/arch/vax/mba/mbavar.h b/sys/arch/vax/mba/mbavar.h index d1b51450027..0dca256e5c2 100644 --- a/sys/arch/vax/mba/mbavar.h +++ b/sys/arch/vax/mba/mbavar.h @@ -1,5 +1,5 @@ -/* $OpenBSD: mbavar.h,v 1.5 2002/03/14 01:26:48 millert Exp $ */ -/* $NetBSD: mbavar.h,v 1.5 2000/01/21 23:39:56 thorpej Exp $ */ +/* $OpenBSD: mbavar.h,v 1.6 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: mbavar.h,v 1.7 2000/06/04 18:04:39 ragge Exp $ */ /* * Copyright (c) 1994 Ludd, University of Lule}, Sweden * All rights reserved. @@ -31,6 +31,7 @@ */ #include <sys/device.h> +#include <machine/scb.h> #define MBCR_INIT 1 #define MBCR_IE (1<<2) @@ -78,10 +79,12 @@ enum xfer_action { * Info passed do unit device driver during autoconfig. */ struct mba_attach_args { - int unit; - int type; - char *name; - enum mb_devices devtyp; + int ma_unit; + int ma_type; + char *ma_name; + enum mb_devices ma_devtyp; + bus_space_tag_t ma_iot; + bus_space_handle_t ma_ioh; }; /* @@ -103,11 +106,11 @@ struct mba_device { struct mba_softc { struct device sc_dev; - struct ivec_dsp sc_dsp; /* Interrupt catch routine */ - struct mba_regs *sc_mbareg; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + struct evcnt sc_intrcnt; struct mba_device *sc_first, *sc_last; enum sc_state sc_state; - int sc_physnr; /* Physical number of this mba */ struct mba_device *sc_md[MAXMBADEV]; }; diff --git a/sys/arch/vax/qbus/if_de.c b/sys/arch/vax/qbus/if_de.c new file mode 100644 index 00000000000..03c71f53728 --- /dev/null +++ b/sys/arch/vax/qbus/if_de.c @@ -0,0 +1,641 @@ +/* $OpenBSD: if_de.c,v 1.1 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: if_de.c,v 1.11 2001/11/13 07:11:24 lukem Exp $ */ + +/* + * Copyright (c) 1982, 1986, 1989 Regents of the University of California. + * 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 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. + * + * @(#)if_de.c 7.12 (Berkeley) 12/16/90 + */ + +/* + * DEC DEUNA interface + * + * Lou Salkind + * New York University + * + * Rewritten by Ragge 30 April 2000 to match new world. + * + * TODO: + * timeout routine (get statistics) + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: if_de.c,v 1.11 2001/11/13 07:11:24 lukem Exp $"); + +#include "opt_inet.h" +#include "bpfilter.h" + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/buf.h> +#include <sys/protosw.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <sys/errno.h> +#include <sys/syslog.h> +#include <sys/device.h> + +#include <net/if.h> +#include <net/if_ether.h> +#include <net/if_dl.h> + +#ifdef INET +#include <netinet/in.h> +#include <netinet/if_inarp.h> +#endif + +#if NBPFILTER > 0 +#include <net/bpf.h> +#include <net/bpfdesc.h> +#endif + +#include <machine/bus.h> + +#include <dev/qbus/ubavar.h> +#include <dev/qbus/if_dereg.h> +#include <dev/qbus/if_uba.h> + +#include "ioconf.h" + +/* + * Be careful with transmit/receive buffers, each entry steals 4 map + * registers, and there is only 496 on one unibus... + */ +#define NRCV 7 /* number of receive buffers (must be > 1) */ +#define NXMT 3 /* number of transmit buffers */ + +/* + * Structure containing the elements that must be in DMA-safe memory. + */ +struct de_cdata { + /* the following structures are always mapped in */ + struct de_pcbb dc_pcbb; /* port control block */ + struct de_ring dc_xrent[NXMT]; /* transmit ring entrys */ + struct de_ring dc_rrent[NRCV]; /* receive ring entrys */ + struct de_udbbuf dc_udbbuf; /* UNIBUS data buffer */ + /* end mapped area */ +}; + +/* + * Ethernet software status per interface. + * + * Each interface is referenced by a network interface structure, + * ds_if, which the routing code uses to locate the interface. + * This structure contains the output queue for the interface, its address, ... + * We also have, for each interface, a UBA interface structure, which + * contains information about the UNIBUS resources held by the interface: + * map registers, buffered data paths, etc. Information is cached in this + * structure for use by the if_uba.c routines in running the interface + * efficiently. + */ +struct de_softc { + struct device sc_dev; /* Configuration common part */ + struct evcnt sc_intrcnt; /* Interrupt counting */ + 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; + int sc_flags; +#define DSF_MAPPED 1 + struct ubinfo sc_ui; + struct de_cdata *sc_dedata; /* Control structure */ + struct de_cdata *sc_pdedata; /* Bus-mapped control structure */ + struct ifubinfo sc_ifuba; /* UNIBUS resources */ + struct ifrw sc_ifr[NRCV]; /* UNIBUS receive buffer maps */ + struct ifxmt sc_ifw[NXMT]; /* UNIBUS receive buffer maps */ + + int sc_xindex; /* UNA index into transmit chain */ + int sc_rindex; /* UNA index into receive chain */ + int sc_xfree; /* index for next transmit buffer */ + int sc_nxmit; /* # of transmits in progress */ + void *sc_sh; /* shutdownhook cookie */ +}; + +static int dematch(struct device *, struct cfdata *, void *); +static void deattach(struct device *, struct device *, void *); +static void dewait(struct de_softc *, char *); +static int deinit(struct ifnet *); +static int deioctl(struct ifnet *, u_long, caddr_t); +static void dereset(struct device *); +static void destop(struct ifnet *, int); +static void destart(struct ifnet *); +static void derecv(struct de_softc *); +static void deintr(void *); +static void deshutdown(void *); + +struct cfattach de_ca = { + sizeof(struct de_softc), dematch, deattach +}; + +#define DE_WCSR(csr, val) \ + bus_space_write_2(sc->sc_iot, sc->sc_ioh, csr, val) +#define DE_WLOW(val) \ + bus_space_write_1(sc->sc_iot, sc->sc_ioh, DE_PCSR0, val) +#define DE_WHIGH(val) \ + bus_space_write_1(sc->sc_iot, sc->sc_ioh, DE_PCSR0 + 1, val) +#define DE_RCSR(csr) \ + bus_space_read_2(sc->sc_iot, sc->sc_ioh, csr) + +#define LOWORD(x) ((int)(x) & 0xffff) +#define HIWORD(x) (((int)(x) >> 16) & 0x3) +/* + * Interface exists: make available by filling in network interface + * record. System will initialize the interface when it is ready + * to accept packets. We get the ethernet address here. + */ +void +deattach(struct device *parent, struct device *self, void *aux) +{ + struct uba_attach_args *ua = aux; + struct de_softc *sc = (struct de_softc *)self; + struct ifnet *ifp = &sc->sc_if; + u_int8_t myaddr[ETHER_ADDR_LEN]; + int csr1, error; + char *c; + + sc->sc_iot = ua->ua_iot; + sc->sc_ioh = ua->ua_ioh; + sc->sc_dmat = ua->ua_dmat; + + /* + * What kind of a board is this? + * The error bits 4-6 in pcsr1 are a device id as long as + * the high byte is zero. + */ + csr1 = DE_RCSR(DE_PCSR1); + if (csr1 & 0xff60) + c = "broken"; + else if (csr1 & 0x10) + c = "delua"; + else + c = "deuna"; + + /* + * Reset the board and temporarily map + * the pcbb buffer onto the Unibus. + */ + DE_WCSR(DE_PCSR0, 0); /* reset INTE */ + DELAY(100); + DE_WCSR(DE_PCSR0, PCSR0_RSET); + dewait(sc, "reset"); + + sc->sc_ui.ui_size = sizeof(struct de_cdata); + if ((error = ubmemalloc((struct uba_softc *)parent, &sc->sc_ui, 0))) + return printf(": failed ubmemalloc(), error = %d\n", error); + sc->sc_dedata = (struct de_cdata *)sc->sc_ui.ui_vaddr; + + /* + * Tell the DEUNA about our PCB + */ + DE_WCSR(DE_PCSR2, LOWORD(sc->sc_ui.ui_baddr)); + DE_WCSR(DE_PCSR3, HIWORD(sc->sc_ui.ui_baddr)); + DE_WLOW(CMD_GETPCBB); + dewait(sc, "pcbb"); + + sc->sc_dedata->dc_pcbb.pcbb0 = FC_RDPHYAD; + DE_WLOW(CMD_GETCMD); + dewait(sc, "read addr "); + + bcopy((caddr_t)&sc->sc_dedata->dc_pcbb.pcbb2, myaddr, sizeof (myaddr)); + printf("\n%s: %s, hardware address %s\n", sc->sc_dev.dv_xname, c, + ether_sprintf(myaddr)); + + uba_intr_establish(ua->ua_icookie, ua->ua_cvec, deintr, sc, + &sc->sc_intrcnt); + uba_reset_establish(dereset, &sc->sc_dev); + evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt, + sc->sc_dev.dv_xname, "intr"); + + strcpy(ifp->if_xname, sc->sc_dev.dv_xname); + ifp->if_softc = sc; + ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI; + ifp->if_ioctl = deioctl; + ifp->if_start = destart; + ifp->if_init = deinit; + ifp->if_stop = destop; + IFQ_SET_READY(&ifp->if_snd); + + if_attach(ifp); + ether_ifattach(ifp, myaddr); + ubmemfree((struct uba_softc *)parent, &sc->sc_ui); + + sc->sc_sh = shutdownhook_establish(deshutdown, sc); +} + +void +destop(struct ifnet *ifp, int a) +{ + struct de_softc *sc = ifp->if_softc; + + DE_WLOW(0); + DELAY(5000); + DE_WLOW(PCSR0_RSET); +} + + +/* + * Reset of interface after UNIBUS reset. + */ +void +dereset(struct device *dev) +{ + struct de_softc *sc = (void *)dev; + + sc->sc_if.if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + sc->sc_flags &= ~DSF_MAPPED; + sc->sc_pdedata = NULL; /* All mappings lost */ + DE_WCSR(DE_PCSR0, PCSR0_RSET); + dewait(sc, "reset"); + deinit(&sc->sc_if); +} + +/* + * Initialization of interface; clear recorded pending + * operations, and reinitialize UNIBUS usage. + */ +int +deinit(struct ifnet *ifp) +{ + struct de_softc *sc = ifp->if_softc; + struct de_cdata *dc, *pdc; + struct ifrw *ifrw; + struct ifxmt *ifxp; + struct de_ring *rp; + int s, error; + + if (ifp->if_flags & IFF_RUNNING) + return 0; + if ((sc->sc_flags & DSF_MAPPED) == 0) { + if (if_ubaminit(&sc->sc_ifuba, (void *)sc->sc_dev.dv_parent, + MCLBYTES, sc->sc_ifr, NRCV, sc->sc_ifw, NXMT)) { + printf("%s: can't initialize\n", sc->sc_dev.dv_xname); + ifp->if_flags &= ~IFF_UP; + return 0; + } + sc->sc_ui.ui_size = sizeof(struct de_cdata); + if ((error = ubmemalloc((void *)sc->sc_dev.dv_parent, + &sc->sc_ui, 0))) { + printf(": unable to ubmemalloc(), error = %d\n", error); + return 0; + } + sc->sc_pdedata = (struct de_cdata *)sc->sc_ui.ui_baddr; + sc->sc_dedata = (struct de_cdata *)sc->sc_ui.ui_vaddr; + sc->sc_flags |= DSF_MAPPED; + } + + /* + * Tell the DEUNA about our PCB + */ + DE_WCSR(DE_PCSR2, LOWORD(sc->sc_pdedata)); + DE_WCSR(DE_PCSR3, HIWORD(sc->sc_pdedata)); + DE_WLOW(0); /* reset INTE */ + DELAY(500); + DE_WLOW(CMD_GETPCBB); + dewait(sc, "pcbb"); + + dc = sc->sc_dedata; + pdc = sc->sc_pdedata; + /* set the transmit and receive ring header addresses */ + dc->dc_pcbb.pcbb0 = FC_WTRING; + dc->dc_pcbb.pcbb2 = LOWORD(&pdc->dc_udbbuf); + dc->dc_pcbb.pcbb4 = HIWORD(&pdc->dc_udbbuf); + + dc->dc_udbbuf.b_tdrbl = LOWORD(&pdc->dc_xrent[0]); + dc->dc_udbbuf.b_tdrbh = HIWORD(&pdc->dc_xrent[0]); + dc->dc_udbbuf.b_telen = sizeof (struct de_ring) / sizeof(u_int16_t); + dc->dc_udbbuf.b_trlen = NXMT; + dc->dc_udbbuf.b_rdrbl = LOWORD(&pdc->dc_rrent[0]); + dc->dc_udbbuf.b_rdrbh = HIWORD(&pdc->dc_rrent[0]); + dc->dc_udbbuf.b_relen = sizeof (struct de_ring) / sizeof(u_int16_t); + dc->dc_udbbuf.b_rrlen = NRCV; + + DE_WLOW(CMD_GETCMD); + dewait(sc, "wtring"); + + sc->sc_dedata->dc_pcbb.pcbb0 = FC_WTMODE; + sc->sc_dedata->dc_pcbb.pcbb2 = MOD_TPAD|MOD_HDX|MOD_DRDC|MOD_ENAL; + DE_WLOW(CMD_GETCMD); + dewait(sc, "wtmode"); + + /* set up the receive and transmit ring entries */ + ifxp = &sc->sc_ifw[0]; + for (rp = &dc->dc_xrent[0]; rp < &dc->dc_xrent[NXMT]; rp++) { + rp->r_segbl = LOWORD(ifxp->ifw_info); + rp->r_segbh = HIWORD(ifxp->ifw_info); + rp->r_flags = 0; + ifxp++; + } + ifrw = &sc->sc_ifr[0]; + for (rp = &dc->dc_rrent[0]; rp < &dc->dc_rrent[NRCV]; rp++) { + rp->r_slen = MCLBYTES - 2; + rp->r_segbl = LOWORD(ifrw->ifrw_info); + rp->r_segbh = HIWORD(ifrw->ifrw_info); + rp->r_flags = RFLG_OWN; + ifrw++; + } + + /* start up the board (rah rah) */ + s = splnet(); + sc->sc_rindex = sc->sc_xindex = sc->sc_xfree = sc->sc_nxmit = 0; + sc->sc_if.if_flags |= IFF_RUNNING; + DE_WLOW(PCSR0_INTE); /* avoid interlock */ + destart(&sc->sc_if); /* queue output packets */ + DE_WLOW(CMD_START|PCSR0_INTE); + splx(s); + return 0; +} + +/* + * Setup output on interface. + * Get another datagram to send off of the interface queue, + * and map it to the interface before starting the output. + * Must be called from ipl >= our interrupt level. + */ +void +destart(struct ifnet *ifp) +{ + struct de_softc *sc = ifp->if_softc; + struct de_cdata *dc; + struct de_ring *rp; + struct mbuf *m; + int nxmit, len; + + /* + * the following test is necessary, since + * the code is not reentrant and we have + * multiple transmission buffers. + */ + if (sc->sc_if.if_flags & IFF_OACTIVE) + return; + dc = sc->sc_dedata; + for (nxmit = sc->sc_nxmit; nxmit < NXMT; nxmit++) { + IFQ_DEQUEUE(&ifp->if_snd, m); + if (m == 0) + break; + + rp = &dc->dc_xrent[sc->sc_xfree]; + if (rp->r_flags & XFLG_OWN) + panic("deuna xmit in progress"); +#if NBPFILTER > 0 + if (ifp->if_bpf) + bpf_mtap(ifp->if_bpf, m); +#endif + + len = if_ubaput(&sc->sc_ifuba, &sc->sc_ifw[sc->sc_xfree], m); + rp->r_slen = len; + rp->r_tdrerr = 0; + rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN; + + sc->sc_xfree++; + if (sc->sc_xfree == NXMT) + sc->sc_xfree = 0; + } + if (sc->sc_nxmit != nxmit) { + sc->sc_nxmit = nxmit; + if (ifp->if_flags & IFF_RUNNING) + DE_WLOW(PCSR0_INTE|CMD_PDMD); + } +} + +/* + * Command done interrupt. + */ +void +deintr(void *arg) +{ + struct ifxmt *ifxp; + struct de_cdata *dc; + struct de_softc *sc = arg; + struct de_ring *rp; + short csr0; + + /* save flags right away - clear out interrupt bits */ + csr0 = DE_RCSR(DE_PCSR0); + DE_WHIGH(csr0 >> 8); + + + sc->sc_if.if_flags |= IFF_OACTIVE; /* prevent entering destart */ + /* + * if receive, put receive buffer on mbuf + * and hang the request again + */ + derecv(sc); + + /* + * Poll transmit ring and check status. + * Be careful about loopback requests. + * Then free buffer space and check for + * more transmit requests. + */ + dc = sc->sc_dedata; + for ( ; sc->sc_nxmit > 0; sc->sc_nxmit--) { + rp = &dc->dc_xrent[sc->sc_xindex]; + if (rp->r_flags & XFLG_OWN) + break; + + sc->sc_if.if_opackets++; + ifxp = &sc->sc_ifw[sc->sc_xindex]; + /* check for unusual conditions */ + if (rp->r_flags & (XFLG_ERRS|XFLG_MTCH|XFLG_ONE|XFLG_MORE)) { + if (rp->r_flags & XFLG_ERRS) { + /* output error */ + sc->sc_if.if_oerrors++; + } else if (rp->r_flags & XFLG_ONE) { + /* one collision */ + sc->sc_if.if_collisions++; + } else if (rp->r_flags & XFLG_MORE) { + /* more than one collision */ + sc->sc_if.if_collisions += 2; /* guess */ + } + } + if_ubaend(&sc->sc_ifuba, ifxp); + /* check if next transmit buffer also finished */ + sc->sc_xindex++; + if (sc->sc_xindex == NXMT) + sc->sc_xindex = 0; + } + sc->sc_if.if_flags &= ~IFF_OACTIVE; + destart(&sc->sc_if); + + if (csr0 & PCSR0_RCBI) { + DE_WLOW(PCSR0_INTE|CMD_PDMD); + } +} + +/* + * Ethernet interface receiver interface. + * If input error just drop packet. + * Otherwise purge input buffered data path and examine + * packet to determine type. If can't determine length + * from type, then have to drop packet. Othewise decapsulate + * packet based on type and pass to type specific higher-level + * input routine. + */ +void +derecv(struct de_softc *sc) +{ + struct ifnet *ifp = &sc->sc_if; + struct de_ring *rp; + struct de_cdata *dc; + struct mbuf *m; + int len; + + dc = sc->sc_dedata; + rp = &dc->dc_rrent[sc->sc_rindex]; + while ((rp->r_flags & RFLG_OWN) == 0) { + sc->sc_if.if_ipackets++; + len = (rp->r_lenerr&RERR_MLEN) - ETHER_CRC_LEN; + /* check for errors */ + if ((rp->r_flags & (RFLG_ERRS|RFLG_FRAM|RFLG_OFLO|RFLG_CRC)) || + (rp->r_lenerr & (RERR_BUFL|RERR_UBTO))) { + sc->sc_if.if_ierrors++; + goto next; + } + m = if_ubaget(&sc->sc_ifuba, &sc->sc_ifr[sc->sc_rindex], + ifp, len); + if (m == 0) { + sc->sc_if.if_ierrors++; + goto next; + } +#if NBPFILTER > 0 + if (ifp->if_bpf) + bpf_mtap(ifp->if_bpf, m); +#endif + + (*ifp->if_input)(ifp, m); + + /* hang the receive buffer again */ +next: rp->r_lenerr = 0; + rp->r_flags = RFLG_OWN; + + /* check next receive buffer */ + sc->sc_rindex++; + if (sc->sc_rindex == NRCV) + sc->sc_rindex = 0; + rp = &dc->dc_rrent[sc->sc_rindex]; + } +} + +/* + * Process an ioctl request. + */ +int +deioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +{ + int s, error = 0; + + s = splnet(); + + error = ether_ioctl(ifp, cmd, data); + if (error == ENETRESET) + error = 0; + + splx(s); + return (error); +} + +/* + * Await completion of the named function + * and check for errors. + */ +void +dewait(struct de_softc *sc, char *fn) +{ + int csr0; + + while ((DE_RCSR(DE_PCSR0) & PCSR0_INTR) == 0) + ; + csr0 = DE_RCSR(DE_PCSR0); + DE_WHIGH(csr0 >> 8); + if (csr0 & PCSR0_PCEI) { + char bits[64]; + printf("%s: %s failed, csr0=%s ", sc->sc_dev.dv_xname, fn, + bitmask_snprintf(csr0, PCSR0_BITS, bits, sizeof(bits))); + printf("csr1=%s\n", bitmask_snprintf(DE_RCSR(DE_PCSR1), + PCSR1_BITS, bits, sizeof(bits))); + } +} + +int +dematch(struct device *parent, struct cfdata *cf, void *aux) +{ + struct uba_attach_args *ua = aux; + struct de_softc ssc; + struct de_softc *sc = &ssc; + int i; + + sc->sc_iot = ua->ua_iot; + sc->sc_ioh = ua->ua_ioh; + /* + * Make sure self-test is finished before we screw with the board. + * Self-test on a DELUA can take 15 seconds (argh). + */ + for (i = 0; + (i < 160) && + (DE_RCSR(DE_PCSR0) & PCSR0_FATI) == 0 && + (DE_RCSR(DE_PCSR1) & PCSR1_STMASK) == STAT_RESET; + ++i) + DELAY(50000); + if (((DE_RCSR(DE_PCSR0) & PCSR0_FATI) != 0) || + (((DE_RCSR(DE_PCSR1) & PCSR1_STMASK) != STAT_READY) && + ((DE_RCSR(DE_PCSR1) & PCSR1_STMASK) != STAT_RUN))) + return(0); + + DE_WCSR(DE_PCSR0, 0); + DELAY(5000); + DE_WCSR(DE_PCSR0, PCSR0_RSET); + while ((DE_RCSR(DE_PCSR0) & PCSR0_INTR) == 0) + ; + /* make board interrupt by executing a GETPCBB command */ + DE_WCSR(DE_PCSR0, PCSR0_INTE); + DE_WCSR(DE_PCSR2, 0); + DE_WCSR(DE_PCSR3, 0); + DE_WCSR(DE_PCSR0, PCSR0_INTE|CMD_GETPCBB); + DELAY(50000); + + return 1; +} + +void +deshutdown(void *arg) +{ + struct de_softc *sc = arg; + + DE_WCSR(DE_PCSR0, 0); + DELAY(1000); + DE_WCSR(DE_PCSR0, PCSR0_RSET); + dewait(sc, "shutdown"); +} diff --git a/sys/arch/vax/qbus/if_dereg.h b/sys/arch/vax/qbus/if_dereg.h new file mode 100644 index 00000000000..54da29f4bf1 --- /dev/null +++ b/sys/arch/vax/qbus/if_dereg.h @@ -0,0 +1,221 @@ +/* $OpenBSD: if_dereg.h,v 1.1 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: if_dereg.h,v 1.2 2000/05/28 17:23:44 ragge Exp $ */ + +/* + * Copyright (c) 1982, 1986 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. 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. + * + * @(#)if_dereg.h 7.3 (Berkeley) 6/28/90 + */ + +/* + * DEC DEUNA interface + */ +#ifdef notdef +struct dedevice { + union { + short p0_w; + char p0_b[2]; + } u_p0; +#define pcsr0 u_p0.p0_w +#define pclow u_p0.p0_b[0] +#define pchigh u_p0.p0_b[1] + short pcsr1; + short pcsr2; + short pcsr3; +}; +#endif + +#define DE_PCSR0 0 +#define DE_PCSR1 2 +#define DE_PCSR2 4 +#define DE_PCSR3 6 + +/* + * PCSR 0 bit descriptions + */ +#define PCSR0_SERI 0x8000 /* Status error interrupt */ +#define PCSR0_PCEI 0x4000 /* Port command error interrupt */ +#define PCSR0_RXI 0x2000 /* Receive done interrupt */ +#define PCSR0_TXI 0x1000 /* Transmit done interrupt */ +#define PCSR0_DNI 0x0800 /* Done interrupt */ +#define PCSR0_RCBI 0x0400 /* Receive buffer unavail intrpt */ +#define PCSR0_FATI 0x0100 /* Fatal error interrupt */ +#define PCSR0_INTR 0x0080 /* Interrupt summary */ +#define PCSR0_INTE 0x0040 /* Interrupt enable */ +#define PCSR0_RSET 0x0020 /* DEUNA reset */ +#define PCSR0_CMASK 0x000f /* command mask */ + +#define PCSR0_BITS "\20\20SERI\17PCEI\16RXI\15TXI\14DNI\13RCBI\11FATI\10INTR\7INTE\6RSET" + +/* bits 0-3 are for the PORT_COMMAND */ +#define CMD_NOOP 0x0 +#define CMD_GETPCBB 0x1 /* Get PCB Block */ +#define CMD_GETCMD 0x2 /* Execute command in PCB */ +#define CMD_STEST 0x3 /* Self test mode */ +#define CMD_START 0x4 /* Reset xmit and receive ring ptrs */ +#define CMD_BOOT 0x5 /* Boot DEUNA */ +#define CMD_PDMD 0x8 /* Polling demand */ +#define CMD_TMRO 0x9 /* Sanity timer on */ +#define CMD_TMRF 0xa /* Sanity timer off */ +#define CMD_RSTT 0xb /* Reset sanity timer */ +#define CMD_STOP 0xf /* Suspend operation */ + +/* + * PCSR 1 bit descriptions + */ +#define PCSR1_XPWR 0x8000 /* Transceiver power BAD */ +#define PCSR1_ICAB 0x4000 /* Interconnect cabling BAD */ +#define PCSR1_STCODE 0x3f00 /* Self test error code */ +#define PCSR1_PCTO 0x0080 /* Port command timed out */ +#define PCSR1_ILLINT 0x0040 /* Illegal interrupt */ +#define PCSR1_TIMEOUT 0x0020 /* Timeout */ +#define PCSR1_POWER 0x0010 /* Power fail */ +#define PCSR1_RMTC 0x0008 /* Remote console reserved */ +#define PCSR1_STMASK 0x0007 /* State */ + +/* bit 0-3 are for STATE */ +#define STAT_RESET 0x0 +#define STAT_PRIMLD 0x1 /* Primary load */ +#define STAT_READY 0x2 +#define STAT_RUN 0x3 +#define STAT_UHALT 0x5 /* UNIBUS halted */ +#define STAT_NIHALT 0x6 /* NI halted */ +#define STAT_NIUHALT 0x7 /* NI and UNIBUS Halted */ + +#define PCSR1_BITS "\20\20XPWR\17ICAB\10PCTO\7ILLINT\6TIMEOUT\5POWER\4RMTC" + +/* + * Port Control Block Base + */ +struct de_pcbb { + int16_t pcbb0; /* function */ + int16_t pcbb2; /* command specific */ + int16_t pcbb4; + int16_t pcbb6; +}; + +/* PCBB function codes */ +#define FC_NOOP 0x00 /* NO-OP */ +#define FC_LSUADDR 0x01 /* Load and start microaddress */ +#define FC_RDDEFAULT 0x02 /* Read default physical address */ +#define FC_RDPHYAD 0x04 /* Read physical address */ +#define FC_WTPHYAD 0x05 /* Write physical address */ +#define FC_RDMULTI 0x06 /* Read multicast address list */ +#define FC_WTMULTI 0x07 /* Read multicast address list */ +#define FC_RDRING 0x08 /* Read ring format */ +#define FC_WTRING 0x09 /* Write ring format */ +#define FC_RDCNTS 0x0a /* Read counters */ +#define FC_RCCNTS 0x0b /* Read and clear counters */ +#define FC_RDMODE 0x0c /* Read mode */ +#define FC_WTMODE 0x0d /* Write mode */ +#define FC_RDSTATUS 0x0e /* Read port status */ +#define FC_RCSTATUS 0x0f /* Read and clear port status */ +#define FC_DUMPMEM 0x10 /* Dump internal memory */ +#define FC_LOADMEM 0x11 /* Load internal memory */ +#define FC_RDSYSID 0x12 /* Read system ID parameters */ +#define FC_WTSYSID 0x13 /* Write system ID parameters */ +#define FC_RDSERAD 0x14 /* Read load server address */ +#define FC_WTSERAD 0x15 /* Write load server address */ + +/* + * Unibus Data Block Base (UDBB) for ring buffers + */ +struct de_udbbuf { + int16_t b_tdrbl; /* Transmit desc ring base low 16 bits */ + int8_t b_tdrbh; /* Transmit desc ring base high 2 bits */ + int8_t b_telen; /* Length of each transmit entry */ + int16_t b_trlen; /* Number of entries in the XMIT desc ring */ + int16_t b_rdrbl; /* Receive desc ring base low 16 bits */ + int8_t b_rdrbh; /* Receive desc ring base high 2 bits */ + int8_t b_relen; /* Length of each receive entry */ + int16_t b_rrlen; /* Number of entries in the RECV desc ring */ +}; + +/* + * Transmit/Receive Ring Entry + */ +struct de_ring { + int16_t r_slen; /* Segment length */ + int16_t r_segbl; /* Segment address (low 16 bits) */ + int8_t r_segbh; /* Segment address (hi 2 bits) */ + u_int8_t r_flags; /* Status flags */ + u_int16_t r_tdrerr; /* Errors */ +#define r_lenerr r_tdrerr +}; + +#define XFLG_OWN 0x80 /* If 0 then owned by driver */ +#define XFLG_ERRS 0x40 /* Error summary */ +#define XFLG_MTCH 0x20 /* Address match on xmit request */ +#define XFLG_MORE 0x10 /* More than one entry required */ +#define XFLG_ONE 0x08 /* One collision encountered */ +#define XFLG_DEF 0x04 /* Transmit deferred */ +#define XFLG_STP 0x02 /* Start of packet */ +#define XFLG_ENP 0x01 /* End of packet */ + +#define XFLG_BITS "\10\10OWN\7ERRS\6MTCH\5MORE\4ONE\3DEF\2STP\1ENP" + +#define XERR_BUFL 0x8000 /* Buffer length error */ +#define XERR_UBTO 0x4000 /* UNIBUS tiemout */ +#define XERR_LCOL 0x1000 /* Late collision */ +#define XERR_LCAR 0x0800 /* Loss of carrier */ +#define XERR_RTRY 0x0400 /* Failed after 16 retries */ +#define XERR_TDR 0x03ff /* TDR value */ + +#define XERR_BITS "\20\20BUFL\17UBTO\15LCOL\14LCAR\13RTRY" + +#define RFLG_OWN 0x80 /* If 0 then owned by driver */ +#define RFLG_ERRS 0x40 /* Error summary */ +#define RFLG_FRAM 0x20 /* Framing error */ +#define RFLG_OFLO 0x10 /* Message overflow */ +#define RFLG_CRC 0x08 /* CRC error */ +#define RFLG_STP 0x02 /* Start of packet */ +#define RFLG_ENP 0x01 /* End of packet */ + +#define RFLG_BITS "\10\10OWN\7ERRS\6FRAM\5OFLO\4CRC\2STP\1ENP" + +#define RERR_BUFL 0x8000 /* Buffer length error */ +#define RERR_UBTO 0x4000 /* UNIBUS tiemout */ +#define RERR_NCHN 0x2000 /* No data chaining */ +#define RERR_MLEN 0x0fff /* Message length */ + +#define RERR_BITS "\20\20BUFL\17UBTO\16NCHN" + +/* mode description bits */ +#define MOD_HDX 0x0001 /* Half duplex mode */ +#define MOD_LOOP 0x0004 /* Enable internal loopback */ +#define MOD_DTCR 0x0008 /* Disables CRC generation */ +#define MOD_DMNT 0x0200 /* Disable maintenance features */ +#define MOD_ECT 0x0400 /* Enable collision test */ +#define MOD_TPAD 0x1000 /* Transmit message pad enable */ +#define MOD_DRDC 0x2000 /* Disable data chaining */ +#define MOD_ENAL 0x4000 /* Enable all multicast */ +#define MOD_PROM 0x8000 /* Enable promiscuous mode */ diff --git a/sys/arch/vax/stand/Makefile.inc b/sys/arch/vax/stand/Makefile.inc index 1df25851203..bbe032e06d2 100644 --- a/sys/arch/vax/stand/Makefile.inc +++ b/sys/arch/vax/stand/Makefile.inc @@ -1,12 +1,11 @@ -# $OpenBSD: Makefile.inc,v 1.2 2000/10/04 04:03:10 bjc Exp $ -# $NetBSD: Makefile.inc,v 1.2 1999/07/18 05:55:45 abs Exp $ +# $OpenBSD: Makefile.inc,v 1.3 2002/06/11 09:36:23 hugh Exp $ +# $NetBSD: Makefile.inc,v 1.6 2002/02/24 01:04:23 matt Exp $ -XXRPB=0x354240 RELOC=0x39F000 .PATH: ${.CURDIR}/../../vax ${.CURDIR}/../common -CPPFLAGS+=-I${.CURDIR}/../../../../ -I${.CURDIR}/../../ -I${.CURDIR}/../common -I${.CURDIR}/../../include -CPPFLAGS+=-DXXRPB=${XXRPB} -DRELOC=${RELOC} +CPPFLAGS+=-I. -I${.CURDIR}/../../../../ -I${.CURDIR}/../../ -I${.CURDIR}/../common -I${.CURDIR}/../../include +CPPFLAGS+=-DRELOC=${RELOC} # Private handling of assembler files. .s.o: diff --git a/sys/arch/vax/stand/boot/Makefile b/sys/arch/vax/stand/boot/Makefile index 49f3c3cb072..b48472504f1 100644 --- a/sys/arch/vax/stand/boot/Makefile +++ b/sys/arch/vax/stand/boot/Makefile @@ -1,23 +1,27 @@ -# $OpenBSD: Makefile,v 1.3 2002/02/14 20:45:31 deraadt Exp $ -# $NetBSD: Makefile,v 1.4 1999/05/23 21:58:19 ragge Exp $ +# $OpenBSD: Makefile,v 1.4 2002/06/11 09:36:23 hugh Exp $ +# $NetBSD: Makefile,v 1.27 2002/04/07 07:00:25 matt Exp $ S!= cd ${.CURDIR}/../../../../; pwd +NOMAN= # defined + +.include <bsd.own.mk> -NOMAN= 1 PROG= boot -DEVS= hp.c ctu.c ra.c tmscp.c mfm.c if_qe.c if_le.c if_ze.c -SRCS= srt0.s boot.c devopen.c conf.c autoconf.c netio.c rom.c romread.s \ - urem.s udiv.s consio.c str.s ${DEVS} findcpu.c -#OBJS= autoconf.o boot.o conf.o consio.o ctu.o devopen.o findcpu.o hp.o \ -# if_le.o if_qe.o if_ze.o mfm.o netio.o ra.o rom.o romread.o srt0.o \ -# str.o tmscp.o udiv.o urem.o - -CLEANFILES+=${PROG}.mop -CPPFLAGS+=-DSUPPORT_BOOTPARAMS -DSUPPORT_DHCP -D_STANDALONE +WARNS?= 1 +DEVS= hp.c ctu.c ra.c mfm.c if_qe.c if_le.c if_ze.c if_de.c if_ni.c +SRCS= srt0.S boot.c devopen.c conf.c autoconf.c netio.c rom.c romread.S \ + urem.s udiv.s consio.c consio2.S str.S ${DEVS} findcpu.c + +CLEANFILES+=${PROG} ${PROG}.sym +CPPFLAGS+=-DSUPPORT_BOOTPARAMS -DSUPPORT_DHCP -D_STANDALONE \ + -DNO_MID_CHECK #CPPFLAGS+=-DBOOTP_DEBUG -DNETIF_DEBUG -DETHER_DEBUG -DNFS_DEBUG -DDEV_DEBUG \ -# -DRPC_DEBUG -DRARP_DEBUG -DPARANOID -DSUPPORT_BOOTP -BINDIR= /usr/mdec +# -DRPC_DEBUG -DRARP_DEBUG -DPARANOID + +BINDIR=/usr/mdec +#SA_AS= library +#SAMISCMAKEFLAGS=SA_USE_CREAD=yes SA_INCLUDE_NET=yes SA_USE_LOADFILE=yes SA_ZLIB= yes SAREL= .include "${S}/lib/libsa/Makefile.inc" @@ -32,15 +36,36 @@ LIBZ= ${ZLIB} #.include "${S}/lib/libkern/Makefile.inc" #LIBKERN=${KERNLIB} -boot: ${OBJS} ${SALIB} ${LIBZ} ${LIBKERN} - ld -N -Ttext ${RELOC} -e nisse -o ${PROG} -Llib/sa -L. ${OBJS} \ - ${LIBSA} ${LIBZ} -lsa ${LIBKERN} - /usr/sbin/mopa.out ${PROG} ${PROG}.mop - strip ${PROG} - size ${PROG} +.if ${MACHINE} == "vax" +.PHONY: machine-links +beforedepend: machine-links +machine-links: + @rm -f machine && ln -s ${S}/arch/${MACHINE}/include machine + @rm -f ${MACHINE_ARCH} && ln -s ${S}/arch/${MACHINE_ARCH}/include ${MACHINE_ARCH} +.NOPATH: machine ${MACHINE_ARCH} +CLEANFILES+= machine ${MACHINE_ARCH} +.endif + +#.if ${OBJECT_FMT} == "ELF" +#START=start +#.else +START=nisse +#.endif + +${PROG}: machine-links ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN} + ${LD} -N -Ttext ${RELOC} -e ${START} -o ${PROG}.sym -Llib/sa -L. ${OBJS} \ + ${LIBSA} ${LIBZ} ${LIBSA} ${LIBKERN} + /usr/sbin/mopa.out ${PROG}.sym ${PROG}.mop + /bin/cp ${PROG}.sym ${PROG} + /usr/bin/strip ${PROG} + /usr/bin/size ${PROG} clean:: rm -f a.out [Ee]rrs mklog core *.core ${PROG} ${OBJS} ${LOBJS} \ ${CLEANFILES} +#install: +# ${INSTALL_FILE} -o ${BINOWN} -g ${BINGRP} -m 555 \ +# ${PROG} ${DESTDIR}${MDEC_DIR}/${PROG} + .include <bsd.prog.mk> diff --git a/sys/arch/vax/stand/boot/autoconf.c b/sys/arch/vax/stand/boot/autoconf.c index d3fe75802ce..00a2db03583 100644 --- a/sys/arch/vax/stand/boot/autoconf.c +++ b/sys/arch/vax/stand/boot/autoconf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: autoconf.c,v 1.7 2002/03/09 03:36:33 hugh Exp $ */ -/* $NetBSD: autoconf.c,v 1.5 1999/08/23 19:09:27 ragge Exp $ */ +/* $OpenBSD: autoconf.c,v 1.8 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: autoconf.c,v 1.19 2002/06/01 15:33:22 ragge Exp $ */ /* * Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -34,112 +34,65 @@ -#include "sys/param.h" +#include <sys/param.h> + +#include <lib/libsa/stand.h> + #include "../../include/mtpr.h" #include "../../include/sid.h" +#include "../../include/intr.h" +#include "../../include/rpb.h" #include "../../include/scb.h" #include "vaxstand.h" -extern const struct ivec_dsp idsptch; /* since we are not KERNEL */ - -int nmba=0, nuba=0, nbi=0,nsbi=0,nuda=0; -int *mbaaddr, *ubaaddr, *biaddr; -int *udaaddr, *uioaddr, tmsaddr, *bioaddr; - -static int mba750[]={0xf28000,0xf2a000,0xf2c000}; -static int uba750[]={0xf30000,0xf32000}; -static int uio750[]={0xfc0000,0xf80000}; -static int uda750[]={0772150}; - -/* 11/780's only have 4, 8600 have 8 of these. */ -/* XXX - all of these should be bound to physical addresses */ -static int mba780[]={0x20010000,0x20012000,0x20014000,0x20016000, - 0x22010000,0x22012000,0x22014000,0x22016000}; -static int uba780[]={0, 0, 0, 0x20006000,0x20008000,0x2000a000,0x2000c000, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x22006000,0x22008000,0x2200a000,0x2200c000}; -static int uio780[]={0, 0, 0, 0x20100000,0x20140000,0x20180000,0x201c0000, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x22100000,0x22140000,0x22180000,0x221c0000}; -static int bi8200[]={0x20000000, 0x22000000, 0x24000000, 0x26000000, - 0x28000000, 0x2a000000}; -static int bio8200[]={0x20400000}; - -static int uba630[]={0x20087800}; -static int uio630[]={0x30000000}; -#define qbdev(csr) (((csr) & 017777)-0x10000000) -static int uda630[]={qbdev(0772150),qbdev(0760334)}; - -static int uba670[]={0x20040000}; -static int uio670[]={0x20000000}; -static int uda670[]={0x20004030,0x20004230}; -#define qb670dev(csr) (((csr) & 017777)+0x20000000) +void autoconf(void); +void findcpu(void); +void consinit(void); +void scbinit(void); +int getsecs(void); +void scb_stray(void *); +void longjmp(int *, int); +void rtimer(void *); + +long *bootregs; /* - * Autoconf routine is really stupid; but it actually don't - * need any intelligence. We just assume that all possible - * devices exists on each cpu. Fast & easy. + * Do some initial setup. Also create a fake RPB for net-booted machines + * that don't have an in-prom VMB. */ +void autoconf() { - extern int memsz; int copyrpb = 1; + int fromnet = (bootregs[12] != -1); findcpu(); /* Configures CPU variables */ consinit(); /* Allow us to print out things */ scbinit(); /* Fix interval clock etc */ +#ifdef DEV_DEBUG + printf("Register contents:\n"); + for (copyrpb = 0; copyrpb < 13; copyrpb++) + printf("r%d: %lx\n", copyrpb, bootregs[copyrpb]); +#endif switch (vax_boardtype) { - default: - printf("\nCPU type %d not supported by boot\n",vax_cputype); - printf("trying anyway...\n"); - break; - case VAX_BTYP_780: case VAX_BTYP_790: - memsz = 0; - nmba = 8; - nuba = 32; /* XXX */ - nuda = 1; - mbaaddr = mba780; - ubaaddr = uba780; - udaaddr = uda750; - uioaddr = uio780; - tmsaddr = 0774500; - break; - - case VAX_BTYP_750: - memsz = 0; - nmba = 3; - nuba = 2; - nuda = 1; - mbaaddr = mba750; - ubaaddr = uba750; - udaaddr = uda750; - uioaddr = uio750; - tmsaddr = 0774500; - break; - - case VAX_BTYP_630: /* the same for uvaxIII */ - case VAX_BTYP_650: - case VAX_BTYP_660: - case VAX_BTYP_670: - nuba = 1; - nuda = 2; - ubaaddr = uba630; - udaaddr = uda630; - uioaddr = uio630; - tmsaddr = qbdev(0774500); - break; - case VAX_BTYP_8000: + case VAX_BTYP_9CC: + case VAX_BTYP_9RR: + case VAX_BTYP_1202: + if (fromnet == 0) + break; copyrpb = 0; - memsz = 0; - nbi = 1; - biaddr = bi8200; - bioaddr = bio8200; + bootrpb.devtyp = bootregs[0]; + bootrpb.adpphy = bootregs[1]; + bootrpb.csrphy = bootregs[2]; + bootrpb.unit = bootregs[3]; + bootrpb.rpb_bootr5 = bootregs[5]; + bootrpb.pfncnt = 0; break; case VAX_BTYP_46: @@ -153,15 +106,18 @@ autoconf() map[i] = 0x80000000 | i; }break; - case VAX_BTYP_410: - case VAX_BTYP_420: - case VAX_BTYP_43: - case VAX_BTYP_49: - case VAX_BTYP_1301: - case VAX_BTYP_1303: - case VAX_BTYP_1305: break; } + + if (copyrpb) { + struct rpb *prpb = (struct rpb *)bootregs[11]; + bcopy((caddr_t)prpb, &bootrpb, sizeof(struct rpb)); + if (prpb->iovec) { + bootrpb.iovec = (int)alloc(prpb->iovecsz); + bcopy((caddr_t)prpb->iovec, (caddr_t)bootrpb.iovec, + prpb->iovecsz); + } + } } /* @@ -170,25 +126,34 @@ autoconf() volatile int tickcnt; +int getsecs() { - volatile int loop; - int todr; - return tickcnt/100; } -void scb_stray(), rtimer(); struct ivec_dsp **scb; struct ivec_dsp *scb_vec; +extern struct ivec_dsp idsptch; +extern int jbuf[10]; + +static void +mcheck(void *arg) +{ + int off, *mfp = (int *)&arg; + + off = (mfp[7]/4 + 8); + printf("Machine check, pc=%x, psl=%x\n", mfp[off], mfp[off+1]); + longjmp(jbuf, 1); +} /* * Init the SCB and set up a handler for all vectors in the lower space, * to detect unwanted interrupts. */ +void scbinit() { - extern int timer; int i; /* @@ -211,18 +176,19 @@ scbinit() scb_vec[i].ev = NULL; } scb_vec[0xc0/4].hoppaddr = rtimer; + scb_vec[4/4].hoppaddr = mcheck; - mtpr(-10000, PR_NICR); /* Load in count register */ + if (vax_boardtype != VAX_BTYP_VXT) + mtpr(-10000, PR_NICR); /* Load in count register */ mtpr(0x800000d1, PR_ICCS); /* Start clock and enable interrupt */ mtpr(20, PR_IPL); } -extern int jbuf[10]; extern int sluttid, senast, skip; void -rtimer() +rtimer(void *arg) { mtpr(31, PR_IPL); tickcnt++; @@ -230,29 +196,40 @@ rtimer() if (skip) return; if ((vax_boardtype == VAX_BTYP_46) || - (vax_boardtype == VAX_BTYP_48) || - (vax_boardtype == VAX_BTYP_49)) { + (vax_boardtype == VAX_BTYP_48) || + (vax_boardtype == VAX_BTYP_49)) { int nu = sluttid - getsecs(); if (senast != nu) { mtpr(20, PR_IPL); - longjmp(jbuf); + longjmp(jbuf, 1); } } } +#ifdef __ELF__ +#define IDSPTCH "idsptch" +#define EIDSPTCH "eidsptch" +#define CMN_IDSPTCH "cmn_idsptch" +#else +#define IDSPTCH "_idsptch" +#define EIDSPTCH "_eidsptch" +#define CMN_IDSPTCH "_cmn_idsptch" +#endif + asm(" + .text .align 2 - .globl _idsptch, _eidsptch -_idsptch: + .globl " IDSPTCH ", " EIDSPTCH " +" IDSPTCH ": pushr $0x3f .word 0x9f16 - .long _cmn_idsptch + .long " CMN_IDSPTCH " .long 0 .long 0 .long 0 -_eidsptch: +" EIDSPTCH ": -_cmn_idsptch: +" CMN_IDSPTCH ": movl (sp)+,r0 pushl 4(r0) calls $1,*(r0) @@ -265,8 +242,7 @@ _cmn_idsptch: * This function must _not_ save any registers (in the reg save mask). */ void -scb_stray(arg) - int arg; +scb_stray(void *arg) { static int vector, ipl; @@ -274,4 +250,3 @@ scb_stray(arg) vector = (int) arg; printf("stray interrupt: vector 0x%x, ipl %d\n", vector, ipl); } - diff --git a/sys/arch/vax/stand/boot/boot.c b/sys/arch/vax/stand/boot/boot.c index 5b18de3404f..dd5a4756e98 100644 --- a/sys/arch/vax/stand/boot/boot.c +++ b/sys/arch/vax/stand/boot/boot.c @@ -1,5 +1,5 @@ -/* $OpenBSD: boot.c,v 1.9 2002/02/13 02:42:20 deraadt Exp $ */ -/* $NetBSD: boot.c,v 1.4 1999/10/23 14:42:22 ragge Exp $ */ +/* $OpenBSD: boot.c,v 1.10 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: boot.c,v 1.18 2002/05/31 15:58:26 ragge Exp $ */ /*- * Copyright (c) 1982, 1986 The Regents of the University of California. * All rights reserved. @@ -35,13 +35,18 @@ * @(#)boot.c 7.15 (Berkeley) 5/4/91 */ -#include "sys/param.h" -#include "sys/reboot.h" -#include "rpb.h" +#include <sys/param.h> +#include <sys/reboot.h> #include "lib/libsa/stand.h" +#ifdef notyet +#include "lib/libsa/loadfile.h" +#include "lib/libkern/libkern.h" +#endif #define V750UCODE(x) ((x>>8)&255) +#include "machine/rpb.h" + #include "vaxstand.h" /* @@ -51,16 +56,20 @@ */ char line[100]; -int devtype, bootdev, howto, debug; +int bootdev, debug; extern unsigned opendev; -extern unsigned *bootregs; -struct rpb *rpb; -void usage(), boot(), halt(); +void usage(char *), boot(char *), halt(char *); +void Xmain(void); +void autoconf(void); +int getsecs(void); +int setjmp(int *); +int testkey(void); +void loadpcs(void); -struct vals { +const struct vals { char *namn; - void (*func)(); + void (*func)(char *); char *info; } val[] = { {"?", usage, "Show this help menu"}, @@ -70,34 +79,37 @@ struct vals { {0, 0}, }; -char *filer[] = { - "bsd", - "bsd.gz", - "bsd.old", - 0, +static struct { + char name[12]; + int quiet; +} filelist[] = { + { "bsd", 0 }, + { "bsd.old", 0 }, + { "bsd.vax", 1 }, + { "bsd.gz", 0 }, + { "", 0 }, }; int jbuf[10]; -int sluttid, senast, skip; +int sluttid, senast, skip, askname; +struct rpb bootrpb; -Xmain() +void +Xmain(void) { - int io, type, filindex = 0; + int io; int j, nu; - volatile int askname; - - /* make sure the rpb is out of the way so it does not get trampled; - * this will be the case if booting from net - */ +#ifdef noyet + u_long marks[MARK_MAX]; +#endif + extern const char bootprog_rev[], bootprog_date[]; - rpb = (struct rpb *)bootregs[11]; - bootdev = rpb->devtyp; - io=0; + io = 0; skip = 1; autoconf(); - askname = howto & RB_ASKNAME; - printf("\n\r>> OpenBSD/vax boot [%s %s] <<\n", __DATE__, __TIME__); + askname = bootrpb.rpb_bootr5 & RB_ASKNAME; + printf("\n\r>> OpenBSD/vax boot [%s] [%s] <<\n", "1.9", __DATE__); printf(">> Press enter to autoboot now, or any other key to abort: "); sluttid = getsecs() + 5; senast = 0; @@ -122,25 +134,46 @@ Xmain() skip = 1; printf("\n"); + if (setjmp(jbuf)) + askname = 1; + /* First try to autoboot */ if (askname == 0) { - type = (devtype >> B_TYPESHIFT) & B_TYPEMASK; - if ((unsigned)type < ndevs && devsw[type].dv_name) - while (filer[filindex]) { - errno = 0; - printf("> boot %s\n", filer[filindex]); - exec(filer[filindex++], 0, 0); - printf("boot failed: %s\n", strerror(errno)); -#if 0 - if (testkey()) - break; + int fileindex; + for (fileindex = 0; filelist[fileindex].name[0] != '\0'; + fileindex++) { +#ifdef notyet + int err; #endif + errno = 0; + if (!filelist[fileindex].quiet) + printf("> boot %s\n", filelist[fileindex].name); + exec(filelist[fileindex].name, 0, 0); +#ifdef notyet + marks[MARK_START] = 0; + err = loadfile(filelist[fileindex].name, marks, + LOAD_KERNEL|COUNT_KERNEL); + if (err == 0) { + machdep_start((char *)marks[MARK_ENTRY], + marks[MARK_NSYM], + (void *)marks[MARK_START], + (void *)marks[MARK_SYM], + (void *)marks[MARK_END]); } +#endif + if (!filelist[fileindex].quiet) + printf("%s: boot failed: %s\n", + filelist[fileindex].name, strerror(errno)); +#if 0 /* Will hang VAX 4000 machines */ + if (testkey()) + break; +#endif + } } /* If any key pressed, go to conversational boot */ for (;;) { - struct vals *v = &val[0]; + const struct vals *v = &val[0]; char *c, *d; printf("> "); @@ -165,21 +198,23 @@ Xmain() (*v->func)(d); else printf("Unknown command: %s\n", c); - } } void -halt() +halt(char *hej) { asm("halt"); } void -boot(arg) - char *arg; +boot(char *arg) { char *fn = "bsd"; + int howto, fl, err; +#ifdef notyet + u_long marks[MARK_MAX]; +#endif if (arg) { while (*arg == ' ') @@ -195,10 +230,12 @@ boot(arg) goto load; } if (*arg != '-') { -fail: printf("usage: boot [filename] [-asd]\n"); +fail: printf("usage: boot [filename] [-acsd]\n"); return; } + howto = 0; + while (*++arg) { if (*arg == 'a') howto |= RB_ASKNAME; @@ -211,8 +248,21 @@ fail: printf("usage: boot [filename] [-asd]\n"); else goto fail; } + bootrpb.rpb_bootr5 = howto; + } +load: + exec(fn, 0, 0); +#ifdef notyet + marks[MARK_START] = 0; + err = loadfile(fn, marks, LOAD_KERNEL|COUNT_KERNEL); + if (err == 0) { + machdep_start((char *)marks[MARK_ENTRY], + marks[MARK_NSYM], + (void *)marks[MARK_START], + (void *)marks[MARK_SYM], + (void *)marks[MARK_END]); } -load: exec(fn, 0, 0); +#endif printf("Boot failed: %s\n", strerror(errno)); } @@ -230,12 +280,13 @@ load: exec(fn, 0, 0); #define extzv(one, two, three,four) \ ({ \ - asm __volatile (" extzv %0,%3,%1,(%2)+" \ + asm __volatile (" extzv %0,%3,(%1),(%2)+" \ : \ - : "g"(one),"g"(two),"r"(three),"g"(four)); \ + : "g"(one),"g"(two),"g"(three),"g"(four)); \ }) +void loadpcs() { static int pcsdone = 0; @@ -310,9 +361,9 @@ loadpcs() } void -usage() +usage(char *hej) { - struct vals *v = &val[0]; + const struct vals *v = &val[0]; printf("Commands:\n"); while (v->namn) { diff --git a/sys/arch/vax/stand/boot/conf.c b/sys/arch/vax/stand/boot/conf.c index a5a21df6d33..c08626642ec 100644 --- a/sys/arch/vax/stand/boot/conf.c +++ b/sys/arch/vax/stand/boot/conf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: conf.c,v 1.2 2000/10/04 04:36:29 bjc Exp $ */ -/* $NetBSD: conf.c,v 1.3 1999/10/23 14:42:21 ragge Exp $ */ +/* $OpenBSD: conf.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: conf.c,v 1.10 2000/06/15 19:53:23 ragge Exp $ */ /* * Copyright (c) 1994 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -38,34 +38,33 @@ #include "../../include/rpb.h" +#include "lib/libkern/libkern.h" + #include "lib/libsa/stand.h" #include "lib/libsa/ufs.h" #include "lib/libsa/nfs.h" +#include "lib/libsa/cd9660.h" #include "vaxstand.h" -int raopen(), rastrategy(); -int hpopen(), hpstrategy(); -int ctuopen(), ctustrategy(); -int tmscpopen(), tmscpstrategy(); -int romopen(), romstrategy(); -int mfmopen(), mfmstrategy(); -int sdopen(), sdstrategy(); -int netopen(), netstrategy(), netclose(); +static int nostrategy(void *, int, daddr_t, size_t, void *, size_t *); struct devsw devsw[]={ SADEV("hp",hpstrategy, hpopen, nullsys, noioctl), - SADEV("qe",netstrategy, netopen, netclose, noioctl), /* DEQNA */ + SADEV("qe",nostrategy, qeopen, qeclose, noioctl), /* DEQNA */ SADEV("ctu",ctustrategy, ctuopen, nullsys, noioctl), SADEV("ra",rastrategy, raopen, nullsys, noioctl), - SADEV("mt",tmscpstrategy, tmscpopen, nullsys, noioctl), + SADEV("mt",rastrategy, raopen, nullsys, noioctl), SADEV("rom",romstrategy, romopen, nullsys, noioctl), - SADEV("rd",mfmstrategy, mfmopen, nullsys, noioctl), + SADEV("hd",mfmstrategy, mfmopen, nullsys, noioctl), SADEV("sd",romstrategy, romopen, nullsys, noioctl), - SADEV("sd",romstrategy, romopen, nullsys, noioctl), /* SDN */ + SADEV("sd",romstrategy, romopen, nullsys, noioctl), /* SDN */ SADEV("st",nullsys, nullsys, nullsys, noioctl), - SADEV("le",netstrategy, netopen, netclose, noioctl), /* LANCE */ - SADEV("ze",netstrategy, netopen, netclose, noioctl), /* SGEC */ + SADEV("le",nostrategy, leopen, leclose, noioctl), /* LANCE */ + SADEV("ze",nostrategy, zeopen, zeclose, noioctl), /* SGEC */ + SADEV("rl",romstrategy, romopen, nullsys, noioctl), + SADEV("de",nostrategy, deopen, declose, noioctl), /* DEUNA */ + SADEV("ni",nostrategy, niopen, nullsys, noioctl), /* DEBNA */ }; int cnvtab[] = { @@ -81,6 +80,9 @@ int cnvtab[] = { BDEV_ST, BDEV_LE, BDEV_ZE, + BDEV_RL, + BDEV_DE, + BDEV_NI, }; int ndevs = (sizeof(devsw)/sizeof(devsw[0])); @@ -88,18 +90,17 @@ int ndevs = (sizeof(devsw)/sizeof(devsw[0])); struct fs_ops file_system[] = { { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat }, { nfs_open, nfs_close, nfs_read, nfs_write, nfs_seek, nfs_stat }, + { cd9660_open, cd9660_close, cd9660_read, cd9660_write, + cd9660_seek, cd9660_stat }, }; int nfsys = (sizeof(file_system) / sizeof(struct fs_ops)); -extern struct netif_driver qe_driver; -extern struct netif_driver le_driver; -extern struct netif_driver ze_driver; - -struct netif_driver *netif_drivers[] = { - &qe_driver, - &le_driver, - &ze_driver, -}; -int n_netif_drivers = (sizeof(netif_drivers) / sizeof(netif_drivers[0])); - +int +nostrategy(void *f, int func, daddr_t dblk, + size_t size, void *buf, size_t *rsize) +{ + *rsize = size; + bzero(buf, size); + return 0; +} diff --git a/sys/arch/vax/stand/boot/consio.c b/sys/arch/vax/stand/boot/consio.c index 39775324c5b..ddfb19c8c5b 100644 --- a/sys/arch/vax/stand/boot/consio.c +++ b/sys/arch/vax/stand/boot/consio.c @@ -1,5 +1,5 @@ -/* $OpenBSD: consio.c,v 1.3 2002/03/14 01:26:47 millert Exp $ */ -/* $NetBSD: consio.c,v 1.11 2000/07/19 00:58:24 matt Exp $ */ +/* $OpenBSD: consio.c,v 1.4 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: consio.c,v 1.13 2002/05/24 21:40:59 ragge Exp $ */ /* * Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -41,68 +41,66 @@ #include "mtpr.h" #include "sid.h" #include "rpb.h" +#include "ka630.h" #include "data.h" void setup(void); -unsigned *bootregs; -extern struct rpb *rpb; -struct bqo *bqo; - -static int (*put_fp)(int) = NULL; +static void (*put_fp)(int) = NULL; static int (*get_fp)(void) = NULL; static int (*test_fp)(void) = NULL; -/* Also added such a thing for KA53 - MK-991208 */ -unsigned char *ka53_conspage; -void ka53_consinit(void); - -int ka53_rom_putchar(int c); -int ka53_rom_getchar(void); -int ka53_rom_testchar(void); - -int pr_putchar(int c); /* putchar() using mtpr/mfpr */ +void pr_putchar(int c); /* putchar() using mtpr/mfpr */ int pr_getchar(void); int pr_testchar(void); -int rom_putchar(int c); /* putchar() using ROM routines */ +void rom_putchar(int c); /* putchar() using ROM routines */ int rom_getchar(void); int rom_testchar(void); -static int rom_putc; /* ROM-address of put-routine */ -static int rom_getc; /* ROM-address of get-routine */ - -/* Location of address of KA630 console page */ -#define NVR_ADRS 0x200B8024 -/* Definitions for various locations in the KA630 console page */ -#define KA630_PUTC_POLL 0x20 -#define KA630_PUTC 0x24 -#define KA630_GETC 0x1C -#define KA630_ROW 0x4C -#define KA630_MINROW 0x4D -#define KA630_MAXROW 0x4E -#define KA630_COL 0x50 -#define KA630_MINCOL 0x51 -#define KA630_MAXCOL 0x52 +int rom_putc; /* ROM-address of put-routine */ +int rom_getc; /* ROM-address of get-routine */ + /* Pointer to KA630 console page, initialized by ka630_consinit */ -unsigned char *ka630_conspage; +unsigned char *ka630_conspage; + /* Function that initializes things for KA630 ROM console I/O */ -void ka630_consinit(void); +void ka630_consinit __P((void)); + /* Functions that use KA630 ROM for console I/O */ -int ka630_rom_putchar(int c); -int ka630_rom_getchar(void); -int ka630_rom_testchar(void); +void ka630_rom_putchar __P((int c)); +int ka630_rom_getchar __P((void)); +int ka630_rom_testchar __P((void)); -putchar(c) - int c; +/* Also added such a thing for KA53 - MK-991208 */ +unsigned char *ka53_conspage; +void ka53_consinit(void); + +void ka53_rom_putchar(int c); +int ka53_rom_getchar(void); +int ka53_rom_testchar(void); + +void vxt_putchar(int c); +int vxt_getchar(void); +int vxt_testchar(void); + +void putchar(int); +int getchar(void); +int testkey(void); +void consinit(void); +void _rtt(void); + +void +putchar(int c) { (*put_fp)(c); if (c == 10) (*put_fp)(13); /* CR/LF */ } -getchar() +int +getchar(void) { int c; @@ -114,7 +112,8 @@ getchar() return c; } -testkey() +int +testkey(void) { return (*test_fp)(); } @@ -124,7 +123,7 @@ testkey() * initializes data which are globally used and is called before main(). */ void -consinit() +consinit(void) { put_fp = pr_putchar; /* Default */ get_fp = pr_getchar; @@ -141,14 +140,6 @@ consinit() */ switch (vax_boardtype) { - case VAX_BTYP_690: - put_fp = rom_putchar; - get_fp = rom_getchar; - test_fp = rom_testchar; - rom_putc = 0x20040058; /* 537133144 */ - rom_getc = 0x20040008; /* 537133064 */ - break; - case VAX_BTYP_43: case VAX_BTYP_410: case VAX_BTYP_420: @@ -159,9 +150,15 @@ consinit() rom_getc = 0x20040044; /* 537133124 */ break; + case VAX_BTYP_VXT: + put_fp = vxt_putchar; + get_fp = vxt_getchar; + test_fp = vxt_testchar; + break; + case VAX_BTYP_630: - ka630_consinit(); - break; + ka630_consinit(); + break; case VAX_BTYP_46: case VAX_BTYP_48: @@ -193,144 +190,82 @@ consinit() /* * putchar() using MTPR */ -pr_putchar(c) - int c; +void +pr_putchar(int c) { - int timeout = 1<<15; /* don't hang the machine! */ - while ((mfpr(PR_TXCS) & GC_RDY) == 0) /* Wait until xmit ready */ + int timeout = 1<<15; /* don't hang the machine! */ + + /* + * On KA88 we may get C-S/C-Q from the console. + * Must obey it. + */ + while (mfpr(PR_RXCS) & GC_DON) { + if ((mfpr(PR_RXDB) & 0x7f) == 19) { + while (1) { + while ((mfpr(PR_RXCS) & GC_DON) == 0) + ; + if ((mfpr(PR_RXDB) & 0x7f) == 17) + break; + } + } + } + + while ((mfpr(PR_TXCS) & GC_RDY) == 0) /* Wait until xmit ready */ if (--timeout < 0) break; - mtpr(c, PR_TXDB); /* xmit character */ + mtpr(c, PR_TXDB); /* xmit character */ } /* * getchar() using MFPR */ -pr_getchar() +int +pr_getchar(void) { - while ((mfpr(PR_RXCS) & GC_DON) == 0); /* wait for char */ + while ((mfpr(PR_RXCS) & GC_DON) == 0) + ; /* wait for char */ return (mfpr(PR_RXDB)); /* now get it */ } -pr_testchar() +int +pr_testchar(void) { if (mfpr(PR_RXCS) & GC_DON) return mfpr(PR_RXDB); else return 0; } -/* - * int rom_putchar (int c) ==> putchar() using ROM-routines - */ -asm(" - .globl _rom_putchar - _rom_putchar: - .word 0x04 # save-mask: R2 - movl 4(ap), r2 # move argument to R2 - jsb *_rom_putc # write it - ret # that's all -"); - - -/* - * int rom_getchar (void) ==> getchar() using ROM-routines - */ -asm(" - .globl _rom_getchar - _rom_getchar: - .word 0x02 # save-mask: R1 - loop: # do { - jsb *_rom_getc # call the getc-routine - tstl r0 # check if char ready - beql loop # } while (R0 == 0) - movl r1, r0 # R1 holds char - ret # we're done - - _rom_testchar: - .word 0 - mnegl $1,r0 - jsb *_rom_getc - tstl r0 - beql 1f - movl r1,r0 - 1: ret -"); - -_rtt() -{ - asm("halt"); -} - - /* * void ka630_rom_getchar (void) ==> initialize KA630 ROM console I/O */ -void ka630_consinit() +void ka630_consinit(void) { - register short *NVR; - register int i; + short *NVR; + int i; - /* Find the console page */ - NVR = (short *) NVR_ADRS; + /* Find the console page */ + NVR = (short *) KA630_NVR_ADRS; - i = *NVR++ & 0xFF; - i |= (*NVR++ & 0xFF) << 8; - i |= (*NVR++ & 0xFF) << 16; - i |= (*NVR++ & 0xFF) << 24; + i = *NVR++ & 0xFF; + i |= (*NVR++ & 0xFF) << 8; + i |= (*NVR++ & 0xFF) << 16; + i |= (*NVR++ & 0xFF) << 24; - ka630_conspage = (char *) i; + ka630_conspage = (char *) i; - /* Go to last row to minimize confusion */ + /* Go to last row to minimize confusion */ ka630_conspage[KA630_ROW] = ka630_conspage[KA630_MAXROW]; ka630_conspage[KA630_COL] = ka630_conspage[KA630_MINCOL]; - /* Use KA630 ROM console I/O routines */ + /* Use KA630 ROM console I/O routines */ put_fp = ka630_rom_putchar; get_fp = ka630_rom_getchar; test_fp = ka630_rom_testchar; } - -/* - * int ka630_rom_getchar (void) ==> getchar() using ROM-routines on KA630 - */ -asm(" - .globl _ka630_rom_getchar - _ka630_rom_getchar: - .word 0x802 # save-mask: R1, R11 - movl _ka630_conspage,r11 # load location of console page - loop630g: # do { - jsb *0x1C(r11) # call the getc-routine (KA630_GETC) - blbc r0, loop630g # } while (R0 == 0) - movl r1, r0 # R1 holds char - ret # we're done - - _ka630_rom_testchar: - .word 0 - movl _ka630_conspage,r3 - jsb *0x1C(r3) - blbc r0,1f - movl r1,r0 - 1: ret -"); /* - * int ka630_rom_putchar (int c) ==> putchar() using ROM-routines on KA630 - */ -asm(" - .globl _ka630_rom_putchar - _ka630_rom_putchar: - .word 0x802 # save-mask: R1, R11 - movl _ka630_conspage,r11 # load location of console page - loop630p: # do { - jsb *0x20(r11) # is rom ready? (KA630_PUTC_POLL) - blbc r0, loop630p # } while (R0 == 0) - movl 4(ap), r1 # R1 holds char - jsb *0x24(r11) # output character (KA630_PUTC) - ret # we're done -"); -/* * void ka53_consinit (void) ==> initialize KA53 ROM console I/O */ void ka53_consinit(void) @@ -342,46 +277,33 @@ void ka53_consinit(void) test_fp = ka53_rom_testchar; } -/* - * int ka53_rom_getchar (void) ==> getchar() using ROM-routines - */ +static volatile int *vxtregs = (int *)0x200A0000; -asm(" - .globl _ka53_rom_getchar - _ka53_rom_getchar: - .word 0x0802 # r1, r11 - movl _ka53_conspage, r11 # load location of console page -1: jsb *0x64(r11) # test for char - blbc r0, 1b # while r0 is 0 - jsb *0x6c(r11) # get char - ret -"); - -asm(" - .globl _ka53_rom_testchar - _ka53_rom_testchar: - .word 0x8 # r3 - movl _ka53_conspage, r3 - jsb *0x64(r3) - blbc r0, 1f - jsb *0x6c(r3) # get it -1: ret -"); - -/* - * int ka53_rom_putchar (int c) ==> putchar() using ROM-routines - */ +#define CH_SR 1 +#define CH_DAT 3 +#define SR_TX_RDY 0x04 +#define SR_RX_RDY 0x01 -asm(" - .globl _ka53_rom_putchar - _ka53_rom_putchar: - .word 0x0802 # r1, r11 - movl _ka53_conspage, r11 -1: jsb *0x20(r11) # ready to write? - blbc r0, 1b # keep going if r0 == 0 - movl 4(ap), r1 # char is in r1 - jsb *0x24(r11) # output char - ret -"); +void +vxt_putchar(int c) +{ + while ((vxtregs[CH_SR] & SR_TX_RDY) == 0) + ; + vxtregs[CH_DAT] = c; +} +int +vxt_getchar(void) +{ + while ((vxtregs[CH_SR] & SR_RX_RDY) == 0) + ; + return vxtregs[CH_DAT]; +} +int +vxt_testchar(void) +{ + if ((vxtregs[CH_SR] & SR_RX_RDY) == 0) + return 0; + return vxtregs[CH_DAT]; +} diff --git a/sys/arch/vax/stand/boot/consio2.S b/sys/arch/vax/stand/boot/consio2.S new file mode 100644 index 00000000000..a8a279e7d87 --- /dev/null +++ b/sys/arch/vax/stand/boot/consio2.S @@ -0,0 +1,128 @@ +/* $OpenBSD: consio2.S,v 1.1 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: consio2.S,v 1.1 2002/02/24 01:04:24 matt Exp $ */ +/* + * Copyright (c) 1994, 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}. + * 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 <machine/asm.h> + +/* + * int rom_putchar (int c) ==> putchar() using ROM-routines + */ +ENTRY(rom_putchar, 0x0004) # save-mask: R2 + movl 4(ap), r2 # move argument to R2 + jsb *_C_LABEL(rom_putc) # write it + ret # that is all + + +/* + * int rom_getchar (void) ==> getchar() using ROM-routines + */ +ENTRY(rom_getchar, 0x0002) # save-mask: R1 +loop: # do { + jsb *_C_LABEL(rom_getc) # call the getc-routine + tstl r0 # check if char ready + beql loop # } while (R0 == 0) + movl r1, r0 # R1 holds char + ret # we are done + +ENTRY(rom_testchar, 0) + mnegl $1,r0 + jsb *_C_LABEL(rom_getc) + tstl r0 + beql 1f + movl r1,r0 +1: ret + +ENTRY(_rtt, 0) + halt + + +/* + * int ka630_rom_getchar (void) ==> getchar() using ROM-routines on KA630 + */ +ENTRY(ka630_rom_getchar, 0x0802) # save-mask: R1, R11 + movl _C_LABEL(ka630_conspage),r11 # load location of console page +1: # do { + jsb *0x1C(r11) # call the getc-routine (KA630_GETC) + blbc r0,1b # } while (R0 == 0) + movl r1,r0 # R1 holds char + ret # we are done + +ENTRY(ka630_rom_testchar, 0) + movl _C_LABEL(ka630_conspage),r3 + jsb *0x1C(r3) + blbc r0,1f + movl r1,r0 +1: ret + +/* + * int ka630_rom_putchar (int c) ==> putchar() using ROM-routines on KA630 + */ +ENTRY(ka630_rom_putchar, 0x802) # save-mask: R1, R11 + movl _C_LABEL(ka630_conspage),r11 + # load location of console page +1: # do { + jsb *0x20(r11) # is rom ready? (KA630_PUTC_POLL) + blbc r0,1b # } while (R0 == 0) + movl 4(ap),r1 # R1 holds char + jsb *0x24(r11) # output character (KA630_PUTC) + ret # we are done + +/* + * int ka53_rom_getchar (void) ==> getchar() using ROM-routines on KA53 + */ +ENTRY(ka53_rom_getchar, 0x0802) # save-mask: R1, R11 + movl _C_LABEL(ka53_conspage),r11 + # load location of console page +1: # do { + jsb *0x64(r11) # test for char + blbc r0,1b # } while (R0 == 0) + jsb *0x6c(r11) # get the char + ret # we are done + +ENTRY(ka53_rom_testchar, 0) + movl _C_LABEL(ka53_conspage),r3 + jsb *0x64(r3) + blbc r0,1f + jsb *0x6c(r3) # get the char +1: ret + +/* + * int ka53_rom_putchar (int c) ==> putchar() using ROM-routines on KA53 + */ +ENTRY(ka53_rom_putchar, 0x0802) # save-mask: R1, R11 + movl _C_LABEL(ka53_conspage),r11 + # load location of console page +1: # do { + jsb *0x20(r11) # is rom ready? + blbc r0,1b # } whi le (R0 == 0) + movl 4(ap),r1 # R1 holds char + jsb *0x24(r11) # output character + ret # we are done diff --git a/sys/arch/vax/stand/boot/ctu.c b/sys/arch/vax/stand/boot/ctu.c index acdd35a7c70..b8a9b863faf 100644 --- a/sys/arch/vax/stand/boot/ctu.c +++ b/sys/arch/vax/stand/boot/ctu.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ctu.c,v 1.2 2002/03/14 01:26:47 millert Exp $ */ -/* $NetBSD: ctu.c,v 1.1 1996/02/17 18:23:20 ragge Exp $ */ +/* $OpenBSD: ctu.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: ctu.c,v 1.3 2000/05/20 13:30:03 ragge Exp $ */ /* * Copyright (c) 1996 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -43,6 +43,10 @@ #include <machine/mtpr.h> #include <machine/rsp.h> +#include "vaxstand.h" + +static short ctu_cksum(unsigned short *, int); + enum tu_state { SC_INIT, SC_READY, @@ -78,15 +82,13 @@ ctuopen(f, adapt, ctlr, unit, part) } int -ctustrategy(ra, func, dblk, size, buf, rsize) - struct ra_softc *ra; +ctustrategy(f, func, dblk, size, buf, rsize) + void *f; int func; daddr_t dblk; - char *buf; - u_int size, *rsize; + void *buf; + size_t size, *rsize; { - int s; - struct rsp *rsp = (struct rsp *)tu_sc.sc_rsp; tu_sc.sc_xfptr = buf; @@ -101,7 +103,7 @@ ctustrategy(ra, func, dblk, size, buf, rsize) rsp->rsp_sw = rsp->rsp_xx1 = rsp->rsp_xx2 = 0; rsp->rsp_cnt = tu_sc.sc_nbytes; rsp->rsp_blk = dblk; - rsp->rsp_sum = ctu_cksum(rsp, 6); + rsp->rsp_sum = ctu_cksum((u_short *)rsp, 6); tu_sc.sc_state = SC_SEND_CMD; while (tu_sc.sc_state != SC_GET_RESP) ctutintr(); @@ -144,7 +146,9 @@ cturintr() break; tu_sc.sc_xfptr[tu_sc.sc_xbytes++] = status; break; - + case SC_READY: + case SC_SEND_CMD: + break; } } @@ -165,6 +169,7 @@ ctutintr() } } +short ctu_cksum(buf, words) unsigned short *buf; int words; diff --git a/sys/arch/vax/stand/boot/data.h b/sys/arch/vax/stand/boot/data.h index 9098d501d70..e91bfaf789d 100644 --- a/sys/arch/vax/stand/boot/data.h +++ b/sys/arch/vax/stand/boot/data.h @@ -1,5 +1,5 @@ -/* $OpenBSD: data.h,v 1.1 2000/04/27 02:26:25 bjc Exp $ */ -/* $NetBSD: data.h,v 1.4 1995/09/16 15:58:57 ragge Exp $ */ +/* $OpenBSD: data.h,v 1.2 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: data.h,v 1.3 2001/07/26 15:05:09 wiz Exp $ */ /* * Copyright (c) 1995 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -38,8 +38,6 @@ -extern unsigned *bootregs; - /* * rpb->iovec gives pointer to this structure. * @@ -67,7 +65,7 @@ struct bqo { long umr_tmpl; /* 4 UNIBUS map register template */ /* offset: 60 */ /* - * the rest is unknown / unneccessary ... + * the rest is unknown / unnecessary ... */ long xxx[6]; /* 24 -- total: 84 bytes */ }; diff --git a/sys/arch/vax/stand/boot/devopen.c b/sys/arch/vax/stand/boot/devopen.c index dac5993df30..5cb9ade2994 100644 --- a/sys/arch/vax/stand/boot/devopen.c +++ b/sys/arch/vax/stand/boot/devopen.c @@ -1,5 +1,5 @@ -/* $OpenBSD: devopen.c,v 1.2 2000/10/04 04:09:01 bjc Exp $ */ -/* $NetBSD: devopen.c,v 1.2 1999/06/30 18:30:42 ragge Exp $ */ +/* $OpenBSD: devopen.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: devopen.c,v 1.10 2002/05/24 21:40:59 ragge Exp $ */ /* * Copyright (c) 1997 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -31,14 +31,20 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/reboot.h> - #include "lib/libsa/stand.h" + +#include "machine/rpb.h" +#include "machine/sid.h" +#include "machine/pte.h" +#define VAX780 1 +#include "machine/ka750.h" + +#include "arch/vax/bi/bireg.h" + #include "vaxstand.h" -#include "rpb.h" -unsigned int opendev; -extern struct rpb *rpb; +int atoi(char *); +int nexaddr, csrbase; int devopen(f, fname, file) @@ -46,21 +52,33 @@ devopen(f, fname, file) const char *fname; char **file; { - int dev, ctlr, unit, part, adapt, i, a[4], x; + int dev, unit, ctlr, part, adapt, i, a[4], x; + int *mapregs; struct devsw *dp; extern int cnvtab[]; - char *s, *c, *u; + char *s, *c; + + part = 0; + + /* + * Adaptor and controller are normally zero (or uninteresting), + * but we need to do some conversion here anyway (if it's a + * manual boot, but that's checked by the device driver). + * Set them to -1 to tell if it's a set number or default. + */ + dev = bootrpb.devtyp; + unit = bootrpb.unit; + adapt = ctlr = -1; - dev = rpb->devtyp; - unit = rpb->unit; - adapt = ctlr = part = 0; + if (dev == BDEV_KDB) + dev = BDEV_UDA; /* use the same driver */ for (i = 0, dp = 0; i < ndevs; i++) if (cnvtab[i] == dev) dp = devsw + i; x = 0; - if ((s = index(fname, '('))) { + if ((s = index((char *)fname, '('))) { *s++ = 0; for (i = 0, dp = devsw; i < ndevs; i++, dp++) @@ -99,29 +117,87 @@ devopen(f, fname, file) if (x > 3) adapt = a[0]; *file = c; - - x = 1; } else { *file = (char *)fname; c = (char *)fname; } - if (!dp->dv_open) + if (!dp->dv_open) { + printf("Can't open device type %d\n", dev); return(ENODEV); + } f->f_dev = dp; - - if (dev > 95) { /* MOP boot over network, root & swap over NFS */ - i = (*dp->dv_open)(f, dp->dv_name); - } else - i = (*dp->dv_open)(f, adapt, ctlr, unit, part); - - if(x == 0) { - dev = rpb->devtyp; /* dv_open may have modified rpb */ - unit = rpb->unit; + bootrpb.unit = unit; + bootrpb.devtyp = dev; + + nexaddr = bootrpb.adpphy; + switch (vax_boardtype) { + case VAX_BTYP_750: + csrbase = (nexaddr == 0xf30000 ? 0xffe000 : 0xfbe000); + if (adapt < 0) + break; + nexaddr = (NEX750 + NEXSIZE * adapt); + csrbase = (adapt == 8 ? 0xffe000 : 0xfbe000); + break; + case VAX_BTYP_780: + case VAX_BTYP_790: + csrbase = 0x2007e000 + 0x40000 * ((nexaddr & 0x1e000) >> 13); + if (adapt < 0) + break; + nexaddr = ((int)NEX780 + NEXSIZE * adapt); + csrbase = 0x2007e000 + 0x40000 * adapt; + break; + case VAX_BTYP_9CC: /* 6000/200 */ + case VAX_BTYP_9RR: /* 6000/400 */ + case VAX_BTYP_1202: /* 6000/500 */ + csrbase = 0; + if (ctlr < 0) + ctlr = bootrpb.adpphy & 15; + if (adapt < 0) + adapt = (bootrpb.adpphy >> 4) & 15; + nexaddr = BI_BASE(adapt, ctlr); + break; + + case VAX_BTYP_8000: + case VAX_BTYP_8800: + case VAX_BTYP_8PS: + csrbase = 0; /* _may_ be a KDB */ + nexaddr = bootrpb.csrphy; + if (ctlr < 0) + break; + if (adapt < 0) + nexaddr = (nexaddr & 0xff000000) + BI_NODE(ctlr); + else + nexaddr = BI_BASE(adapt, ctlr); + break; + case VAX_BTYP_610: + nexaddr = 0; /* No map regs */ + csrbase = 0x20000000; + break; + + case VAX_BTYP_VXT: + nexaddr = 0; + csrbase = bootrpb.csrphy; + break; + default: + nexaddr = 0; /* No map regs */ + csrbase = 0x20000000; + /* Always map in the lowest 4M on qbus-based machines */ + mapregs = (void *)0x20088000; + if (bootrpb.adpphy == 0x20087800) + for (i = 0; i < 8192; i++) + mapregs[i] = PG_V | i; + break; } - opendev = MAKEBOOTDEV(dev, adapt, ctlr, unit, part); - return i; +#ifdef DEV_DEBUG + printf("rpb.type %d rpb.unit %d rpb.csr %lx rpb.adp %lx\n", + bootrpb.devtyp, bootrpb.unit, bootrpb.csrphy, bootrpb.adpphy); + printf("adapter %d ctlr %d unit %d part %d\n", adapt, ctlr, unit, part); + printf("nexaddr %x csrbase %x\n", nexaddr, csrbase); +#endif + + return (*dp->dv_open)(f, adapt, ctlr, unit, part); usage: printf("usage: dev(adapter,controller,unit,partition)file -asd\n"); diff --git a/sys/arch/vax/stand/boot/hp.c b/sys/arch/vax/stand/boot/hp.c index 30f29ae1101..a45e4ae3687 100644 --- a/sys/arch/vax/stand/boot/hp.c +++ b/sys/arch/vax/stand/boot/hp.c @@ -1,5 +1,5 @@ -/* $OpenBSD: hp.c,v 1.1 2000/04/27 02:26:25 bjc Exp $ */ -/* $NetBSD: hp.c,v 1.2 1999/04/01 20:40:07 ragge Exp $ */ +/* $OpenBSD: hp.c,v 1.2 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: hp.c,v 1.5 2000/07/19 00:58:25 matt Exp $ */ /* * Copyright (c) 1994 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -40,7 +40,11 @@ #include "lib/libsa/stand.h" #include "../include/pte.h" -/*#include "../include/macros.h"*/ +#include "../include/rpb.h" +#include "../include/sid.h" +#define VAX780 1 +struct proc; +#include "../include/ka750.h" #include "../mba/mbareg.h" #include "../mba/hpreg.h" @@ -54,113 +58,97 @@ * But it works :) */ -struct hp_softc { - int adapt; - int ctlr; - int unit; - int part; -}; - -struct disklabel hplabel; -struct hp_softc hp_softc; -char io_buf[DEV_BSIZE]; -daddr_t part_offset; - -hpopen(f, adapt, ctlr, unit, part) - struct open_file *f; - int ctlr, unit, part; +static struct disklabel hplabel; +static char io_buf[DEV_BSIZE]; +static int dpart; +static int adpadr, unitadr; + +#define MBA_WCSR(reg, val) \ + ((void)(*(volatile u_int32_t *)((adpadr) + (reg)) = (val))); +#define MBA_RCSR(reg) \ + (*(volatile u_int32_t *)((adpadr) + (reg))) +#define HP_WCSR(reg, val) \ + ((void)(*(volatile u_int32_t *)((unitadr) + (reg)) = (val))); +#define HP_RCSR(reg) \ + (*(volatile u_int32_t *)((unitadr) + (reg))) + +int +hpopen(struct open_file *f, int adapt, int ctlr, int unit, int part) { - struct disklabel *lp; - struct hp_softc *hs; - volatile struct mba_regs *mr; - volatile struct hp_drv *hd; char *msg; - int i,err; - - lp = &hplabel; - hs = &hp_softc; - mr = (void *)mbaaddr[ctlr]; - hd = (void *)&mr->mba_md[unit]; - - if (adapt > nsbi) return(EADAPT); - if (ctlr > nmba) return(ECTLR); - if (unit > MAXMBAU) return(EUNIT); - - bzero(lp, sizeof(struct disklabel)); + int err; + size_t i; + + if (askname == 0) { /* Take info from RPB */ + adpadr = bootrpb.adpphy; + unitadr = adpadr + MUREG(bootrpb.unit, 0); + } else { + adpadr = nexaddr; + unitadr = adpadr + MUREG(unit, 0); + bootrpb.adpphy = adpadr; + bootrpb.unit = unit; + } + bzero(&hplabel, sizeof(struct disklabel)); - lp->d_secpercyl = 32; - lp->d_nsectors = 32; - hs->adapt = adapt; - hs->ctlr = ctlr; - hs->unit = unit; - hs->part = part; + hplabel.d_secpercyl = 32; + hplabel.d_nsectors = 32; /* Set volume valid and 16 bit format; only done once */ - mr->mba_cr = MBACR_INIT; - hd->hp_cs1 = HPCS_PA; - hd->hp_of = HPOF_FMT; + MBA_WCSR(MBA_CR, MBACR_INIT); + HP_WCSR(HP_CS1, HPCS_PA); + HP_WCSR(HP_OF, HPOF_FMT); - err = hpstrategy(hs, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i); + err = hpstrategy(0, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i); if (err) { printf("reading disklabel: %s\n", strerror(err)); return 0; } - msg = getdisklabel(io_buf + LABELOFFSET, lp); + msg = getdisklabel(io_buf + LABELOFFSET, &hplabel); if (msg) printf("getdisklabel: %s\n", msg); - - f->f_devdata = (void *)hs; return 0; } -hpstrategy(hs, func, dblk, size, buf, rsize) - struct hp_softc *hs; - daddr_t dblk; - u_int size, *rsize; - char *buf; - int func; +int +hpstrategy(void *f, int func, daddr_t dblk, + size_t size, void *buf, size_t *rsize) { - volatile struct mba_regs *mr; - volatile struct hp_drv *hd; - struct disklabel *lp; - unsigned int i, pfnum, mapnr, nsize, bn, cn, sn, tn; - - mr = (void *)mbaaddr[hs->ctlr]; - hd = (void *)&mr->mba_md[hs->unit]; - lp = &hplabel; + unsigned int pfnum, mapnr, nsize, bn, cn, sn, tn; pfnum = (u_int)buf >> VAX_PGSHIFT; - for(mapnr = 0, nsize = size; (nsize + VAX_NBPG) > 0; nsize -= VAX_NBPG) - *(int *)&mr->mba_map[mapnr++] = PG_V | pfnum++; + for(mapnr = 0, nsize = size; (nsize + VAX_NBPG) > 0; + nsize -= VAX_NBPG, mapnr++, pfnum++) + MBA_WCSR(MAPREG(mapnr), PG_V | pfnum); - mr->mba_var = ((u_int)buf & VAX_PGOFSET); - mr->mba_bc = (~size) + 1; - bn = dblk + lp->d_partitions[hs->part].p_offset; + MBA_WCSR(MBA_VAR, ((u_int)buf & VAX_PGOFSET)); + MBA_WCSR(MBA_BC, (~size) + 1); + bn = dblk + hplabel.d_partitions[dpart].p_offset; if (bn) { - cn = bn / lp->d_secpercyl; - sn = bn % lp->d_secpercyl; - tn = sn / lp->d_nsectors; - sn = sn % lp->d_nsectors; + cn = bn / hplabel.d_secpercyl; + sn = bn % hplabel.d_secpercyl; + tn = sn / hplabel.d_nsectors; + sn = sn % hplabel.d_nsectors; } else cn = sn = tn = 0; - hd->hp_dc = cn; - hd->hp_da = (tn << 8) | sn; + HP_WCSR(HP_DC, cn); + HP_WCSR(HP_DA, (tn << 8) | sn); +#ifdef notdef if (func == F_WRITE) - hd->hp_cs1 = HPCS_WRITE; + HP_WCSR(HP_CS1, HPCS_WRITE); else - hd->hp_cs1 = HPCS_READ; +#endif + HP_WCSR(HP_CS1, HPCS_READ); - while (mr->mba_sr & MBASR_DTBUSY) + while (MBA_RCSR(MBA_SR) & MBASR_DTBUSY) ; - if (mr->mba_sr & MBACR_ABORT) + if (MBA_RCSR(MBA_SR) & MBACR_ABORT) return 1; - - *rsize = size; + *rsize = size; return 0; } diff --git a/sys/arch/vax/stand/boot/if_de.c b/sys/arch/vax/stand/boot/if_de.c new file mode 100644 index 00000000000..b48d816c75f --- /dev/null +++ b/sys/arch/vax/stand/boot/if_de.c @@ -0,0 +1,290 @@ +/* $OpenBSD: if_de.c,v 1.1 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: if_de.c,v 1.2 2002/05/24 21:41:40 ragge 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. + * + * Standalone routine for the DEUNA Ethernet controller. + */ + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/queue.h> + +#include <net/if.h> + +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/if_ether.h> + +#include <lib/libsa/netif.h> +#include <lib/libsa/stand.h> + +#include <arch/vax/qbus/if_dereg.h> + +#include "arch/vax/include/sid.h" +#include "arch/vax/include/rpb.h" +#include "arch/vax/include/pte.h" + +#include "vaxstand.h" + +static int de_get(struct iodesc *, void *, size_t, time_t); +static int de_put(struct iodesc *, void *, size_t); +static void dewait(char *); + +struct netif_driver de_driver = { + 0, 0, 0, 0, de_get, de_put, +}; + +#define NRCV 8 /* allocate 8 receive descriptors */ +#define NXMT 4 /* and 4 transmit - must be >1 */ + +struct de_cdata { + /* the following structures are always mapped in */ + struct de_pcbb dc_pcbb; /* port control block */ + struct de_ring dc_xrent[NXMT]; /* transmit ring entrys */ + struct de_ring dc_rrent[NRCV]; /* receive ring entrys */ + struct de_udbbuf dc_udbbuf; /* UNIBUS data buffer */ + char dc_rbuf[NRCV][ETHER_MAX_LEN]; + char dc_xbuf[NXMT][ETHER_MAX_LEN]; + /* end mapped area */ +}; + +static volatile struct de_cdata *dc, *pdc; +static volatile char *addr; +static int crx, ctx; +#define DE_WCSR(csr, val) *(volatile u_short *)(addr + (csr)) = (val) +#define DE_WLOW(val) *(volatile u_char *)(addr + DE_PCSR0) = (val) +#define DE_WHIGH(val) *(volatile u_char *)(addr + DE_PCSR0 + 1) = (val) +#define DE_RCSR(csr) *(volatile u_short *)(addr + (csr)) +#define LOWORD(x) ((u_int)(x) & 0xffff) +#define HIWORD(x) (((u_int)(x) >> 16) & 0x3) +#define dereg(x) ((x) & 017777) + +int +deopen(struct open_file *f, int adapt, int ctlr, int unit, int part) +{ + int i, cdata, *map, npgs; + char eaddr[6]; + + /* point to the device in memory */ + if (askname == 0) /* Override if autoboot */ + addr = (char *)bootrpb.csrphy; + else { + addr = (char *)csrbase + dereg(0174510); + bootrpb.csrphy = (int)addr; + } +#ifdef DEV_DEBUG + printf("deopen: csrbase %x addr %p nexaddr %x\n", + csrbase, addr, nexaddr); +#endif + /* reset the device and wait for completion */ + DE_WCSR(DE_PCSR0, 0); + {volatile int j = 100; while (--j);} + DE_WCSR(DE_PCSR0, PCSR0_RSET); + dewait("reset"); + + /* Map in the control structures and buffers */ + dc = alloc(sizeof(struct de_cdata)); + (int)pdc = (int)dc & VAX_PGOFSET; + map = (int *)nexaddr + 512; + npgs = (sizeof(struct de_cdata) >> VAX_PGSHIFT) + 1; + cdata = (int)dc >> VAX_PGSHIFT; + for (i = 0; i < npgs; i++) { + map[i] = PG_V | (cdata + i); + } + + bzero((char *)dc, sizeof(struct de_cdata)); + + /* Tell the DEUNA about our PCB */ + DE_WCSR(DE_PCSR2, LOWORD(pdc)); + DE_WCSR(DE_PCSR3, HIWORD(pdc)); + DE_WLOW(CMD_GETPCBB); + dewait("pcbb"); + + /* Get our address */ + dc->dc_pcbb.pcbb0 = FC_RDPHYAD; + DE_WLOW(CMD_GETCMD); + dewait("read physaddr"); + bcopy((char *)&dc->dc_pcbb.pcbb2, eaddr, 6); + + /* Create and link the descriptors */ + for (i=0; i < NRCV; i++) { + volatile struct de_ring *rp = &dc->dc_rrent[i]; + + rp->r_lenerr = 0; + rp->r_segbl = LOWORD(&pdc->dc_rbuf[i][0]); + rp->r_segbh = HIWORD(&pdc->dc_rbuf[i][0]); + rp->r_flags = RFLG_OWN; + rp->r_slen = ETHER_MAX_LEN; + } + for (i=0; i < NXMT; i++) { + volatile struct de_ring *rp = &dc->dc_xrent[i]; + + rp->r_segbl = LOWORD(&pdc->dc_xbuf[i][0]); + rp->r_segbh = HIWORD(&pdc->dc_xbuf[i][0]); + rp->r_tdrerr = 0; + rp->r_flags = 0; + } + crx = ctx = 0; + + /* set the transmit and receive ring header addresses */ + dc->dc_pcbb.pcbb0 = FC_WTRING; + dc->dc_pcbb.pcbb2 = LOWORD(&pdc->dc_udbbuf); + dc->dc_pcbb.pcbb4 = HIWORD(&pdc->dc_udbbuf); + + dc->dc_udbbuf.b_tdrbl = LOWORD(&pdc->dc_xrent[0]); + dc->dc_udbbuf.b_tdrbh = HIWORD(&pdc->dc_xrent[0]); + dc->dc_udbbuf.b_telen = sizeof (struct de_ring) / sizeof(u_int16_t); + dc->dc_udbbuf.b_trlen = NXMT; + dc->dc_udbbuf.b_rdrbl = LOWORD(&pdc->dc_rrent[0]); + dc->dc_udbbuf.b_rdrbh = HIWORD(&pdc->dc_rrent[0]); + dc->dc_udbbuf.b_relen = sizeof (struct de_ring) / sizeof(u_int16_t); + dc->dc_udbbuf.b_rrlen = NRCV; + + DE_WLOW(CMD_GETCMD); + dewait("wtring"); + + dc->dc_pcbb.pcbb0 = FC_WTMODE; + dc->dc_pcbb.pcbb2 = MOD_DRDC|MOD_TPAD|MOD_HDX; + DE_WLOW(CMD_GETCMD); + dewait("wtmode"); + + DE_WLOW(CMD_START); + dewait("start"); + + DE_WLOW(CMD_PDMD); + dewait("initpoll"); + /* Should be running by now */ + + net_devinit(f, &de_driver, eaddr); + + return 0; +} + +int +de_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timeout) +{ + volatile int to = 100000 * timeout; + int len, csr0; + + if ((csr0 = DE_RCSR(DE_PCSR0)) & PCSR0_INTR) + DE_WHIGH(csr0 >> 8); +retry: + if (to-- == 0) + return 0; + + if (dc->dc_rrent[crx].r_flags & RFLG_OWN) + goto retry; + + if (dc->dc_rrent[crx].r_flags & RFLG_ERRS) + len = 0; + else + len = dc->dc_rrent[crx].r_lenerr & RERR_MLEN; + + if (len > maxlen) + len = maxlen; + if (len) + bcopy((char *)&dc->dc_rbuf[crx][0], pkt, len); + + dc->dc_rrent[crx].r_flags = RFLG_OWN; + dc->dc_rrent[crx].r_lenerr = 0; +#ifdef DEV_DEBUG + printf("Got packet: len %d idx %d maxlen %ld\n", len, crx, maxlen); +#endif + if (++crx == NRCV) + crx = 0; + + if (len == 0) + goto retry; + return len; +} + + +int +de_put(struct iodesc *desc, void *pkt, size_t len) +{ + volatile int to = 100000; + int csr0; + + if ((csr0 = DE_RCSR(DE_PCSR0)) & PCSR0_INTR) + DE_WHIGH(csr0 >> 8); +#ifdef DEV_DEBUG + printf("de_put: len %ld\n", len); +#endif +retry: + if (to-- == 0) + return -1; + + if (dc->dc_xrent[ctx].r_flags & RFLG_OWN) + goto retry; + + bcopy(pkt, (char *)&dc->dc_xbuf[ctx][0], len); + + dc->dc_xrent[ctx].r_slen = len; + dc->dc_xrent[ctx].r_tdrerr = 0; + dc->dc_xrent[ctx].r_flags = XFLG_OWN|XFLG_STP|XFLG_ENP; + + DE_WLOW(CMD_PDMD); + dewait("start"); + + if (++ctx == NXMT) + ctx = 0; + return len; +} + +int +declose(struct open_file *f) +{ + DE_WCSR(DE_PCSR0, PCSR0_RSET); + dewait("close"); + return 0; +} + +void +dewait(char *fn) +{ + int csr0; + +#ifdef DEV_DEBUG + printf("dewait: %s...", fn); +#endif + while ((DE_RCSR(DE_PCSR0) & PCSR0_INTR) == 0) + ; + csr0 = DE_RCSR(DE_PCSR0); + DE_WHIGH(csr0 >> 8); +#ifdef DEV_DEBUG + if (csr0 & PCSR0_PCEI) + printf("failed! CSR0 %x", csr0); + else + printf("done"); + printf(", PCSR1 %x\n", DE_RCSR(DE_PCSR1)); +#endif +} diff --git a/sys/arch/vax/stand/boot/if_le.c b/sys/arch/vax/stand/boot/if_le.c index 31fb9f756b1..2c32d88948c 100644 --- a/sys/arch/vax/stand/boot/if_le.c +++ b/sys/arch/vax/stand/boot/if_le.c @@ -1,5 +1,5 @@ -/* $OpenBSD: if_le.c,v 1.1 2000/04/27 02:26:25 bjc Exp $ */ -/* $NetBSD: if_le.c,v 1.4 1999/08/14 19:41:14 ragge Exp $ */ +/* $OpenBSD: if_le.c,v 1.2 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: if_le.c,v 1.6 2000/05/20 13:30:03 ragge Exp $ */ /* * Copyright (c) 1997, 1999 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -47,13 +47,17 @@ #include <netinet/if_ether.h> #include <../include/sid.h> +#include <../include/rpb.h> #include <lib/libsa/netif.h> +#include <lib/libsa/stand.h> #include <dev/ic/am7990reg.h> +#include "vaxstand.h" + /* - * The following are incorrect. Why doesn't DEC follow its own specs??? + * Buffer sizes. */ #define TLEN 1 #define NTBUF (1 << TLEN) @@ -62,23 +66,16 @@ #define BUFSIZE 1518 #define ETHER_MIN_LEN 64 /* minimum frame length, including CRC */ -#define QW_ALLOC(x) ((alloc((x) + 7) + 7) & ~7) - -int le_probe(), le_match(), le_get(), le_put(); -void le_init(), le_end(); -static void copyin(), copyout(); -struct netif_stats le_stats; +#define QW_ALLOC(x) (((int)alloc((x) + 7) + 7) & ~7) -struct netif_dif le_ifs[] = { -/* dif_unit dif_nsel dif_stats dif_private */ -{ 0, 1, &le_stats, }, -}; - -struct netif_stats le_stats; +static int le_get(struct iodesc *, void *, size_t, time_t); +static int le_put(struct iodesc *, void *, size_t); +static void copyout(void *from, int dest, int len); +static void copyin(int src, void *to, int len); struct netif_driver le_driver = { - "le", le_match, le_probe, le_init, le_get, le_put, le_end, le_ifs, 1, + 0, 0, 0, 0, le_get, le_put, }; /* @@ -98,7 +95,7 @@ struct nireg { volatile u_short ni_rdp; /* data port */ volatile short ni_pad0; volatile short ni_rap; /* register select port */ -} *nireg = (struct nireg *)0x200e0000; +} *nireg; volatile struct buffdesc { @@ -138,27 +135,11 @@ int next_rdesc, next_tdesc; (nireg->ni_rap = port, nireg->ni_rdp) int -le_match(nif, machdep_hint) - struct netif *nif; - void *machdep_hint; -{ - return strcmp(machdep_hint, "le") == 0; -} - -le_probe(nif, machdep_hint) - struct netif *nif; - void *machdep_hint; -{ - return 0; -} - -void -le_init(desc, machdep_hint) - struct iodesc *desc; - void *machdep_hint; +leopen(struct open_file *f, int adapt, int ctlr, int unit, int part) { - int stat, i, *ea; + int i, *ea; volatile int to = 100000; + u_char eaddr[6]; next_rdesc = next_tdesc = 0; @@ -170,7 +151,12 @@ le_init(desc, machdep_hint) } else { *(int *)0x20080014 = 0; /* Be sure we do DMA in low 16MB */ ea = (void *)0x20090000; /* XXX ethernetadressen */ + nireg = (void *)0x200e0000; } + if (askname == 0) /* Override if autoboot */ + nireg = (void *)bootrpb.csrphy; + else /* Tell kernel from where we booted */ + bootrpb.csrphy = (int)nireg; if (vax_boardtype == VAX_BTYP_43) addoff = 0x28000000; @@ -182,12 +168,13 @@ igen: ; for (i = 0; i < 6; i++) - desc->myea[i] = ea[i] & 0377; + eaddr[i] = ea[i] & 0377; if (initblock == NULL) { - initblock = (void *)QW_ALLOC(sizeof(struct initblock)) + addoff; + (void *)initblock = + (char *)QW_ALLOC(sizeof(struct initblock)) + addoff; initblock->ib_mode = LE_MODE_NORMAL; - bcopy(desc->myea, initblock->ib_padr, 6); + bcopy(eaddr, initblock->ib_padr, 6); initblock->ib_ladrf1 = 0; initblock->ib_ladrf2 = 0; @@ -210,7 +197,7 @@ igen: rdesc[i].bd_mcnt = 0; } if (kopiera) - copyout(rdesc, (int)rdesc - (int)initblock, + copyout((void *)rdesc, (int)rdesc - (int)initblock, sizeof(struct buffdesc) * NRBUF); for (i = 0; i < NTBUF; i++) { @@ -221,7 +208,7 @@ igen: tdesc[i].bd_mcnt = 0; } if (kopiera) - copyout(tdesc, (int)tdesc - (int)initblock, + copyout((void *)tdesc, (int)tdesc - (int)initblock, sizeof(struct buffdesc) * NTBUF); } @@ -246,14 +233,13 @@ igen: } LEWRCSR(LE_CSR0, LE_C0_INEA | LE_C0_STRT | LE_C0_IDON); + + net_devinit(f, &le_driver, eaddr); + return 0; } int -le_get(desc, pkt, maxlen, timeout) - struct iodesc *desc; - void *pkt; - int maxlen; - time_t timeout; +le_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timeout) { int csr, len; volatile int to = 100000 * timeout; @@ -267,7 +253,7 @@ retry: if (kopiera) copyin((int)&rdesc[next_rdesc] - (int)initblock, - &rdesc[next_rdesc], sizeof(struct buffdesc)); + (void *)&rdesc[next_rdesc], sizeof(struct buffdesc)); if (rdesc[next_rdesc].bd_adrflg & BR_OWN) goto retry; @@ -281,14 +267,14 @@ retry: copyin((rdesc[next_rdesc].bd_adrflg&0xffffff), pkt, len); else - bcopy((void *)(rdesc[next_rdesc].bd_adrflg&0xffffff) + + bcopy((char *)(rdesc[next_rdesc].bd_adrflg&0xffffff) + addoff, pkt, len); } rdesc[next_rdesc].bd_mcnt = 0; rdesc[next_rdesc].bd_adrflg |= BR_OWN; if (kopiera) - copyout(&rdesc[next_rdesc], (int)&rdesc[next_rdesc] - + copyout((void *)&rdesc[next_rdesc], (int)&rdesc[next_rdesc] - (int)initblock, sizeof(struct buffdesc)); if (++next_rdesc >= NRBUF) next_rdesc = 0; @@ -300,10 +286,7 @@ retry: } int -le_put(desc, pkt, len) - struct iodesc *desc; - void *pkt; - int len; +le_put(struct iodesc *desc, void *pkt, size_t len) { volatile int to = 100000; int csr; @@ -317,21 +300,21 @@ retry: if (kopiera) copyin((int)&tdesc[next_tdesc] - (int)initblock, - &tdesc[next_tdesc], sizeof(struct buffdesc)); + (void *)&tdesc[next_tdesc], sizeof(struct buffdesc)); if (tdesc[next_tdesc].bd_adrflg & BT_OWN) goto retry; if (kopiera) copyout(pkt, (tdesc[next_tdesc].bd_adrflg & 0xffffff), len); else - bcopy(pkt, (void *)(tdesc[next_tdesc].bd_adrflg & 0xffffff) + + bcopy(pkt, (char *)(tdesc[next_tdesc].bd_adrflg & 0xffffff) + addoff, len); tdesc[next_tdesc].bd_bcnt = (len < ETHER_MIN_LEN ? -ETHER_MIN_LEN : -len); tdesc[next_tdesc].bd_mcnt = 0; tdesc[next_tdesc].bd_adrflg |= BT_OWN | BT_STP | BT_ENP; if (kopiera) - copyout(&tdesc[next_tdesc], (int)&tdesc[next_tdesc] - + copyout((void *)&tdesc[next_tdesc], (int)&tdesc[next_tdesc] - (int)initblock, sizeof(struct buffdesc)); LEWRCSR(LE_CSR0, LE_C0_TDMD); @@ -350,17 +333,18 @@ retry: return -1; } -void -le_end() +int +leclose(struct open_file *f) { LEWRCSR(LE_CSR0, LE_C0_STOP); + + return 0; } void -copyout(from, dest, len) - short *from; - int dest, len; +copyout(void *f, int dest, int len) { + short *from = f; short *toaddr; toaddr = (short *)0x20120000 + dest; @@ -373,10 +357,9 @@ copyout(from, dest, len) } void -copyin(src, to, len) - short *to; - int src, len; +copyin(int src, void *f, int len) { + short *to = f; short *fromaddr; fromaddr = (short *)0x20120000 + src; diff --git a/sys/arch/vax/stand/boot/if_ni.c b/sys/arch/vax/stand/boot/if_ni.c new file mode 100644 index 00000000000..76f3477eb65 --- /dev/null +++ b/sys/arch/vax/stand/boot/if_ni.c @@ -0,0 +1,534 @@ +/* $OpenBSD: if_ni.c,v 1.1 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: if_ni.c,v 1.2 2000/07/10 10:40:38 ragge 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. + */ + +/* + * Standalone routine for DEBNA Ethernet controller. + */ + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/socket.h> + +#include <net/if.h> + +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/if_ether.h> + +#include <../include/sid.h> +#include <../include/rpb.h> +#include <../include/pte.h> +#include <../include/macros.h> +#include <../include/mtpr.h> +#include <../include/scb.h> + +#include <lib/libkern/libkern.h> + +#include <lib/libsa/netif.h> +#include <lib/libsa/stand.h> +#include <lib/libsa/net.h> + +#include <arch/vax/bi/bireg.h> + +#include "vaxstand.h" + +#undef NIDEBUG +/* + * 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 1 /* Number of transmit buffer fragments */ +#define NRXBUF 24 /* Receive queue entries */ +#define NBDESCS (NTXBUF + 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 18 /* "" transmit "" */ +#define MSGADD 134 /* "" message "" */ + +#include <arch/vax/bi/if_nireg.h> + + +#define SPTSIZ 16384 /* 8MB */ +#define roundpg(x) (((int)x + VAX_PGOFSET) & ~VAX_PGOFSET) +#define ALLOC(x) \ + allocbase;xbzero((caddr_t)allocbase,x);allocbase+=roundpg(x); +#define nipqb (&gvppqb->nc_pqb) +#define gvp gvppqb +#define NI_WREG(csr, val) *(volatile long *)(niaddr + (csr)) = (val) +#define NI_RREG(csr) *(volatile long *)(niaddr + (csr)) +#define DELAY(x) {volatile int i = x * 3;while (--i);} +#define WAITREG(csr,val) while (NI_RREG(csr) & val); + +static int ni_get(struct iodesc *, void *, size_t, time_t); +static int ni_put(struct iodesc *, void *, size_t); + +static int *syspte, allocbase, niaddr; +static struct ni_gvppqb *gvppqb; +static struct ni_fqb *fqb; +static struct ni_bbd *bbd; +static char enaddr[6]; +static int beenhere = 0; + +struct netif_driver ni_driver = { + 0, 0, 0, 0, ni_get, ni_put, +}; + +static void +xbzero(char *a, int s) +{ + while (s--) + *a++ = 0; +} + +static int +failtest(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("ni: %s\n", str); + return 1; + } + return 0; +} + +static int +INSQTI(void *e, void *h) +{ + int ret; + + while ((ret = insqti(e, h)) == ILCK_FAILED) + ; + return ret; +} + +static void * +REMQHI(void *h) +{ + void *ret; + + while ((ret = remqhi(h)) == (void *)ILCK_FAILED) + ; + return ret; +} + +static void +puton(void *pkt, void *q, int args) +{ + INSQTI(pkt, q); + + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, args); + WAITREG(NI_PCR, PCR_OWN); +} + +static void +remput(void *fq, void *pq, int args) +{ + struct ni_dg *data; + int res; + + while ((data = REMQHI(fq)) == 0) + ; + + res = INSQTI(data, pq); + if (res == Q_EMPTY) { + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, args); + } +} + +static void +insput(void *elem, void *q, int args) +{ + int res; + + res = INSQTI(elem, q); + if (res == Q_EMPTY) { + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, args); + } +} + +int +niopen(struct open_file *f, int adapt, int ctlr, int unit, int part) +{ + struct ni_dg *data; + struct ni_msg *msg; + struct ni_ptdb *ptdb; + int i, va, res; + + if (beenhere++ && askname == 0) + return 0; + + niaddr = nexaddr & ~(BI_NODESIZE - 1); + bootrpb.csrphy = niaddr; + if (adapt >= 0) + bootrpb.adpphy = adapt; + /* + * We need a bunch of memory, take it from our load + * address plus 1M. + */ + allocbase = RELOC + 1024 * 1024; + /* + * First create a SPT for the first 8MB of physmem. + */ + syspte = (int *)ALLOC(SPTSIZ*4); + for (i = 0; i < SPTSIZ; i++) + syspte[i] = PG_V|PG_RW|i; + + + gvppqb = (struct ni_gvppqb *)ALLOC(sizeof(struct ni_gvppqb)); + fqb = (struct ni_fqb *)ALLOC(sizeof(struct ni_fqb)); + bbd = (struct ni_bbd *)ALLOC(sizeof(struct ni_bbd) * NBDESCS); + + /* Init the PQB struct */ + nipqb->np_spt = nipqb->np_gpt = (int)syspte; + nipqb->np_sptlen = nipqb->np_gptlen = SPTSIZ; + nipqb->np_vpqb = (u_int32_t)gvp; + 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; +#ifdef NIDEBUG + printf("niopen: syspte %p gvp %p fqb %p bbd %p\n", + syspte, gvppqb, fqb, bbd); +#endif + + NI_WREG(BIREG_VAXBICSR, NI_RREG(BIREG_VAXBICSR) | BICSR_NRST); + DELAY(500000); + i = 20; + while ((NI_RREG(BIREG_VAXBICSR) & BICSR_BROKE) && --i) + DELAY(500000); +#ifdef NIDEBUG + if (i == 0) { + printf("ni: BROKE bit set after reset\n"); + return 1; + } +#endif + /* Check state */ + if (failtest(NI_PSR, PSR_STATE, PSR_UNDEF, "not undefined state")) + return 1; + + /* 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, (int)gvppqb | PCR_INIT | PCR_OWN); + while (NI_RREG(NI_PCR) & PCR_OWN) + DELAY(100000); + + /* Check state */ + if (failtest(NI_PSR, PSR_INITED, PSR_INITED, "failed initialize")) + return 1; + + 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(NI_PSR, PSR_STATE, PSR_ENABLED, "failed enable")) + return 1; + + NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN); + +#ifdef NIDEBUG + printf("Set up message free queue\n"); +#endif + + /* Set up message free queue */ + va = ALLOC(NMSGBUF * 512); + for (i = 0; i < NMSGBUF; i++) { + 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); + +#ifdef NIDEBUG + printf("Set up xmit queue\n"); +#endif + + /* Set up xmit queue */ + va = ALLOC(NTXBUF * 512); + 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; + data->bufs[0]._offset = 0; + data->bufs[0]._key = 1; + data->nd_cmdref = allocbase; + bbd[i].nb_key = 1; + bbd[i].nb_status = 0; + bbd[i].nb_pte = (int)&syspte[allocbase>>9]; + allocbase += 2048; + data->bufs[0]._index = i; + + 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); + +#ifdef NIDEBUG + printf("recv buffers\n"); +#endif + + /* recv buffers */ + va = ALLOC(NRXBUF * 512); + for (i = 0; i < NRXBUF; i++) { + struct ni_dg *data; + struct ni_bbd *bd; + int idx; + + data = (void *)(va + i * 512); + data->nd_cmdref = allocbase; + data->nd_len = RXADD; + data->nd_opcode = BVP_DGRAMRX; + data->nd_ptdbidx = 2; + data->bufs[0]._key = 1; + + idx = NTXBUF + i; + bd = &bbd[idx]; + bd->nb_pte = (int)&syspte[allocbase>>9]; + allocbase += 2048; + bd->nb_len = 2048; + bd->nb_status = NIBD_VALID; + bd->nb_key = 1; + data->bufs[0]._offset = 0; + data->bufs[0]._len = bd->nb_len; + data->bufs[0]._index = idx; + + 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); + +#ifdef NIDEBUG + printf("Set initial parameters\n"); +#endif + + /* 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; + + puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + + + while ((data = REMQHI(&gvp->nc_forwr)) == 0) + ; + + msg = (struct ni_msg *)data; +#ifdef NIDEBUG + if (msg->nm_opcode2 != NI_WPARAM) { + printf("ni: wrong response code %d\n", msg->nm_opcode2); + insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + } +#endif + bcopy(((struct ni_param *)&msg->nm_text[0])->np_dpa, + enaddr, ETHER_ADDR_LEN); + insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + +#ifdef NIDEBUG + printf("Clear counters\n"); +#endif + + /* 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; + + puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + +#ifdef NIDEBUG + printf("Enable transmit logic\n"); +#endif + + /* 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]; + bzero(ptdb, sizeof(struct ni_ptdb)); + ptdb->np_index = 1; + ptdb->np_fque = 1; + + puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + +#ifdef NIDEBUG + printf("ni: hardware address %s\n", ether_sprintf(enaddr)); + printf("Setting receive parameters\n"); +#endif + msg = REMQHI(&fqb->nf_mforw); + ptdb = (struct ni_ptdb *)&msg->nm_text[0]; + bzero(ptdb, sizeof(struct ni_ptdb)); + msg->nm_opcode = BVP_MSG; + msg->nm_len = 18; + ptdb->np_index = 2; + ptdb->np_fque = 2; + msg->nm_opcode2 = NI_STPTDB; + ptdb->np_type = ETHERTYPE_IP; + ptdb->np_flags = PTDB_UNKN|PTDB_BDC; + memset(ptdb->np_mcast[0], 0xff, ETHER_ADDR_LEN); + ptdb->np_adrlen = 1; + msg->nm_len += 8; + insput(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + +#ifdef NIDEBUG + printf("finished\n"); +#endif + + net_devinit(f, &ni_driver, enaddr); + return 0; +} + +int +ni_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timeout) +{ + struct ni_dg *data; + struct ni_bbd *bd; + int nsec = getsecs() + timeout; + int len, idx; + +loop: while ((data = REMQHI(&gvp->nc_forwr)) == 0 && (nsec > getsecs())) + ; + + if (nsec <= getsecs()) + return 0; + + switch (data->nd_opcode) { + case BVP_DGRAMRX: + idx = data->bufs[0]._index; + bd = &bbd[idx]; + len = data->bufs[0]._len; + if (len > maxlen) + len = maxlen; + bcopy((caddr_t)data->nd_cmdref, pkt, len); + bd->nb_pte = (int)&syspte[data->nd_cmdref>>9]; + data->bufs[0]._len = bd->nb_len = 2048; + data->bufs[0]._offset = 0; + data->bufs[0]._key = 1; + bd->nb_status = NIBD_VALID; + bd->nb_key = 1; + data->nd_len = RXADD; + data->nd_status = 0; + insput(data, &fqb->nf_rforw, + PCR_FREEQNE|PCR_RFREEQ|PCR_OWN); + return len; + + case BVP_DGRAM: + insput(data, &fqb->nf_dforw, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN); + break; + default: + insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); + break; + } + + NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~(PSR_OWN|PSR_RSQ)); + goto loop; +} + +int +ni_put(struct iodesc *desc, void *pkt, size_t len) +{ + struct ni_dg *data; + struct ni_bbd *bdp; + + data = REMQHI(&fqb->nf_dforw); +#ifdef NIDEBUG + if (data == 0) { + printf("ni_put: driver problem, data == 0\n"); + return -1; + } +#endif + bdp = &bbd[(data->bufs[0]._index & 0x7fff)]; + bdp->nb_status = NIBD_VALID; + bdp->nb_len = (len < 64 ? 64 : len); + bcopy(pkt, (caddr_t)data->nd_cmdref, len); + data->bufs[0]._offset = 0; + data->bufs[0]._len = bdp->nb_len; + data->nd_opcode = BVP_DGRAM; + data->nd_pad3 = 1; + data->nd_ptdbidx = 1; + data->nd_len = 18; + insput(data, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); + return len; +} + +int +niclose(struct open_file *f) +{ + if (beenhere) { + WAITREG(NI_PCR, PCR_OWN); + NI_WREG(NI_PCR, PCR_OWN|PCR_SHUTDOWN); + WAITREG(NI_PCR, PCR_OWN); + } + return 0; +} diff --git a/sys/arch/vax/stand/boot/if_qe.c b/sys/arch/vax/stand/boot/if_qe.c index a1c1c248907..36a6b30d376 100644 --- a/sys/arch/vax/stand/boot/if_qe.c +++ b/sys/arch/vax/stand/boot/if_qe.c @@ -1,5 +1,5 @@ -/* $OpenBSD: if_qe.c,v 1.2 2002/03/14 03:16:02 millert Exp $ */ -/* $NetBSD: if_qe.c,v 1.2 1999/06/30 18:19:26 ragge Exp $ */ +/* $OpenBSD: if_qe.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: if_qe.c,v 1.3 2000/05/20 13:30:03 ragge Exp $ */ /* * Copyright (c) 1998 Roar Thronæs. All rights reserved. @@ -39,116 +39,103 @@ #include <netinet/in_systm.h> #include <lib/libsa/netif.h> +#include <lib/libsa/stand.h> #include <arch/vax/if/if_qereg.h> -int qe_probe(), qe_match(), qe_get(), qe_put(); -void qe_init(), qe_end(); +#include "../include/rpb.h" -struct netif_stats qe_stats; +#include "vaxstand.h" -struct netif_dif qe_ifs[] = { -/* dif_unit dif_nsel dif_stats dif_private */ -{ 0, 1, &qe_stats, }, -}; - -struct netif_stats qe_stats; +static int qe_get(struct iodesc *desc, void *pkt, size_t, time_t timeout); +static int qe_put(struct iodesc *desc, void *pkt, size_t); +static void qe_init(u_char *eaddr); struct netif_driver qe_driver = { - "qe", qe_match, qe_probe, qe_init, qe_get, qe_put, qe_end, qe_ifs, 1, + 0, 0, 0, 0, qe_get, qe_put, }; -#define PG_V 0x80000000 -#define QBAMAP 0x20088000 +#define NRCV 1 /* Receive descriptors */ +#define NXMT 1 /* Transmit descriptors */ -#define NRCV 1 /* Receive descriptors */ -#define NXMT 1 /* Transmit descriptors */ +#define QE_INTS (QE_RCV_INT | QE_XMIT_INT) +#define MAXPACKETSIZE 0x800 /* Because of (buggy) DEQNA */ -#define QE_INTS (QE_RCV_INT | QE_XMIT_INT) -#define MAXPACKETSIZE 0x800 /* Because of (buggy) DEQNA */ - -struct qe_softc { - struct qe_ring rring[NRCV+2]; /* Receive ring descriptors */ - struct qe_ring tring[NXMT+2]; /* Xmit ring descriptors */ - u_char setup_pkt[16][8]; /* Setup packet */ +static struct qe_softc { + struct qe_ring rring[NRCV+2]; /* Receive ring descriptors */ + struct qe_ring tring[NXMT+2]; /* Xmit ring descriptors */ + u_char setup_pkt[16][8]; /* Setup packet */ char qein[2048], qeout[2048];/* Packet buffers */ -}; +} qe_softc; -static volatile struct qe_softc *sc; +static struct qe_softc *sc = &qe_softc; static int addr; #define QE_WCSR(csr, val) \ - (*((volatile u_short *)(addr + (csr))) = (val)) + (*((volatile u_short *)(addr + (csr))) = (val)) #define QE_RCSR(csr) \ - *((volatile u_short *)(addr + (csr))) -#define DELAY(x) {volatile int i = x;while (--i);} -#define LOWORD(x) ((int)(x) & 0xffff) -#define HIWORD(x) (((int)(x) >> 16) & 0x3f) + *((volatile u_short *)(addr + (csr))) +#define DELAY(x) {volatile int i = x;while (--i);} +#define LOWORD(x) ((int)(x) & 0xffff) +#define HIWORD(x) (((int)(x) >> 16) & 0x3f) +#define qereg(x) ((x) & 017777) int -qe_match(nif, machdep_hint) - struct netif *nif; - void *machdep_hint; -{ - return strcmp(machdep_hint, "qe") == 0; -} +qeopen(struct open_file *f, int adapt, int ctlr, int unit, int part) { + u_char eaddr[6]; + + if (askname == 0) + addr = bootrpb.csrphy; /* Autoboot; use RPB instead */ + else { + addr = 0x20000000; + if (unit == 0) + addr += qereg(0774440); /* XQA0 */ + else if (unit == 1) + addr += qereg(0174460); /* XQB0 */ + else + return ECTLR; + } -int -qe_probe(nif, machdep_hint) - struct netif *nif; - void *machdep_hint; -{ + qe_init(eaddr); + + net_devinit(f, &qe_driver, eaddr); return 0; } void -qe_init(desc, machdep_hint) - struct iodesc *desc; - void *machdep_hint; +qe_init(u_char *eaddr) { - int i,j; - u_int *qm=(u_int *) QBAMAP; - - sc = (void *)alloc(sizeof(struct qe_softc)); - - bzero(sc,sizeof(struct qe_softc)); - - for(i = 0; i < 8192; i++) - qm[i] = PG_V | i; - - /* XXX hardcoded addr */ - addr = (0x20000000 + (0774440 & 017777)); QE_WCSR(QE_CSR_CSR, QE_RESET); QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~QE_RESET); - for (i = 0; i < 6; i++) { - sc->setup_pkt[i][1] = QE_RCSR(i * 2); - sc->setup_pkt[i+8][1] = QE_RCSR(i * 2); + for (i = 0; i < 6; i++) { + sc->setup_pkt[i][1] = QE_RCSR(i * 2); + sc->setup_pkt[i+8][1] = QE_RCSR(i * 2); sc->setup_pkt[i][2] = 0xff; - sc->setup_pkt[i+8][2] = QE_RCSR(i * 2); + sc->setup_pkt[i+8][2] = QE_RCSR(i * 2); for (j=3; j < 8; j++) { - sc->setup_pkt[i][j] = QE_RCSR(i * 2); - sc->setup_pkt[i+8][j] = QE_RCSR(i * 2); + sc->setup_pkt[i][j] = QE_RCSR(i * 2); + sc->setup_pkt[i+8][j] = QE_RCSR(i * 2); } - desc->myea[i] = QE_RCSR(i * 2); + eaddr[i] = QE_RCSR(i * 2); } bzero((caddr_t)sc->rring, sizeof(struct qe_ring)); - sc->rring->qe_buf_len = -64; - sc->rring->qe_addr_lo = (short)((int)sc->setup_pkt); - sc->rring->qe_addr_hi = (short)((int)sc->setup_pkt >> 16); + sc->rring->qe_buf_len = -64; + sc->rring->qe_addr_lo = (short)((int)sc->setup_pkt); + sc->rring->qe_addr_hi = (short)((int)sc->setup_pkt >> 16); bzero((caddr_t)sc->tring, sizeof(struct qe_ring)); - sc->tring->qe_buf_len = -64; - sc->tring->qe_addr_lo = (short)((int)sc->setup_pkt); - sc->tring->qe_addr_hi = (short)((int)sc->setup_pkt >> 16); + sc->tring->qe_buf_len = -64; + sc->tring->qe_addr_lo = (short)((int)sc->setup_pkt); + sc->tring->qe_addr_hi = (short)((int)sc->setup_pkt >> 16); - sc->rring[0].qe_flag = sc->rring[0].qe_status1 = QE_NOTYET; + sc->rring[0].qe_flag = sc->rring[0].qe_status1 = QE_NOTYET; sc->rring->qe_addr_hi |= QE_VALID; - sc->tring[0].qe_flag = sc->tring[0].qe_status1 = QE_NOTYET; + sc->tring[0].qe_flag = sc->tring[0].qe_status1 = QE_NOTYET; sc->tring->qe_addr_hi |= QE_VALID | QE_SETUP | QE_EOMSG; QE_WCSR(QE_CSR_CSR, QE_XMIT_INT | QE_RCV_INT); @@ -164,8 +151,8 @@ qe_init(desc, machdep_hint) QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~(QE_INT_ENABLE|QE_ELOOP)); QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) | QE_ILOOP); - sc->rring[0].qe_addr_lo = (short)((int)sc->qein & 0xffff); - sc->rring[0].qe_addr_hi = (short)((int)sc->qein >> 16); + sc->rring[0].qe_addr_lo = (short)((int)sc->qein & 0xffff); + sc->rring[0].qe_addr_hi = (short)((int)sc->qein >> 16); sc->rring[0].qe_buf_len=-MAXPACKETSIZE/2; sc->rring[0].qe_addr_hi |= QE_VALID; sc->rring[0].qe_flag=sc->rring[0].qe_status1=QE_NOTYET; @@ -176,8 +163,8 @@ qe_init(desc, machdep_hint) sc->rring[1].qe_flag=sc->rring[1].qe_status1=QE_NOTYET; sc->rring[1].qe_status2=1; - sc->tring[0].qe_addr_lo = (short)((int)sc->qeout & 0xffff); - sc->tring[0].qe_addr_hi = (short)((int)sc->qeout >> 16); + sc->tring[0].qe_addr_lo = (short)((int)sc->qeout & 0xffff); + sc->tring[0].qe_addr_hi = (short)((int)sc->qeout >> 16); sc->tring[0].qe_buf_len=0; sc->tring[0].qe_flag=sc->tring[0].qe_status1=QE_NOTYET; sc->tring[0].qe_addr_hi |= QE_EOMSG|QE_VALID; @@ -192,12 +179,7 @@ qe_init(desc, machdep_hint) } int -qe_get(desc, pkt, maxlen, timeout) - struct iodesc *desc; - void *pkt; - int maxlen; - time_t timeout; -{ +qe_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timeout) { int len, j; retry: @@ -215,10 +197,10 @@ retry: if (sc->rring[0].qe_status1 & 0xc000) goto fail; - if (len == 0) + if (len == 0) goto retry; - bcopy((void *)sc->qein,pkt,len); + bcopy((void*)sc->qein,pkt,len); end: @@ -236,17 +218,13 @@ fail: len = -1; } int -qe_put(desc, pkt, len) - struct iodesc *desc; - void *pkt; - int len; -{ +qe_put(struct iodesc *desc, void *pkt, size_t len) { int j; - bcopy(pkt,sc->qeout,len); - sc->tring[0].qe_buf_len=-len/2; - sc->tring[0].qe_flag=sc->tring[0].qe_status1=QE_NOTYET; - sc->tring[1].qe_flag=sc->tring[1].qe_status1=QE_NOTYET; + bcopy(pkt, (char *)sc->qeout, len); + sc->tring[0].qe_buf_len=-len/2; + sc->tring[0].qe_flag=sc->tring[0].qe_status1=QE_NOTYET; + sc->tring[1].qe_flag=sc->tring[1].qe_status1=QE_NOTYET; QE_WCSR(QE_CSR_XMTL, LOWORD(sc->tring)); QE_WCSR(QE_CSR_XMTH, HIWORD(sc->tring)); @@ -255,22 +233,27 @@ qe_put(desc, pkt, len) ; if ((QE_RCSR(QE_CSR_CSR) & QE_XMIT_INT) == 0) { - qe_init(desc,0); + char eaddr[6]; + + qe_init(eaddr); return -1; } QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~QE_RCV_INT); if (sc->tring[0].qe_status1 & 0xc000) { - qe_init(desc,0); + char eaddr[6]; + + qe_init(eaddr); return -1; } return len; } -void -qe_end(nif) - struct netif *nif; +int +qeclose(struct open_file *nif) { QE_WCSR(QE_CSR_CSR, QE_RESET); QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~QE_RESET); + + return 0; } diff --git a/sys/arch/vax/stand/boot/if_ze.c b/sys/arch/vax/stand/boot/if_ze.c index 3f88decb7c6..a58081d38d0 100644 --- a/sys/arch/vax/stand/boot/if_ze.c +++ b/sys/arch/vax/stand/boot/if_ze.c @@ -1,5 +1,5 @@ -/* $OpenBSD: if_ze.c,v 1.3 2002/03/31 01:10:36 hugh Exp $ */ -/* $NetBSD: if_ze.c,v 1.5 1999/08/23 19:09:27 ragge Exp $ */ +/* $OpenBSD: if_ze.c,v 1.4 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: if_ze.c,v 1.12 2002/05/27 16:54:18 ragge Exp $ */ /* * Copyright (c) 1998 James R. Maynard III. All rights reserved. * @@ -42,39 +42,33 @@ #include <netinet/in_systm.h> #include <netinet/if_ether.h> -#include <lib/libkern/libkern.h> #include <lib/libsa/netif.h> #include <lib/libsa/stand.h> +#include <lib/libsa/net.h> #include <arch/vax/if/sgecreg.h> #include "arch/vax/include/sid.h" +#include "arch/vax/include/rpb.h" -int ze_probe(), ze_match(), ze_get(), ze_put(); -void ze_init(), ze_end(); +#include "vaxstand.h" -struct netif_stats ze_stats; - -struct netif_dif ze_ifs[] = { -/* dif_unit dif_nsel dif_stats dif_private */ -{ 0, 1, &ze_stats, }, -}; - -struct netif_stats ze_stats; +static int ze_get(struct iodesc *, void *, size_t, time_t); +static int ze_put(struct iodesc *, void *, size_t); #define ETHER_MIN_LEN 64 #define ETHER_MAX_LEN 1518 struct netif_driver ze_driver = { - "ze", ze_match, ze_probe, ze_init, ze_get, ze_put, ze_end, ze_ifs, 1, + 0, 0, 0, 0, ze_get, ze_put, }; #define NRCV 8 /* allocate 8 receive descriptors */ -#define NXMT 5 /* and 5 transmit - must be >1 */ +#define NXMT 4 /* and 4 transmit - must be >1 */ #define SETUP_FRAME_LEN 128 /* length of the setup frame */ /* allocate a buffer on an octaword boundary */ -#define OW_ALLOC(x) ((void *)((int)(alloc((x) + 15) + 15) & ~15)) +#define OW_ALLOC(x) ((void *)((int)((int)alloc((x) + 15) + 15) & ~15)) static volatile struct zedevice *addr; @@ -83,33 +77,17 @@ struct ze_rdes *ze_rdes_list; /* and receive desc list */ u_char ze_myaddr[ETHER_ADDR_LEN]; /* my Ethernet address */ int -ze_match(nif, machdep_hint) - struct netif *nif; - void *machdep_hint; -{ - return strcmp(machdep_hint, "ze") == 0; -} - -int -ze_probe(nif, machdep_hint) - struct netif *nif; - void *machdep_hint; -{ - return 0; -} - -void -ze_init(desc, machdep_hint) - struct iodesc *desc; - void *machdep_hint; +zeopen(struct open_file *f, int adapt, int ctlr, int unit, int part) { u_long nicsr0_work, *nisa_rom; - int i; - u_char *saved_buf; struct ze_tdes *ze_setup_tdes_list; + int i; /* point to the device in memory */ - addr = (struct zedevice *)0x20008000; + if (askname == 0) /* Override if autoboot */ + addr = (struct zedevice *)bootrpb.csrphy; + else + addr = (struct zedevice *)0x20008000; /* reset the device and wait for completion */ addr->ze_nicsr6 = ZE_NICSR6_MBO | ZE_NICSR6_RE; @@ -117,6 +95,7 @@ ze_init(desc, machdep_hint) ; if (addr->ze_nicsr5 & ZE_NICSR5_SF) { printf("SGEC self-test failed...\n"); + return 1; } /* Get our Ethernet address */ @@ -124,6 +103,10 @@ ze_init(desc, machdep_hint) nisa_rom = (u_long *)0x27800000; for (i=0; i<ETHER_ADDR_LEN; i++) ze_myaddr[i] = nisa_rom[i] & 0377; + } else if (vax_boardtype == VAX_BTYP_VXT) { + nisa_rom = (u_long *)0x200c4000; + for (i=0; i<ETHER_ADDR_LEN; i++) + ze_myaddr[i] = nisa_rom[i] & 0xff; } else { nisa_rom = (u_long *)0x20084000; for (i=0; i<ETHER_ADDR_LEN; i++) @@ -132,7 +115,7 @@ ze_init(desc, machdep_hint) else ze_myaddr[i] = (nisa_rom[i] & 0x0000ff00) >> 8; } - bcopy(ze_myaddr,desc->myea,ETHER_ADDR_LEN); + printf("SGEC: Ethernet address %s\n", ether_sprintf(ze_myaddr)); /* initialize SGEC operating mode */ /* disable interrupts here */ @@ -198,13 +181,16 @@ ze_init(desc, machdep_hint) addr->ze_nicsr6 |= ZE_NICSR6_SR; /* And away-y-y we go! */ + + net_devinit(f, &ze_driver, ze_myaddr); + return 0; } int ze_get(desc, pkt, maxlen, timeout) struct iodesc *desc; void *pkt; - int maxlen; + size_t maxlen; time_t timeout; { int timeout_ctr=100000*timeout, len, rdes; @@ -260,7 +246,7 @@ int ze_put(desc, pkt, len) struct iodesc *desc; void *pkt; - int len; + size_t len; { int timeout=100000; @@ -289,7 +275,7 @@ ze_put(desc, pkt, len) /* Wait for the frame to be sent, but not too long. */ timeout = 100000; - while ((addr->ze_nicsr5 & ZE_NICSR5_TI == 0) && (--timeout>0)) + while (((addr->ze_nicsr5 & ZE_NICSR5_TI) == 0) && (--timeout>0)) ; /* Reset the transmitter interrupt pending flag. */ @@ -300,8 +286,10 @@ ze_put(desc, pkt, len) return -1; } -void -ze_end() +int +zeclose(struct open_file *f) { addr->ze_nicsr6 = ZE_NICSR6_RE; + + return 0; } diff --git a/sys/arch/vax/stand/boot/mfm.c b/sys/arch/vax/stand/boot/mfm.c index 2e22bda7139..761104bd8c1 100644 --- a/sys/arch/vax/stand/boot/mfm.c +++ b/sys/arch/vax/stand/boot/mfm.c @@ -1,5 +1,5 @@ -/* $OpenBSD: mfm.c,v 1.2 2002/03/14 03:16:02 millert Exp $ */ -/* $NetBSD: mfm.c,v 1.2 1997/03/15 13:04:28 ragge Exp $ */ +/* $OpenBSD: mfm.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: mfm.c,v 1.4 2001/07/26 22:55:13 wiz Exp $ */ /* * Copyright (c) 1996 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -69,29 +69,36 @@ struct mfm_softc { int unit; }; -int mfmstrategy(), mfmopen(); -struct disklabel mfmlabel; -struct mfm_softc mfm_softc; -char io_buf[DEV_BSIZE]; +static struct disklabel mfmlabel; +static struct mfm_softc mfm_softc; +static char io_buf[DEV_BSIZE]; /* * These should probably be somewhere else, but ka410 is the only * one with mfm disks anyway... */ -volatile unsigned char *ka410_intreq = (void *)0x2008000f; -volatile unsigned char *ka410_intclr = (void *)0x2008000f; -volatile unsigned char *ka410_intmsk = (void *)0x2008000c; +volatile unsigned char *ka410_intreq = (void*)0x2008000f; +volatile unsigned char *ka410_intclr = (void*)0x2008000f; +volatile unsigned char *ka410_intmsk = (void*)0x2008000c; static volatile struct hdc9224_DKCreg *dkc = (void *) 0x200c0000; static volatile struct hdc9224_UDCreg sreg; /* input */ static volatile struct hdc9224_UDCreg creg; /* output */ +static void sreg_read(void); +static void creg_write(void); +static int mfm_rxprepare(void); +static int mfm_command(int cmd); +static int mfm_rxselect(int unit); +static int mfm_rdselect(int unit); +static int mfm_rxstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize); +static int mfm_rdstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize); /* * we have to wait 0.7 usec between two accesses to any of the * dkc-registers, on a VS2000 with 1 MIPS, this is roughly one * instruction. Thus the loop-overhead will be enough... */ -static int +static void sreg_read() { int i; @@ -103,7 +110,7 @@ sreg_read() *p++ = dkc->dkc_reg; /* dkc_reg auto-increments */ } -static int +static void creg_write() { int i; @@ -120,7 +127,7 @@ creg_write() * * before reading/writing a sector from/to floppy, we use the SEEK/READ_ID * command to place the head at the desired location. Then we wait some - * time before issueing the real command in order to let the drive become + * time before issuing the real command in order to let the drive become * ready... */ int @@ -138,8 +145,7 @@ mfm_rxprepare() } int -mfm_rxselect(unit) - int unit; +mfm_rxselect(int unit) { int error; @@ -164,12 +170,12 @@ mfm_rxselect(unit) */ error = mfm_command(DKC_CMD_DRSEL_RX33 | unit); - if ((error != 0) || (sreg.udc_dstat & UDC_DS_READY == 0)) { + if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) { printf("\nfloppy-drive not ready (new floppy inserted?)\n\n"); creg.udc_rtcnt &= ~UDC_RC_INVRDY; /* clear INVRDY-flag */ error = mfm_command(DKC_CMD_DRSEL_RX33 | unit); - if ((error != 0) || (sreg.udc_dstat & UDC_DS_READY == 0)) { + if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) { printf("diskette not ready(1): %x/%x\n", error, sreg.udc_dstat); printf("floppy-drive offline?\n"); @@ -184,14 +190,14 @@ mfm_rxselect(unit) * now ready should be 0, cause INVRDY is not set * (retrying a command makes this fail...) */ - if ((error != 0) || (sreg.udc_dstat & UDC_DS_READY == 1)) { + if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 1)) { printf("diskette not ready(2): %x/%x\n", error, sreg.udc_dstat); } creg.udc_rtcnt |= UDC_RC_INVRDY; error = mfm_command(DKC_CMD_DRSEL_RX33 | unit); - if ((error != 0) || (sreg.udc_dstat & UDC_DS_READY == 0)) { + if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) { printf("diskette not ready(3): %x/%x\n", error, sreg.udc_dstat); printf("no floppy inserted or floppy-door open\n"); @@ -203,8 +209,7 @@ mfm_rxselect(unit) } int -mfm_rdselect(unit) - int unit; +mfm_rdselect(int unit) { int error; @@ -232,8 +237,7 @@ mfm_rdselect(unit) static int mfm_retry = 0; int -mfm_command(cmd) - int cmd; +mfm_command(int cmd) { int termcode, ready, i; @@ -354,14 +358,16 @@ display_xbn(p) } #endif +int mfmopen(f, adapt, ctlr, unit, part) struct open_file *f; int ctlr, unit, part; { char *msg; struct disklabel *lp = &mfmlabel; - volatile struct mfm_softc *msc = &mfm_softc; - int i, err; + struct mfm_softc *msc = &mfm_softc; + int err; + size_t i; bzero(lp, sizeof(struct disklabel)); msc->unit = unit; @@ -379,12 +385,14 @@ mfmopen(f, adapt, ctlr, unit, part) f->f_devdata = (void *) msc; { +#ifdef verbose int k; unsigned char *ucp; struct mfm_xbn *xp; +#endif /* mfmstrategy(msc, F_READ, -16, 8192, io_buf, &i); */ - mfmstrategy(msc, F_READ, -16, DEV_BSIZE, io_buf, &i); + mfmstrategy(msc, F_READ, -16, 512, io_buf, &i); #ifdef verbose printf("dumping raw disk-block #0:\n"); ucp = io_buf; @@ -446,15 +454,11 @@ mfmopen(f, adapt, ctlr, unit, part) return (0); } -mfm_rxstrategy(msc, func, dblk, size, buf, rsize) - struct mfm_softc *msc; - int func; - daddr_t dblk; - char *buf; - int size, *rsize; -{ +int +mfm_rxstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize) { + struct mfm_softc *msc = f; struct disklabel *lp; - int block, sect, head, cyl, scount, i, cmd, res, sval; + int block, sect, head, cyl, scount, res; lp = &mfmlabel; block = (dblk < 0 ? 0 : dblk + lp->d_partitions[msc->part].p_offset); @@ -484,7 +488,7 @@ mfm_rxstrategy(msc, func, dblk, size, buf, rsize) sect = sect % lp->d_nsectors; /* - * *rsize = 512; /* one sector after the other + * *rsize = 512; one sector after the other * ... */ *rsize = 512 * min(scount, lp->d_nsectors - sect); @@ -528,22 +532,18 @@ mfm_rxstrategy(msc, func, dblk, size, buf, rsize) scount -= *rsize / 512; block += *rsize / 512; - buf += *rsize; + (char *)buf += *rsize; } *rsize = size; return 0; } -mfm_rdstrategy(msc, func, dblk, size, buf, rsize) - struct mfm_softc *msc; - int func; - daddr_t dblk; - char *buf; - int size, *rsize; -{ +int +mfm_rdstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize) { + struct mfm_softc *msc = f; struct disklabel *lp; - int block, sect, head, cyl, scount, i, cmd, res, sval; + int block, sect, head, cyl, scount, cmd, res; lp = &mfmlabel; block = (dblk < 0 ? 0 : dblk + lp->d_partitions[msc->part].p_offset); @@ -618,7 +618,7 @@ mfm_rdstrategy(msc, func, dblk, size, buf, rsize) scount -= *rsize / 512; block += *rsize / 512; - buf += *rsize; + (char *)buf += *rsize; } /* @@ -631,25 +631,26 @@ mfm_rdstrategy(msc, func, dblk, size, buf, rsize) } int -mfmstrategy(msc, func, dblk, size, buf, rsize) - struct mfm_softc *msc; +mfmstrategy(f, func, dblk, size, buf, rsize) + void *f; int func; daddr_t dblk; - char *buf; - int size, *rsize; + void *buf; + size_t size, *rsize; { + struct mfm_softc *msc = f; int res = -1; switch (msc->unit) { case 0: case 1: - res = mfm_rdstrategy(msc, func, dblk, size, buf, rsize); + res = mfm_rdstrategy(f, func, dblk, size, buf, rsize); break; case 2: - res = mfm_rxstrategy(msc, func, dblk, size, buf, rsize); + res = mfm_rxstrategy(f, func, dblk, size, buf, rsize); break; default: - printf("invalid unit %d in mfmstrategy()\n"); + printf("invalid unit %d in mfmstrategy()\n", msc->unit); } return (res); } diff --git a/sys/arch/vax/stand/boot/netio.c b/sys/arch/vax/stand/boot/netio.c index 116e28f2c9c..8a3f5e798c9 100644 --- a/sys/arch/vax/stand/boot/netio.c +++ b/sys/arch/vax/stand/boot/netio.c @@ -1,5 +1,5 @@ -/* $OpenBSD: netio.c,v 1.3 2002/03/14 01:26:47 millert Exp $ */ -/* $NetBSD: netio.c,v 1.4 1999/06/30 18:38:03 ragge Exp $ */ +/* $OpenBSD: netio.c,v 1.4 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: netio.c,v 1.6 2000/05/26 20:16:46 ragge Exp $ */ /*- * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. @@ -53,7 +53,7 @@ * derived from this software without specific prior written permission. * 4. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by Gordon W. Ross + * This product includes software developed by Gordon W. Ross * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -69,7 +69,7 @@ /* * This module implements a "raw device" interface suitable for - * use by the stand-alone I/O library NFS code. This interface + * use by the stand-alone I/O library NFS code. This interface * does not support any "block" access, and exists only for the * purpose of initializing the network interface, getting boot * parameters, and performing the NFS mount. @@ -79,7 +79,7 @@ * find interface - netif_open() * RARP for IP address - rarp_getipaddress() * RPC/bootparams - callrpc(d, RPC_BOOTPARAMS, ...) - * RPC/mountd - nfs_mount(sock, ip, path) + * RPC/mountd - nfs_mount(sock, ip, path) * * the root file handle from mountd is saved in a global * for use by the NFS open code (NFS/lookup). @@ -97,133 +97,34 @@ #include "lib/libsa/netif.h" #include "lib/libsa/bootparam.h" #include "lib/libsa/nfs.h" +#include "lib/libsa/bootp.h" -extern int nfs_root_node[]; /* XXX - get from nfs_mount() */ +#include "vaxstand.h" -struct in_addr myip, rootip, gateip; -n_long netmask; -char rootpath[FNAME_SIZE]; +static struct iodesc desc; +static int inited = 0; -int netdev_sock = -1; -static int open_count; - -int netio_ask = 0; /* default to bootparam, can override */ - -static char input_line[100]; - -int netmountroot(struct open_file *, char *); - -/* - * Called by devopen after it sets f->f_dev to our devsw entry. - * This opens the low-level device and sets f->f_devdata. - */ -int -netopen(f, devname) - struct open_file *f; - char *devname; /* Device part of file name (or NULL). */ -{ - int error = 0; - - /* On first open, do netif open, mount, etc. */ - if (open_count == 0) { - /* Find network interface. */ - if ((netdev_sock = netif_open(devname)) < 0) - return (error=ENXIO); - if ((error = netmountroot(f, devname)) != 0) - return (error); - } - open_count++; - f->f_devdata = nfs_root_node; - return (error); -} - -int -netclose(f) - struct open_file *f; -{ - if(--open_count == 0) - netif_close(netdev_sock); - f->f_devdata = NULL; - return 0; -} - -int -netstrategy(devdata, func, dblk, size, v_buf, rsize) - void *devdata; - int func; - daddr_t dblk; - size_t size; - void *v_buf; - size_t *rsize; +struct iodesc * +socktodesc(sock) { - - *rsize = size; - return EIO; + return &desc; } int -netmountroot(f, devname) - struct open_file *f; - char *devname; /* Device part of file name (or NULL). */ -{ - int error; - struct iodesc *d; - - if (netio_ask) { - get_my_ip: - printf("My IP address? "); - bzero(input_line, sizeof(input_line)); - gets(input_line); - if ((myip.s_addr = inet_addr(input_line)) == - htonl(INADDR_NONE)) { - printf("invalid IP address: %s\n", input_line); - goto get_my_ip; - } - - get_my_netmask: - printf("My netmask? "); - bzero(input_line, sizeof(input_line)); - gets(input_line); - if ((netmask = inet_addr(input_line)) == - htonl(INADDR_NONE)) { - printf("invalid netmask: %s\n", input_line); - goto get_my_netmask; - } +net_devinit(struct open_file *f, struct netif_driver *drv, u_char *eaddr) { + static struct netif best_if; + struct iodesc *s; + int r; - get_my_gateway: - printf("My gateway? "); - bzero(input_line, sizeof(input_line)); - gets(input_line); - if ((gateip.s_addr = inet_addr(input_line)) == - htonl(INADDR_NONE)) { - printf("invalid IP address: %s\n", input_line); - goto get_my_gateway; - } + if (inited) + return 0; + /* find a free socket */ + s = &desc; - get_server_ip: - printf("Server IP address? "); - bzero(input_line, sizeof(input_line)); - gets(input_line); - if ((rootip.s_addr = inet_addr(input_line)) == - htonl(INADDR_NONE)) { - printf("invalid IP address: %s\n", input_line); - goto get_server_ip; - } - - get_server_path: - printf("Server path? "); - bzero(rootpath, sizeof(rootpath)); - gets(rootpath); - if (rootpath[0] == '\0' || rootpath[0] == '\n') - goto get_server_path; - - if ((d = socktodesc(netdev_sock)) == NULL) - return (EMFILE); - - d->myip = myip; - - goto do_nfs_mount; - } + bzero(s, sizeof(*s)); + best_if.nif_driver = drv; + s->io_netif = &best_if; + bcopy(eaddr, s->myea, 6); /* * Get info for NFS boot: our IP address, our hostname, @@ -236,17 +137,12 @@ netmountroot(f, devname) /* Get boot info using BOOTP way. (RFC951, RFC1048) */ printf("Trying BOOTP\n"); - bootp(netdev_sock); + bootp(0); if (myip.s_addr) { printf("Using IP address: %s\n", inet_ntoa(myip)); - printf("myip: %s (%s)", hostname, inet_ntoa(myip)); - if (gateip.s_addr) - printf(", gateip: %s", inet_ntoa(gateip)); - if (netmask) - printf(", mask: %s", intoa(netmask)); - printf("\n"); + printf("myip: %s (%s)\n", hostname, inet_ntoa(myip)); } else #endif /* SUPPORT_BOOTP */ @@ -255,28 +151,43 @@ netmountroot(f, devname) /* Get boot info using RARP and Sun bootparams. */ printf("Trying BOOTPARAMS\n"); - /* Get our IP address. (rarp.c) */ - if (rarp_getipaddress(netdev_sock) == -1) + /* Get our IP address. (rarp.c) */ + if (rarp_getipaddress(0) == -1) return (errno); printf("boot: client IP address: %s\n", inet_ntoa(myip)); /* Get our hostname, server IP address. */ - if (bp_whoami(netdev_sock)) + if (bp_whoami(0)) return (errno); printf("boot: client name: %s\n", hostname); /* Get the root pathname. */ - if (bp_getfile(netdev_sock, "root", &rootip, rootpath)) + if (bp_getfile(0, "root", &rootip, rootpath)) return (errno); #endif } printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath); + f->f_devdata = s; - do_nfs_mount: /* Get the NFS file handle (mount). */ - error = nfs_mount(netdev_sock, rootip, rootpath); + r = nfs_mount(0, rootip, rootpath); + if (r) + return r; + + inited = 1; + return 0; +} - return (error); +ssize_t +netif_put(struct iodesc *desc, void *pkt, size_t len) +{ + return (*desc->io_netif->nif_driver->netif_put)(desc, pkt, len); +} + +ssize_t +netif_get(struct iodesc *desc, void *pkt, size_t len, time_t timo) +{ + return (*desc->io_netif->nif_driver->netif_get)(desc, pkt, len, timo); } diff --git a/sys/arch/vax/stand/boot/ra.c b/sys/arch/vax/stand/boot/ra.c index a0eeaa4cfb0..0bb3f748b21 100644 --- a/sys/arch/vax/stand/boot/ra.c +++ b/sys/arch/vax/stand/boot/ra.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ra.c,v 1.2 2002/03/14 03:16:02 millert Exp $ */ -/* $NetBSD: ra.c,v 1.4 1999/08/07 11:19:04 ragge Exp $ */ +/* $OpenBSD: ra.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: ra.c,v 1.11 2002/06/04 15:13:55 ragge Exp $ */ /* * Copyright (c) 1995 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -41,7 +41,7 @@ #include "lib/libsa/stand.h" #include "../include/pte.h" -#include "../include/sid.h" +#include "../include/rpb.h" #include "arch/vax/mscp/mscp.h" #include "arch/vax/mscp/mscpreg.h" @@ -51,9 +51,7 @@ #include "vaxstand.h" -static command(int); - - +static void command(int, int); /* * These routines for RA disk standalone boot is wery simple, @@ -63,70 +61,80 @@ static command(int); * But it works :) */ -struct ra_softc { - int udaddr; - int ubaddr; - int part; - int unit; - unsigned short *ra_ip; - unsigned short *ra_sa; - unsigned short *ra_sw; -}; - -volatile struct uda { - struct mscp_1ca uda_ca; /* communications area */ - struct mscp uda_rsp; /* response packets */ - struct mscp uda_cmd; /* command packets */ +static volatile struct uda { + struct mscp_1ca uda_ca; /* communications area */ + struct mscp uda_rsp; /* response packets */ + struct mscp uda_cmd; /* command packets */ } uda; -volatile struct uda *ubauda; -struct disklabel ralabel; -struct ra_softc ra_softc; -char io_buf[DEV_BSIZE]; +static struct disklabel ralabel; +static char io_buf[DEV_BSIZE]; +static int dpart, dunit, remap, is_tmscp, curblock; +static volatile u_short *ra_ip, *ra_sa, *ra_sw; +static volatile u_int *mapregs; -raopen(f, adapt, ctlr, unit, part) - struct open_file *f; - int ctlr, unit, part; +int +raopen(struct open_file *f, int adapt, int ctlr, int unit, int part) { - char *msg; - struct disklabel *lp = &ralabel; - volatile struct ra_softc *ra = &ra_softc; - volatile u_int *nisse; + static volatile struct uda *ubauda; unsigned short johan, johan2; - int i,err, udacsr; + size_t i; + int err; + char *msg; #ifdef DEV_DEBUG printf("raopen: adapter %d ctlr %d unit %d part %d\n", adapt, ctlr, unit, part); + printf("raopen: csrbase %x nexaddr %x\n", csrbase, nexaddr); #endif - bzero(lp, sizeof(struct disklabel)); - ra->unit = unit; - ra->part = part; - if (vax_cputype != VAX_8200) { - if (adapt > nuba) - return(EADAPT); - if (ctlr > nuda) - return(ECTLR); - nisse = ((u_int *)ubaaddr[adapt]) + 512; - nisse[494] = PG_V | (((u_int)&uda) >> 9); - nisse[495] = nisse[494] + 1; - udacsr = (int)uioaddr[adapt] + udaaddr[ctlr]; - ubauda = (void *)0x3dc00 + (((u_int)(&uda))&0x1ff); + bzero(&ralabel, sizeof(struct disklabel)); + bzero((void *)&uda, sizeof(struct uda)); + if (bootrpb.devtyp == BDEV_TK) + is_tmscp = 1; + dunit = unit; + dpart = part; + if (ctlr < 0) + ctlr = 0; + remap = csrbase && nexaddr; + curblock = 0; + if (csrbase) { /* On a uda-alike adapter */ + if (askname == 0) { + csrbase = bootrpb.csrphy; + dunit = bootrpb.unit; + nexaddr = bootrpb.adpphy; + } else + csrbase += (ctlr ? 000334 : 012150); + ra_ip = (short *)csrbase; + ra_sa = ra_sw = (short *)csrbase + 1; + if (nexaddr) { /* have map registers */ + mapregs = (int *)nexaddr + 512; + mapregs[494] = PG_V | (((u_int)&uda) >> 9); + mapregs[495] = mapregs[494] + 1; + (char *)ubauda = (char *)0x3dc00 + + (((u_int)(&uda))&0x1ff); + } else + ubauda = &uda; johan = (((u_int)ubauda) & 0xffff) + 8; - johan2 = 3; - ra->ra_ip = (short *)udacsr; - ra->ra_sa = ra->ra_sw = (short *)udacsr + 1; - ra->udaddr = uioaddr[adapt] + udaaddr[ctlr]; - ra->ubaddr = (int)ubaaddr[adapt]; - *ra->ra_ip = 0; /* Start init */ + johan2 = (((u_int)ubauda) >> 16) & 077; + *ra_ip = 0; /* Start init */ + bootrpb.csrphy = csrbase; } else { - paddr_t kdaddr = (paddr_t)biaddr[adapt] + BI_NODE(ctlr); + paddr_t kdaddr; volatile int *w; volatile int i = 10000; - ra->ra_ip = (short *)(kdaddr + KDB_IP); - ra->ra_sa = (short *)(kdaddr + KDB_SA); - ra->ra_sw = (short *)(kdaddr + KDB_SW); + if (askname == 0) { + nexaddr = bootrpb.csrphy; + dunit = bootrpb.unit; + } else { + nexaddr = (bootrpb.csrphy & ~(BI_NODESIZE - 1)) + KDB_IP; + bootrpb.csrphy = nexaddr; + } + + kdaddr = nexaddr & ~(BI_NODESIZE - 1); + ra_ip = (short *)(kdaddr + KDB_IP); + ra_sa = (short *)(kdaddr + KDB_SA); + ra_sw = (short *)(kdaddr + KDB_SW); johan = ((u_int)&uda.uda_ca.ca_rspdsc) & 0xffff; johan2 = (((u_int)&uda.uda_ca.ca_rspdsc) & 0xffff0000) >> 16; w = (int *)(kdaddr + BIREG_VAXBICSR); @@ -138,45 +146,70 @@ raopen(f, adapt, ctlr, unit, part) ubauda = &uda; } +#ifdef DEV_DEBUG + printf("start init\n"); +#endif /* Init of this uda */ - while ((*ra->ra_sa & MP_STEP1) == 0) + while ((*ra_sa & MP_STEP1) == 0) ; #ifdef DEV_DEBUG printf("MP_STEP1..."); #endif - *ra->ra_sw = 0x8000; - while ((*ra->ra_sa & MP_STEP2) == 0) + *ra_sw = 0x8000; + while ((*ra_sa & MP_STEP2) == 0) ; #ifdef DEV_DEBUG printf("MP_STEP2..."); #endif - *ra->ra_sw = johan; - while ((*ra->ra_sa & MP_STEP3) == 0) + *ra_sw = johan; + while ((*ra_sa & MP_STEP3) == 0) ; #ifdef DEV_DEBUG printf("MP_STEP3..."); #endif - *ra->ra_sw = johan2; - while ((*ra->ra_sa & MP_STEP4) == 0) + *ra_sw = johan2; + while ((*ra_sa & MP_STEP4) == 0) ; #ifdef DEV_DEBUG printf("MP_STEP4\n"); #endif - *ra->ra_sw = 0x0001; + *ra_sw = 0x0001; uda.uda_ca.ca_rspdsc = (int)&ubauda->uda_rsp.mscp_cmdref; uda.uda_ca.ca_cmddsc = (int)&ubauda->uda_cmd.mscp_cmdref; + if (is_tmscp) { + uda.uda_cmd.mscp_un.un_seq.seq_addr = + (long *)&uda.uda_ca.ca_cmddsc; + uda.uda_rsp.mscp_un.un_seq.seq_addr = + (long *)&uda.uda_ca.ca_rspdsc; + uda.uda_cmd.mscp_vcid = 1; + uda.uda_cmd.mscp_un.un_sccc.sccc_ctlrflags = 0; + } - command(M_OP_SETCTLRC); - uda.uda_cmd.mscp_unit = ra->unit; - command(M_OP_ONLINE); + command(M_OP_SETCTLRC, 0); + uda.uda_cmd.mscp_unit = dunit; + command(M_OP_ONLINE, 0); + if (is_tmscp) { + if (part) { +#ifdef DEV_DEBUG + printf("Repos of tape..."); +#endif + uda.uda_cmd.mscp_un.un_seq.seq_buffer = part; + command(M_OP_POS, 0); + uda.uda_cmd.mscp_un.un_seq.seq_buffer = 0; +#ifdef DEV_DEBUG + printf("Done!\n"); +#endif + } + return 0; + } #ifdef DEV_DEBUG printf("reading disklabel\n"); #endif - err = rastrategy(ra,F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i); + err = rastrategy(0, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i); if(err){ printf("reading disklabel: %s\n",strerror(err)); return 0; @@ -185,19 +218,21 @@ raopen(f, adapt, ctlr, unit, part) #ifdef DEV_DEBUG printf("getting disklabel\n"); #endif - msg = getdisklabel(io_buf+LABELOFFSET, lp); + msg = getdisklabel(io_buf+LABELOFFSET, &ralabel); if (msg) printf("getdisklabel: %s\n", msg); - f->f_devdata = (void *)ra; return(0); } -static -command(cmd) +static void +command(int cmd, int arg) { - volatile int hej; + volatile short hej; + int to; + +igen: uda.uda_cmd.mscp_opcode = cmd; + uda.uda_cmd.mscp_modifier = arg; - uda.uda_cmd.mscp_opcode = cmd; uda.uda_cmd.mscp_msglen = MSCP_MSGLEN; uda.uda_rsp.mscp_msglen = MSCP_MSGLEN; uda.uda_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT; @@ -205,51 +240,87 @@ command(cmd) #ifdef DEV_DEBUG printf("sending cmd %x...", cmd); #endif - hej = *ra_softc.ra_ip; - while(uda.uda_ca.ca_rspdsc<0) - ; + hej = *ra_ip; + to = 10000000; + while (uda.uda_ca.ca_rspdsc < 0) { +// if (uda.uda_ca.ca_cmdint) +// uda.uda_ca.ca_cmdint = 0; + if (--to < 0) { +#ifdef DEV_DEBUG + printf("timing out, retry\n"); +#endif + goto igen; + } + } #ifdef DEV_DEBUG printf("sent.\n"); #endif } -rastrategy(ra, func, dblk, size, buf, rsize) - struct ra_softc *ra; - int func; - daddr_t dblk; - char *buf; - u_int size, *rsize; +int +rastrategy(void *f, int func, daddr_t dblk, + size_t size, void *buf, size_t *rsize) { - volatile u_int *ptmapp; - struct disklabel *lp; - u_int i, j, pfnum, mapnr, nsize; - volatile int hej; - - if (vax_cputype != VAX_8200) { - ptmapp = ((u_int *)ra->ubaddr) + 512; + u_int pfnum, mapnr, nsize; +#ifdef DEV_DEBUG + printf("rastrategy: buf %p remap %d is_tmscp %d\n", + buf, remap, is_tmscp); +#endif + if (remap) { pfnum = (u_int)buf >> VAX_PGSHIFT; for(mapnr = 0, nsize = size; (nsize + VAX_NBPG) > 0; nsize -= VAX_NBPG) - ptmapp[mapnr++] = PG_V | pfnum++; + mapregs[mapnr++] = PG_V | pfnum++; uda.uda_cmd.mscp_seq.seq_buffer = ((u_int)buf) & 0x1ff; } else uda.uda_cmd.mscp_seq.seq_buffer = ((u_int)buf); - lp = &ralabel; - uda.uda_cmd.mscp_seq.seq_lbn = - dblk + lp->d_partitions[ra->part].p_offset; - uda.uda_cmd.mscp_seq.seq_bytecount = size; - uda.uda_cmd.mscp_unit = ra->unit; + if (is_tmscp) { + int i; + + /* + * First position tape. Remember where we are. + */ + if (dblk < curblock) { + uda.uda_cmd.mscp_seq.seq_bytecount = curblock - dblk; + command(M_OP_POS, 12); /* 12 == step block backward */ + } else { + uda.uda_cmd.mscp_seq.seq_bytecount = dblk - curblock; + command(M_OP_POS, 4); /* 4 == step block forward */ + } + curblock = size/512 + dblk; + + /* + * Read in the number of blocks we need. + * Why doesn't read of multiple blocks work????? + */ + for (i = 0 ; i < size/512 ; i++) { + uda.uda_cmd.mscp_seq.seq_lbn = 1; + uda.uda_cmd.mscp_seq.seq_bytecount = 512; + uda.uda_cmd.mscp_seq.seq_buffer = + (((u_int)buf) & 0x1ff) + i * 512; + uda.uda_cmd.mscp_unit = dunit; + command(M_OP_READ, 0); + } + } else { + + uda.uda_cmd.mscp_seq.seq_lbn = + dblk + ralabel.d_partitions[dpart].p_offset; + uda.uda_cmd.mscp_seq.seq_bytecount = size; + uda.uda_cmd.mscp_unit = dunit; #ifdef DEV_DEBUG - printf("rastrategy: blk 0x%lx count %lx unit %lx\n", - uda.uda_cmd.mscp_seq.seq_lbn, size, ra->unit); + printf("rastrategy: blk 0x%lx count %lx unit %x\n", + uda.uda_cmd.mscp_seq.seq_lbn, size, dunit); +#endif +#ifdef notdef + if (func == F_WRITE) + command(M_OP_WRITE, 0); + else #endif - if (func == F_WRITE) - command(M_OP_WRITE); - else - command(M_OP_READ); + command(M_OP_READ, 0); + } *rsize = size; return 0; diff --git a/sys/arch/vax/stand/boot/rom.c b/sys/arch/vax/stand/boot/rom.c index 2d3f0c3a6b5..f6fb3a7b271 100644 --- a/sys/arch/vax/stand/boot/rom.c +++ b/sys/arch/vax/stand/boot/rom.c @@ -1,5 +1,5 @@ -/* $OpenBSD: rom.c,v 1.3 2002/03/14 03:16:02 millert Exp $ */ -/* $NetBSD: rom.c,v 1.1 1996/08/02 11:22:21 ragge Exp $ */ +/* $OpenBSD: rom.c,v 1.4 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: rom.c,v 1.3 2000/07/19 00:58:25 matt Exp $ */ /* * Copyright (c) 1996 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -50,42 +50,32 @@ #include "data.h" #include "vaxstand.h" -extern unsigned *bootregs; -extern struct rpb *rpb; +static struct disklabel romlabel; +static char io_buf[DEV_BSIZE]; +static struct bqo *bqo; +static int dpart, dunit; -struct rom_softc { - int part; - int unit; -}; - -int romstrategy(), romopen(); -struct disklabel romlabel; -struct rom_softc rom_softc; -char io_buf[DEV_BSIZE]; - -romopen(f, adapt, ctlr, unit, part) - struct open_file *f; - int ctlr, unit, part; +int +romopen(struct open_file *f, int adapt, int ctlr, int unit, int part) { char *msg; struct disklabel *lp = &romlabel; - volatile struct rom_softc *rsc = &rom_softc; - int i,err; + size_t i; + int err; - bootregs[11] = XXRPB; - bqo = (void *)rpb->iovec; + bqo = (void *)bootrpb.iovec; - if (rpb->unit > 0 && (rpb->unit % 100) == 0) { - printf ("changing rpb->unit from %d ", rpb->unit); - rpb->unit /= 100; - printf ("to %d\n", rpb->unit); + if (bootrpb.unit > 0 && (bootrpb.unit % 100) == 0) { + printf ("changing bootrpb.unit from %d ", bootrpb.unit); + bootrpb.unit /= 100; + printf ("to %d\n", bootrpb.unit); } bzero(lp, sizeof(struct disklabel)); - rsc->unit = unit; - rsc->part = part; + dunit = unit; + dpart = part; - err = romstrategy(rsc, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i); + err = romstrategy(0, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i); if (err) { printf("reading disklabel: %s\n",strerror(err)); return 0; @@ -93,29 +83,33 @@ romopen(f, adapt, ctlr, unit, part) msg = getdisklabel(io_buf+LABELOFFSET, lp); if (msg) printf("getdisklabel: %s\n",msg); - f->f_devdata = (void *)rsc; return(0); } -romstrategy (rsc, func, dblk, size, buf, rsize) - struct rom_softc *rsc; - int func; +int romwrite_uvax(int, int, void *, struct rpb *); +int romread_uvax(int, int, void *, struct rpb *); + +int +romstrategy (f, func, dblk, size, buf, rsize) + void *f; + int func; daddr_t dblk; - char *buf; - int size, *rsize; + size_t size; + void *buf; + size_t *rsize; { struct disklabel *lp; int block; lp = &romlabel; - block = dblk + lp->d_partitions[rsc->part].p_offset; - if (rsc->unit >= 0 && rsc->unit < 10) - rpb->unit = rsc->unit; + block = dblk + lp->d_partitions[dpart].p_offset; + if (dunit >= 0 && dunit < 10) + bootrpb.unit = dunit; if (func == F_WRITE) - romwrite_uvax(block, size, buf, bootregs); + romwrite_uvax(block, size, buf, &bootrpb); else - romread_uvax(block, size, buf, bootregs); + romread_uvax(block, size, buf, &bootrpb); *rsize = size; return 0; diff --git a/sys/arch/vax/stand/boot/tmscp.c b/sys/arch/vax/stand/boot/tmscp.c index ec0f185a01c..ff466c8c15b 100644 --- a/sys/arch/vax/stand/boot/tmscp.c +++ b/sys/arch/vax/stand/boot/tmscp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tmscp.c,v 1.2 2002/03/14 03:16:02 millert Exp $ */ +/* $OpenBSD: tmscp.c,v 1.3 2002/06/11 09:36:23 hugh Exp $ */ /* $NetBSD: tmscp.c,v 1.3 1999/06/30 18:19:26 ragge Exp $ */ /* * Copyright (c) 1995 Ludd, University of Lule}, Sweden. @@ -95,11 +95,11 @@ tmscpopen(f, adapt, ctlr, unit, part) ra->udaddr=uioaddr[adapt]+tmsaddr; ra->ubaddr=(int)ubaaddr[adapt]; ra->unit=unit; - udacsr=(void *)ra->udaddr; + udacsr=(void*)ra->udaddr; nisse=((u_int *)ubaaddr[adapt]) + 512; nisse[494]=PG_V|(((u_int)&uda)>>9); nisse[495]=nisse[494]+1; - ubauda=(void *)0x3dc00+(((u_int)(&uda))&0x1ff); + ubauda=(void*)0x3dc00+(((u_int)(&uda))&0x1ff); /* * Init of this tmscp ctlr. @@ -165,7 +165,7 @@ tmscpstrategy(ra, func, dblk, size, buf, rsize) u_int size, *rsize; { u_int i,j,pfnum, mapnr, nsize, bn, cn, sn, tn; - volatile struct udadevice *udadev=(void *)ra->udaddr; + volatile struct udadevice *udadev=(void*)ra->udaddr; volatile u_int *ptmapp = (u_int *)ra->ubaddr + 512; volatile int hej; diff --git a/sys/arch/vax/stand/boot/vaxstand.h b/sys/arch/vax/stand/boot/vaxstand.h new file mode 100644 index 00000000000..8d48a376189 --- /dev/null +++ b/sys/arch/vax/stand/boot/vaxstand.h @@ -0,0 +1,85 @@ +/* $OpenBSD: vaxstand.h,v 1.1 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: vaxstand.h,v 1.5 2000/06/15 19:53:23 ragge Exp $ */ +/* + * Copyright (c) 1994 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}. + * 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. + */ + +/* Variables used in autoconf */ +extern int askname; +extern struct rpb bootrpb; +extern int csrbase, nexaddr; + +/* devsw type definitions, used in bootxx and conf */ +#define SADEV(name,strategy,open,close,ioctl) \ + { (char *)name, \ + (int(*)(void *, int ,daddr_t , size_t, void *, size_t *))strategy, \ + (int(*)(struct open_file *, ...))open, \ + (int(*)(struct open_file *))close, \ + (int(*)(struct open_file *,u_long, void *))ioctl} + +#define SDELAY(count) {volatile int i; for (i = count; i; i--);} +/* + * Easy-to-use definitions + */ +#ifndef min +#define min(x,y) (x < y ? x : y) +#endif /* min */ + +struct netif_driver; + +char *index(char *, int); +int net_devinit(struct open_file *f, struct netif_driver *drv, u_char *eaddr); + +/* device calls */ +int raopen(struct open_file *, int, int, int, int), + rastrategy(void *, int, daddr_t, size_t, void *, size_t *); +int hpopen(struct open_file *, int, int, int, int), + hpstrategy(void *, int, daddr_t, size_t, void *, size_t *); +int ctuopen(struct open_file *, int, int, int, int), + ctustrategy(void *, int, daddr_t, size_t, void *, size_t *); +int tmscpopen(struct open_file *, int, int, int, int), + tmscpstrategy(void *, int, daddr_t, size_t, void *, size_t *); +int romopen(struct open_file *, int, int, int, int), + romstrategy(void *, int, daddr_t, size_t, void *, size_t *); +int mfmopen(struct open_file *, int, int, int, int), + mfmstrategy(void *, int, daddr_t, size_t, void *, size_t *); +int sdopen(struct open_file *), + sdstrategy(void *, int, daddr_t, size_t, void *, size_t *); +int leopen(struct open_file *, int, int, int, int), + leclose(struct open_file *); +int qeopen(struct open_file *, int, int, int, int), + qeclose(struct open_file *); +int zeopen(struct open_file *, int, int, int, int), + zeclose(struct open_file *); +int deopen(struct open_file *, int, int, int, int), + declose(struct open_file *); +int niopen(struct open_file *, int, int, int, int), + niclose(struct open_file *); +int netopen(struct open_file *), netclose(struct open_file *); + diff --git a/sys/arch/vax/stand/boot/version b/sys/arch/vax/stand/boot/version new file mode 100644 index 00000000000..4e5f4b0b4c1 --- /dev/null +++ b/sys/arch/vax/stand/boot/version @@ -0,0 +1,31 @@ +$OpenBSD: version,v 1.1 2002/06/11 09:36:23 hugh Exp $ +$NetBSD: version,v 1.4 2001/11/09 19:53:15 scw Exp $ + +NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this +file is important - make sure the entries are appended on end, last item +is taken as the current. + +1.0: Initial import. +1.1: Bunch of small fixes to make boot work on most VAXen. +1.2: Use common routines to identify cpu type. + Set up a SCB to be able to handle clock interrupts in the boot program. + Now timer countdown should work on all types of vaxen. +1.3: Unify the ra and tmscp driver. + Standalone driver for the Digital Equipment Unibus Network Adapter + (DEUNA). This allows 11/750 owners to install from a single TU58 + cassette. + Adopt to the RPB changes. Complete change of how network devices are + handled. No more hacks to find bus addresses. +1.5: Standalone device driver for DEBNx (ni) ethernet controllers. +1.6: Add support for VAX 6000 + VAX 8000. Tweak console routines. + Create a fake RPB if either netbooted (on machine without RPB) or + loaded from console storage (without VMB intervention). +1.7: Add support for loading a 2nd stage boot in either a.out or ELF. + Add support for loading a 2nd stage boot directly to it's desired + address if possible. + Cleanup use of u_int/size_t. +1.8: Switch to loadfile instead of exec. Now we can load a.out or ELF + kernels. +1.9: Support verbose/quiet boot. +1.10: loadfile() update: ELF symbols no longer need backward seeks. +1.11: loadfile() update to avoid backwards seeks for ELF Program Headers. diff --git a/sys/arch/vax/stand/common/romread.s b/sys/arch/vax/stand/common/romread.S index 749a70bae2d..4de1e0a90f8 100644 --- a/sys/arch/vax/stand/common/romread.s +++ b/sys/arch/vax/stand/common/romread.S @@ -1,5 +1,5 @@ -/* $OpenBSD: romread.s,v 1.1 2000/04/27 02:26:26 bjc Exp $ */ -/* $NetBSD: romread.s,v 1.4 1996/08/02 11:22:24 ragge Exp $ */ +/* $OpenBSD: romread.S,v 1.1 2002/06/11 09:36:23 hugh Exp $ */ +/* $NetBSD: romread.S,v 1.1 2002/02/24 01:04:25 matt Exp $ */ /* * Copyright (c) 1995 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -59,36 +59,34 @@ ENTRY(read750, 0xFFE) ret /* - * romread_uvax (int lbn, int size, void *buf, int *regs) + * romread_uvax (int lbn, int size, void *buf, struct rpb *rpb) */ ENTRY(romread_uvax, 0xFFE) - movl 16(ap), r11 # array of bootregs - movl 44(r11), r11 # restore boot-contents of r11 (rpb) - movl 52(r11), r7 # load iovec/bqo into r7 - addl3 (r7), r7, r6 # load qio into r6 - pushl r11 # base of rpb - pushl $0 # virtual-flag - pushl $33 # read-logical-block - pushl 4(ap) # lbn to start reading - pushl 8(ap) # number of bytes to read - pushl 12(ap) # buffer-address + movl 16(ap),r11 # restore boot-contents of %r11 (rpb) + movl 52(r11), r7 # load iovec/bqo into %r7 + addl3 (r7), r7, r6 # load qio into %r6 + pushl r11 # base of rpb + pushl $0 # virtual-flag + pushl $33 # read-logical-block + pushl 4(ap) # lbn to start reading + pushl 8(ap) # number of bytes to read + pushl 12(ap) # buffer-address calls $6, (r6) # call the qio-routine - ret # r0 holds the result + ret # %r0 holds the result /* - * romwrite_uvax (int lbn, int size, void *buf, int *regs) + * romwrite_uvax (int lbn, int size, void *buf, struct rpb *rpb) */ ENTRY(romwrite_uvax, 0xFFE) - movl 16(ap), r11 # array of bootregs - movl 44(r11), r11 # restore boot-contents of r11 (rpb) - movl 52(r11), r7 # load iovec/bqo into r7 - addl3 (r7), r7, r6 # load qio into r6 - pushl r11 # base of rpb - pushl $0 # virtual-flag - pushl $32 # write-logical-block - pushl 4(ap) # lbn to start reading - pushl 8(ap) # number of bytes to read - pushl 12(ap) # buffer-address + movl 16(ap), r11 # restore boot-contents of %r11 (rpb) + movl 52(r11), r7 # load iovec/bqo into %r7 + addl3 (r7), r7, r6 # load qio into %r6 + pushl r11 # base of rpb + pushl $0 # virtual-flag + pushl $32 # write-logical-block + pushl 4(ap) # lbn to start reading + pushl 8(ap) # number of bytes to read + pushl 12(ap) # buffer-address calls $6, (r6) # call the qio-routine - ret # r0 holds the result + ret # %r0 holds the result diff --git a/sys/arch/vax/stand/common/srt0.s b/sys/arch/vax/stand/common/srt0.S index fb5dabecf6d..8ff71c5a35c 100644 --- a/sys/arch/vax/stand/common/srt0.s +++ b/sys/arch/vax/stand/common/srt0.S @@ -1,5 +1,5 @@ -/* $OpenBSD: srt0.s,v 1.2 2000/10/04 04:09:01 bjc Exp $ */ -/* $NetBSD: srt0.s,v 1.2 1999/05/23 21:58:19 ragge Exp $ */ +/* $OpenBSD: srt0.S,v 1.1 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: srt0.S,v 1.2 2002/03/31 00:11:14 matt Exp $ */ /* * Copyright (c) 1994 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -33,6 +33,7 @@ /* All bugs are subject to removal without further notice */ #include "../include/asm.h" + /* * Auto-moving startup code for standalone programs. Can be loaded * (almost) anywhere in memory but moves itself to the position @@ -41,45 +42,44 @@ * position set in a.out header. */ -nisse: .set nisse,0 # pass -e nisse to ld gives OK start addr - .globl nisse - -_start: .globl _start - nop;nop; # If we get called by calls, or something - - movl r8, _memsz # If we come from disk, save memsize - ashl $9,76(r11),_memsz # got memsize from rpb - movzwl 48(r11), r10 # Get howto + .globl nisse # pass -e nisse to ld gives OK start addr + .set nisse,0 -2: movl $_start, sp # Probably safe place for stack - pushr $0x1fff +ALTENTRY(start) + nop;nop; + movl $_C_LABEL(start), sp # Probably safe place for stack + pushr $0x1fff # save for later usage - subl3 $_start, $_edata, r0 - movab _start, r1 - movl $_start, r3 - movc3 r0,(r1),(r3) # Kopiera text + data - subl3 $_edata, $_end, r2 - movc5 $0,(r3),$0,r2,(r3) # Nolla bss också. + subl3 $_C_LABEL(start), $_C_LABEL(edata), r0 + movab _C_LABEL(start), r1 # get where we are + movl $_C_LABEL(start), r3 # get where we want to be + cmpl r1,r3 # are we where we want to be? + beql relocated # already relocated, skip copy + movc3 r0,(r1),(r3) # copy + subl3 $_C_LABEL(edata), $_C_LABEL(end), r2 + movc5 $0,(r3),$0,r2,(r3) # Zero bss - jsb 1f -1: movl $relocated, (sp) # return-address on top of stack - rsb # can be replaced with new address -relocated: # now relocation is done !!! - movl r10,_howto # howto also... - movl sp, _bootregs - calls $0, _Xmain # Were here! + movpsl -(sp) + pushl $relocated + rei +relocated: # now relocation is done !!! + movl sp,_C_LABEL(bootregs) # *bootregs + calls $0, _C_LABEL(Xmain) # Were here! halt # no return ENTRY(machdep_start, 0) + calls $0,_C_LABEL(niclose) # Evil hack to shutdown DEBNA. mtpr $0x1f,$0x12 # Block all interrupts mtpr $0,$0x18 # stop real time interrupt clock movl 4(ap), r6 - movl _howto, r11 - movl _opendev, r10 - movl 20(ap), r9 - movl _memsz, r8 - calls $0,(r6) - ret + movl 20(ap), r9 # end of symbol table + pushl 8(ap) # number of symbols + pushl 16(ap) # start of symbols + movab _C_LABEL(bootrpb),r10 # get RPB address + pushl r10 # argument for new boot + ashl $9,76(r10),r8 # memory size (COMPAT) + movl $3,r11 # ask boot (COMPAT) + clrl r10 # no boot dev (COMPAT) - .globl _memsz -_memsz: .long 0x0 + calls $3,(r6) + halt diff --git a/sys/arch/vax/boot/common/str.s b/sys/arch/vax/stand/common/str.S index e45ab28ea67..e88cb9ca9ce 100644 --- a/sys/arch/vax/boot/common/str.s +++ b/sys/arch/vax/stand/common/str.S @@ -1,5 +1,5 @@ -/* $OpenBSD: str.s,v 1.2 2000/05/01 00:12:02 bjc Exp $ */ -/* $NetBSD: str.s,v 1.1 1999/03/06 16:36:06 ragge Exp $ */ +/* $OpenBSD: str.S,v 1.1 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: str.S,v 1.1 2002/02/24 01:04:25 matt Exp $ */ /* * Copyright (c) 1996 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -41,7 +41,7 @@ /* * atoi() used in devopen. */ -ENTRY(atoi, 0); +ENTRY(atoi, 0) movl 4(ap),r1 clrl r0 @@ -60,7 +60,7 @@ ENTRY(atoi, 0); * index() small and easy. * doesnt work if we search for null. */ -ENTRY(index, 0); +ENTRY(index, 0) movq 4(ap),r0 1: cmpb (r0), r1 beql 2f @@ -72,7 +72,7 @@ ENTRY(index, 0); /* * cmpc3 is emulated on MVII. */ -ENTRY(bcmp, 0); +ENTRY(bcmp, 0) movl 4(ap), r2 movl 8(ap), r1 movl 12(ap), r0 @@ -85,15 +85,15 @@ ENTRY(bcmp, 0); /* * Is movc3/movc5 emulated on any CPU? I dont think so; use them here. */ -ENTRY(bzero,0); +ENTRY(bzero,0) movc5 $0,*4(ap),$0,8(ap),*4(ap) ret -ENTRY(bcopy,0); +ENTRY(bcopy,0) movc3 12(ap), *4(ap), *8(ap) ret -ENTRY(strlen, 0); +ENTRY(strlen, 0) movl 4(ap), r0 1: tstb (r0)+ bneq 1b @@ -139,7 +139,7 @@ ENTRY(strncpy, 0) ENTRY(strcat, 0) pushl 4(ap) - calls $1,_strlen + calls $1,_C_LABEL(strlen) addl2 4(ap),r0 movl 8(ap),r1 1: movb (r1)+,(r0)+ @@ -147,18 +147,19 @@ ENTRY(strcat, 0) ret ENTRY(setjmp, 0) - movl 4(ap), r0 - movl 8(fp), (r0) - movl 12(fp), 4(r0) - movl 16(fp), 8(r0) - addl3 fp,$28,12(r0) - clrl r0 - ret + movl 4(ap), r0 + movl 8(fp), (r0) + movl 12(fp), 4(r0) + movl 16(fp), 8(r0) + addl3 fp,$28,12(r0) + clrl r0 + ret ENTRY(longjmp, 0) - movl 4(ap), r1 - movl 8(ap), r0 - movl (r1), ap - movl 4(r1), fp - movl 12(r1), sp - jmp *8(r1) + movl 4(ap), r1 + movl 8(ap), r0 + movl (r1), ap + movl 4(r1), fp + movl 12(r1), sp + jmp *8(r1) + diff --git a/sys/arch/vax/stand/xxboot/Makefile b/sys/arch/vax/stand/xxboot/Makefile index 9c69452e26c..d3aac85b173 100644 --- a/sys/arch/vax/stand/xxboot/Makefile +++ b/sys/arch/vax/stand/xxboot/Makefile @@ -1,37 +1,57 @@ -# $OpenBSD: Makefile,v 1.3 2002/03/10 06:52:16 hugh Exp $ -# $NetBSD: Makefile,v 1.2 1999/10/23 14:40:39 ragge Exp $ +# $OpenBSD: Makefile,v 1.4 2002/06/11 09:36:24 hugh Exp $ +# $NetBSD: Makefile,v 1.12 2002/02/24 01:04:25 matt Exp $ -S=${.CURDIR}/../../../../ +S= ${.CURDIR}/../../../../ PROG= xxboot LINKS= ${BINDIR}/xxboot ${BINDIR}/raboot LINKS+= ${BINDIR}/xxboot ${BINDIR}/hdboot LINKS+= ${BINDIR}/xxboot ${BINDIR}/sdboot LINKS+= ${BINDIR}/xxboot ${BINDIR}/hpboot +WARNS?= 1 -SRCS= start.s bootxx.c romread.s urem.s udiv.s str.s +SRCS= start.S bootxx.c romread.S str.S urem.s udiv.s STRIPFLAG= CPPFLAGS+=-D_STANDALONE -DLIBSA_NO_FD_CHECKING -DLIBSA_NO_RAW_ACCESS \ -DLIBSA_NO_TWIDDLE -DLIBSA_SINGLE_DEVICE=rom \ - -DLIBSA_SINGLE_FILESYSTEM=ufs + -DLIBSA_NO_COMPAT_UFS \ + -DLIBSA_NO_FS_SYMLINK -DLIBSA_NO_FS_CLOSE \ + -DLIBSA_NO_FS_WRITE -DLIBSA_NO_FS_SEEK \ + -DNEED_UFS BINDIR= /usr/mdec -NOMAN= 1 +NOMAN= # defined + +CFLAGS= -Os SAREL= SA_AS= library .include "${S}/lib/libsa/Makefile.inc" LIBSA= ${SALIB} -${PROG}: ${OBJS} ${LIBSA} - ld -N -Ttext 100000 -o a.out ${OBJS} ${LIBSA} - strip a.out - size a.out - dd if=a.out of=${PROG} bs=32 skip=1 -# rm -f a.out +#KERN_AS=library +#.include "${S}/lib/libkern/Makefile.inc" +#LIBKERN=${KERNLIB} + +.if ${MACHINE} == "vax" +.PHONY: machine-links +beforedepend: machine-links +machine-links: + @[ -h machine ] || ln -s ${S}/arch/${MACHINE}/include machine + @[ -h ${MACHINE_ARCH} ] || ln -s ${S}/arch/${MACHINE_ARCH}/include ${MACHINE_ARCH} +.NOPATH: machine ${MACHINE_ARCH} +CLEANFILES+= machine ${MACHINE_ARCH} +.endif + +${PROG}: ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN} +${PROG}: ${OBJS} ${LIBSA} ${LIBKERN} + ${LD} -N -Ttext 100000 -o ${PROG}.out ${OBJS} ${LIBSA} ${LIBKERN} + /usr/bin/strip ${PROG}.out + /usr/bin/size ${PROG}.out + /bin/dd if=${PROG}.out of=${PROG} bs=32 skip=1 clean:: rm -f a.out [Ee]rrs mklog core *.core ${PROG} ${OBJS} ${LOBJS} \ - ${CLEANFILES} + ${CLEANFILES} .include <bsd.prog.mk> diff --git a/sys/arch/vax/stand/xxboot/bootxx.c b/sys/arch/vax/stand/xxboot/bootxx.c index 30007379ea1..7c57b7267fa 100644 --- a/sys/arch/vax/stand/xxboot/bootxx.c +++ b/sys/arch/vax/stand/xxboot/bootxx.c @@ -1,5 +1,6 @@ -/* $OpenBSD: bootxx.c,v 1.4 2002/03/14 03:16:02 millert Exp $ */ -/* $NetBSD: bootxx.c,v 1.2 1999/10/23 14:40:38 ragge Exp $ */ +/* $OpenBSD: bootxx.c,v 1.5 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: bootxx.c,v 1.16 2002/03/29 05:45:08 matt Exp $ */ + /*- * Copyright (c) 1982, 1986 The Regents of the University of California. * All rights reserved. @@ -38,167 +39,149 @@ #include "sys/param.h" #include "sys/reboot.h" #include "sys/disklabel.h" +#include "sys/exec.h" +#include "sys/exec_elf.h" #include "lib/libsa/stand.h" #include "lib/libsa/ufs.h" +#include "lib/libsa/cd9660.h" -#include "../include/pte.h" -#include "../include/sid.h" -#include "../include/mtpr.h" -#include "../include/reg.h" -#include "../include/rpb.h" +#include "machine/pte.h" +#include "machine/sid.h" +#include "machine/mtpr.h" +#include "machine/reg.h" +#include "machine/rpb.h" +#include "../vax/gencons.h" #include "../mba/mbareg.h" #include "../mba/hpreg.h" #define NRSP 1 /* Kludge */ #define NCMD 1 /* Kludge */ +#define LIBSA_TOO_OLD -#include "../mscp/mscp.h" -#include "../mscp/mscpreg.h" - -#include "vaxstand.h" +#include "arch/vax/mscp/mscp.h" +#include "arch/vax/mscp/mscpreg.h" -struct rom_softc { - int part; - int unit; -} rom_softc; +#include "../boot/data.h" -int romstrategy(void *, int, daddr_t, size_t, void *, size_t *); -int romopen(struct open_file *, int, int, int, int); - -struct fs_ops file_system[] = { - { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat } -}; -int nfsys = (sizeof(file_system) / sizeof(struct fs_ops)); - -struct devsw devsw[] = { - SADEV("rom", romstrategy, romopen, nullsys, noioctl), -}; -int ndevs = (sizeof(devsw)/sizeof(devsw[0])); - -int command(int cmd, int arg); - -/* - * Boot program... argume passed in r10 and r11 determine whether boot - * stops to ask for system name and which device boot comes from. - */ +#define RF_PROTECTED_SECTORS 64 /* XXX refer to <.../rf_optnames.h> */ -volatile dev_t devtype, bootdev; -unsigned opendev, boothowto, bootset, memsz; +void Xmain(void); +void hoppabort(int); +void romread_uvax(int lbn, int size, void *buf, struct rpb *rpb); +void hpread(int block); +int read750(int block, int *regs); +int unit_init(int, struct rpb *, int); struct open_file file; unsigned *bootregs; struct rpb *rpb; +struct bqo *bqo; int vax_cputype; +int vax_load_failure; +struct udadevice {u_short udaip;u_short udasa;}; +volatile struct udadevice *csr; +static int moved; + +extern int from; +#define FROM750 1 +#define FROMMV 2 +#define FROMVMB 4 /* * The boot block are used by 11/750, 8200, MicroVAX II/III, VS2000, * VS3100/??, VS4000 and VAX6000/???, and only when booting from disk. */ +void Xmain() { + union { + struct exec aout; + Elf32_Ehdr elf; + } hdr; int io; - char *scbb; - char *new, *bqo; - char *hej = "/boot"; + u_long entry; vax_cputype = (mfpr(PR_SID) >> 24) & 0xFF; - + moved = 0; /* */ - switch (vax_cputype) { - case VAX_TYP_UV2: - case VAX_TYP_CVAX: - case VAX_TYP_RIGEL: - case VAX_TYP_NVAX: - case VAX_TYP_MARIAH: - case VAX_TYP_SOC: + rpb = (void *)0xf0000; /* Safe address right now */ + bqo = (void *)0xf1000; + if (from == FROMMV) { /* * now relocate rpb/bqo (which are used by ROM-routines) */ - rpb = (void *)XXRPB; - bcopy ((void *)bootregs[11], rpb, 512); - rpb->rpb_base = rpb; - bqo = (void *)(512+(int)rpb); - bcopy ((void *)rpb->iovec, bqo, rpb->iovecsz); - rpb->iovec = (int)bqo; - bootregs[11] = (int)rpb; - bootdev = rpb->devtyp; - memsz = rpb->pfncnt << 9; - break; - case VAX_8200: - case VAX_750: - bootdev = bootregs[10]; - memsz = 0; - break; - default: - asm("halt"); - } - - bootset = getbootdev(); - io = open(hej, 0); - - read(io, (void *)0x10000, 0x10000); - bcopy((void *) 0x10000, 0, 0xffff); - hoppabort(32, XXRPB, bootset); - asm("halt"); -} - -getbootdev() -{ - int i, adaptor, controller, unit, partition, retval; - - adaptor = controller = unit = partition = 0; - - switch (vax_cputype) { - case VAX_TYP_UV2: - case VAX_TYP_CVAX: - case VAX_TYP_MARIAH: - case VAX_TYP_RIGEL: - if (rpb->devtyp == BDEV_SD || rpb->devtyp == BDEV_SDN) { - unit = rpb->unit / 100; - controller = (rpb->csrphy & 0x100 ? 1 : 0); - } else { - controller = ((rpb->csrphy & 017777) == 0xDC)?1:0; - unit = rpb->unit; /* DUC, DUD? */ + bcopy ((void *)bootregs[11], rpb, sizeof(struct rpb)); + bcopy ((void*)rpb->iovec, bqo, rpb->iovecsz); +#if 0 + if (rpb->devtyp == BDEV_SDN) + rpb->devtyp = BDEV_SD; /* XXX until driver fixed */ +#endif + } else { + bzero(rpb, sizeof(struct rpb)); + rpb->devtyp = bootregs[0]; + rpb->unit = bootregs[3]; + rpb->rpb_bootr5 = bootregs[5]; + rpb->csrphy = bootregs[2]; + rpb->adpphy = bootregs[1]; /* BI node on 8200 */ + if (rpb->devtyp != BDEV_HP && vax_cputype == VAX_TYP_750) + rpb->adpphy = + (bootregs[1] == 0xffe000 ? 0xf30000 : 0xf32000); + } + rpb->rpb_base = rpb; + rpb->iovec = (int)bqo; + + io = open("/boot.vax", 0); + if (io < 0) + io = open("/boot", 0); + if (io < 0) + asm("movl $0xbeef1, r0; halt"); + + read(io, (void *)&hdr.aout, sizeof(hdr.aout)); + if (N_GETMAGIC(hdr.aout) == OMAGIC && N_GETMID(hdr.aout) == MID_VAX) { + vax_load_failure++; + entry = hdr.aout.a_entry; + if (entry < sizeof(hdr.aout)) + entry = sizeof(hdr.aout); + read(io, (void *) entry, hdr.aout.a_text + hdr.aout.a_data); + memset((void *) (entry + hdr.aout.a_text + hdr.aout.a_data), + 0, hdr.aout.a_bss); + } else if (memcmp(hdr.elf.e_ident, ELFMAG, SELFMAG) == 0) { + Elf32_Phdr ph; + size_t off = sizeof(hdr.elf); + vax_load_failure += 2; + read(io, (caddr_t)(&hdr.elf) + sizeof(hdr.aout), + sizeof(hdr.elf) - sizeof(hdr.aout)); + if (hdr.elf.e_machine != EM_VAX || hdr.elf.e_type != ET_EXEC + || hdr.elf.e_phnum != 1) + goto die; + vax_load_failure++; + entry = hdr.elf.e_entry; + if (hdr.elf.e_phoff != sizeof(hdr.elf)) + goto die; + vax_load_failure++; + read(io, &ph, sizeof(ph)); + off += sizeof(ph); + if (ph.p_type != PT_LOAD) + goto die; + vax_load_failure++; + while (off < ph.p_offset) { + u_int32_t tmp; + read(io, &tmp, sizeof(tmp)); + off += sizeof(tmp); } - break; - - case VAX_TYP_8SS: - case VAX_TYP_750: - controller = bootregs[1]; - unit = bootregs[3]; - break; + read(io, (void *) ph.p_paddr, ph.p_filesz); + memset((void *) (ph.p_paddr + ph.p_filesz), 0, + ph.p_memsz - ph.p_filesz); + } else { + goto die; } - - switch (B_TYPE(bootdev)) { - case BDEV_HP: /* massbuss boot */ - adaptor = (bootregs[1] & 0x6000) >> 17; - break; - - case BDEV_UDA: /* UDA50 boot */ - if (vax_cputype == VAX_750) - adaptor = (bootregs[1] & 0x40000 ? 0 : 1); - break; - - case BDEV_TK: /* TK50 boot */ - case BDEV_CNSL: /* Console storage boot */ - case BDEV_RD: /* RD/RX on HDC9224 (MV2000) */ - case BDEV_ST: /* SCSI-tape on NCR5380 (MV2000) */ - case BDEV_SD: /* SCSI-disk on NCR5380 (3100/76) */ - case BDEV_SDN: /* SCSI disk on NCR53C94 */ - break; - - case BDEV_KDB: /* DSA disk on KDB50 (VAXBI VAXen) */ - bootdev = (bootdev & ~B_TYPEMASK) | BDEV_UDA; - break; - - default: - boothowto |= (RB_SINGLE | RB_ASKNAME); - } - return MAKEBOOTDEV(bootdev, adaptor, controller, unit, partition); + hoppabort(entry); +die: + asm("movl $0xbeef2, r0; halt"); } /* @@ -207,6 +190,51 @@ getbootdev() * - Can only load file "boot". * - Must be the first file on tape. */ +struct fs_ops file_system[] = { +#ifdef NEED_UFS + { ufs_open, 0, ufs_read, 0, 0, ufs_stat }, +#endif +#ifdef NEED_CD9660 + { cd9660_open, 0, cd9660_read, 0, 0, cd9660_stat }, +#endif +#ifdef NEED_USTARFS + { ustarfs_open, 0, ustarfs_read, 0, 0, ustarfs_stat }, +#endif +}; + +int nfsys = (sizeof(file_system) / sizeof(struct fs_ops)); + +#ifdef LIBSA_TOO_OLD +#include "../boot/vaxstand.h" + +struct rom_softc { + int part; + int unit; +} rom_softc; + +int romstrategy(void *, int, daddr_t, size_t, void *, size_t *); +int romopen(struct open_file *, int, int, int, int); +struct devsw devsw[] = { + SADEV("rom", romstrategy, romopen, nullsys, noioctl), +}; +int ndevs = (sizeof(devsw)/sizeof(devsw[0])); + +int +romopen(f, adapt, ctlr, unit, part) + struct open_file *f; + int adapt, ctlr, unit, part; +{ + rom_softc.unit = unit; + rom_softc.part = part; + + f->f_devdata = (void *)&rom_softc; + + return 0; +} + +#endif + +#if 0 int tar_open(char *path, struct open_file *f); ssize_t tar_read(struct open_file *f, void *buf, size_t size, size_t *resid); @@ -233,101 +261,68 @@ tar_read(f, buf, size, resid) { romstrategy(0, 0, (8192+512), size, buf, 0); *resid = size; + return 0; /* XXX */ } +#endif -struct disklabel lp; -int part_off = 0; /* offset into partition holding /boot */ -char io_buf[DEV_BSIZE]; -volatile struct uda { - struct mscp_1ca uda_ca; /* communications area */ - struct mscp uda_rsp; /* response packets */ - struct mscp uda_cmd; /* command packets */ -} uda; -struct udadevice {u_short udaip;u_short udasa;}; -volatile struct udadevice *csr; +int devopen(f, fname, file) struct open_file *f; const char *fname; char **file; { - extern char start; - char *msg; - int i, err, off; - char line[64]; - struct devsw *dp; +#ifdef LIBSA_TOO_OLD + int i; + struct devsw *dp; f->f_dev = &devsw[0]; +#endif *file = (char *)fname; + if (from == FROM750) + return 0; /* - * On uVAX we need to init [T]MSCP ctlr to be able to use it. + * Reinit the VMB boot device. */ - if (vax_cputype == VAX_TYP_UV2 || vax_cputype == VAX_TYP_CVAX) { - switch (bootdev) { - case BDEV_UDA: /* MSCP */ - case BDEV_TK: /* TMSCP */ + if (bqo->unit_init && (moved++ == 0)) { + int initfn; + + initfn = rpb->iovec + bqo->unit_init; + if (rpb->devtyp == BDEV_UDA || rpb->devtyp == BDEV_TK) { + /* + * This reset do not seem to be done in the + * ROM routines, so we have to do it manually. + */ csr = (struct udadevice *)rpb->csrphy; - - csr->udaip = 0; /* Start init */ - while((csr->udasa & MP_STEP1) == 0); - csr->udasa = 0x8000; - while((csr->udasa & MP_STEP2) == 0); - csr->udasa = (short)(((u_int)&uda)&0xffff) + 8; - while((csr->udasa & MP_STEP3) == 0); - csr->udasa = 0x10; - while((csr->udasa & MP_STEP4) == 0); - csr->udasa = 0x0001; - - uda.uda_ca.ca_rspdsc = - (int) &uda.uda_rsp.mscp_cmdref; - uda.uda_ca.ca_cmddsc = - (int) &uda.uda_cmd.mscp_cmdref; - if (bootdev == BDEV_TK) - uda.uda_cmd.mscp_vcid = 1; - command(M_OP_SETCTLRC, 0); - uda.uda_cmd.mscp_unit = rpb->unit; - command(M_OP_ONLINE, 0); + csr->udaip = 0; + while ((csr->udasa & MP_STEP1) == 0) + ; } + /* + * AP (R12) have a pointer to the VMB argument list, + * wanted by bqo->unit_init. + */ + unit_init(initfn, rpb, bootregs[12]); } - - /* - * the disklabel _shall_ be at address LABELOFFSET + RELOC in - * phys memory now, no need at all to reread it again. - * Actually disklabel is only needed when using hp disks, - * but it doesn't hurt to always get it. - */ - getdisklabel(LABELOFFSET + &start, &lp); - - /* currently only one dev in devsw; this must change if we add more */ - dp = devsw; - i = 0; - if(dp != NULL && dp->dv_open != NULL) { - i = (*dp->dv_open)(f, B_ADAPTOR(bootdev), B_CONTROLLER(bootdev), - B_UNIT(bootdev), B_PARTITION(bootdev)); - } - - return i; -} - -command(cmd, arg) -{ - volatile int hej; - - uda.uda_cmd.mscp_opcode = cmd; - uda.uda_cmd.mscp_modifier = arg; - - uda.uda_cmd.mscp_msglen = MSCP_MSGLEN; - uda.uda_rsp.mscp_msglen = MSCP_MSGLEN; - uda.uda_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT; - uda.uda_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT; - hej = csr->udaip; - while (uda.uda_ca.ca_rspdsc < 0); - +#ifdef LIBSA_TOO_OLD_FOO + /* currently only one dev in devsw; this must change if we add more */ + dp = devsw; + i = 0; + if(dp != NULL && dp->dv_open != NULL) { + i = (*dp->dv_open)(f, B_ADAPTOR(bootdev), B_CONTROLLER(bootdev), + B_UNIT(bootdev), B_PARTITION(bootdev)); + } + + return i; +#else + return 0; +#endif } -int curblock = 0; +extern struct disklabel romlabel; +int romstrategy(sc, func, dblk, size, buf, rsize) void *sc; int func; @@ -336,77 +331,31 @@ romstrategy(sc, func, dblk, size, buf, rsize) void *buf; size_t *rsize; { - struct rom_softc *romsc = sc; - int i; int block = dblk; int nsize = size; - switch (vax_cputype) { - /* - * case VAX_TYP_UV2: - * case VAX_TYP_CVAX: - * case VAX_TYP_RIGEL: - */ - default: - switch (B_TYPE(bootdev)) { - - case BDEV_UDA: /* MSCP */ - uda.uda_cmd.mscp_seq.seq_lbn = dblk; - uda.uda_cmd.mscp_seq.seq_bytecount = size; - uda.uda_cmd.mscp_seq.seq_buffer = (int)buf; - uda.uda_cmd.mscp_unit = rpb->unit; - command(M_OP_READ, 0); - break; - - case BDEV_TK: /* TMSCP */ - if (dblk < curblock) { - uda.uda_cmd.mscp_seq.seq_bytecount = - curblock - dblk; - command(M_OP_POS, 12); - } else { - uda.uda_cmd.mscp_seq.seq_bytecount = - dblk - curblock; - command(M_OP_POS, 4); + if (romlabel.d_magic == DISKMAGIC && romlabel.d_magic2 == DISKMAGIC) { + if (romlabel.d_npartitions > 1) { + block += romlabel.d_partitions[0].p_offset; + if (romlabel.d_partitions[0].p_fstype == FS_RAID) { + block += RF_PROTECTED_SECTORS; } - curblock = size/512 + dblk; - for (i = 0 ; i < size/512 ; i++) { - uda.uda_cmd.mscp_seq.seq_lbn = 1; - uda.uda_cmd.mscp_seq.seq_bytecount = 512; - uda.uda_cmd.mscp_seq.seq_buffer = - (int)buf + i * 512; - uda.uda_cmd.mscp_unit = rpb->unit; - command(M_OP_READ, 0); - } - break; - - case BDEV_SDN: /* XXX others too eventually */ - case BDEV_SD: /* XXX others too eventually */ - if(romsc != NULL) - block += lp.d_partitions[romsc->part].p_offset; - case BDEV_RD: - case BDEV_ST: - - default: - romread_uvax(block, size, buf, bootregs); - break; + } + } + if (from == FROMMV) { + romread_uvax(block, size, buf, rpb); + } else /* if (from == FROM750) */ { + while (size > 0) { + if (rpb->devtyp == BDEV_HP) + hpread(block); + else + read750(block, bootregs); + bcopy(0, buf, 512); + size -= 512; + (char *)buf += 512; + block++; } - break; - - case VAX_8200: - case VAX_750: - if (bootdev != BDEV_HP) { - while (size > 0) { - while ((read750(block, bootregs) & 0x01) == 0){ - } - bcopy(0, buf, 512); - size -= 512; - buf += 512; - block++; - } - } else - hpread(block, size, buf); - break; } if (rsize) @@ -414,50 +363,66 @@ romstrategy(sc, func, dblk, size, buf, rsize) return 0; } -int -romopen(f, adapt, ctlr, unit, part) - struct open_file *f; - int adapt, ctlr, unit, part; -{ - rom_softc.unit = unit; - rom_softc.part = part; - - f->f_devdata = (void *)&rom_softc; - - return 0; -} +/* + * The 11/750 boot ROM for Massbus disks doesn't seen to have layout info + * for all RP disks (not RP07 at least) so therefore a very small and dumb + * device driver is used. It assumes that there is a label on the disk + * already that has valid layout info. If there is no label, we can't boot + * anyway. + */ + +#define MBA_WCSR(reg, val) \ + ((void)(*(volatile u_int32_t *)((adpadr) + (reg)) = (val))); +#define MBA_RCSR(reg) \ + (*(volatile u_int32_t *)((adpadr) + (reg))) +#define HP_WCSR(reg, val) \ + ((void)(*(volatile u_int32_t *)((unitadr) + (reg)) = (val))); +#define HP_RCSR(reg) \ + (*(volatile u_int32_t *)((unitadr) + (reg))) -hpread(block, size, buf) - char *buf; +void +hpread(int bn) { - volatile struct mba_regs *mr = (void *) bootregs[1]; - volatile struct hp_drv *hd = (void *)&mr->mba_md[bootregs[3]]; - struct disklabel *dp = &lp; - u_int pfnum, nsize, mapnr, bn, cn, sn, tn; - - pfnum = (u_int) buf >> PGSHIFT; - - for (mapnr = 0, nsize = size; (nsize + NBPG) > 0; nsize -= NBPG) - *(int *)&mr->mba_map[mapnr++] = PG_V | pfnum++; - mr->mba_var = ((u_int) buf & PGOFSET); - mr->mba_bc = (~size) + 1; - bn = block; + int adpadr = bootregs[1]; + int unitadr = adpadr + MUREG(bootregs[3], 0); + u_int cn, sn, tn; + struct disklabel *dp; + extern char start; + + dp = (struct disklabel *)(LABELOFFSET + &start); + MBA_WCSR(MAPREG(0), PG_V); + + MBA_WCSR(MBA_VAR, 0); + MBA_WCSR(MBA_BC, (~512) + 1); +#ifdef __GNUC__ + /* + * Avoid four subroutine calls by using hardware division. + */ + asm("clrl %r1;" + "movl %3,%r0;" + "ediv %4,%r0,%0,%1;" + "movl %1,%r0;" + "ediv %5,%r0,%2,%1" + : "=g"(cn),"=g"(sn),"=g"(tn) + : "g"(bn),"g"(dp->d_secpercyl),"g"(dp->d_nsectors) + : "r0","r1","cc"); +#else cn = bn / dp->d_secpercyl; sn = bn % dp->d_secpercyl; tn = sn / dp->d_nsectors; sn = sn % dp->d_nsectors; - hd->hp_dc = cn; - hd->hp_da = (tn << 8) | sn; - hd->hp_cs1 = HPCS_READ; - while (mr->mba_sr & MBASR_DTBUSY); - if (mr->mba_sr & MBACR_ABORT){ - return 1; - } - return 0; +#endif + HP_WCSR(HP_DC, cn); + HP_WCSR(HP_DA, (tn << 8) | sn); + HP_WCSR(HP_CS1, HPCS_READ); + + while (MBA_RCSR(MBA_SR) & MBASR_DTBUSY) + ; + return; } extern char end[]; -static char *top = (char *)end; +static char *top = (char*)end; void * alloc(size) @@ -481,3 +446,31 @@ romclose(f) { return 0; } + +#ifdef USE_PRINTF +void +putchar(int ch) +{ + /* + * On KA88 we may get C-S/C-Q from the console. + * Must obey it. + */ + while (mfpr(PR_RXCS) & GC_DON) { + if ((mfpr(PR_RXDB) & 0x7f) == 19) { + while (1) { + while ((mfpr(PR_RXCS) & GC_DON) == 0) + ; + if ((mfpr(PR_RXDB) & 0x7f) == 17) + break; + } + } + } + + while ((mfpr(PR_TXCS) & GC_RDY) == 0) + ; + mtpr(0, PR_TXCS); + mtpr(ch & 0377, PR_TXDB); + if (ch == 10) + putchar(13); +} +#endif diff --git a/sys/arch/vax/boot/xxboot/start.s b/sys/arch/vax/stand/xxboot/start.S index f39ecafab62..309b53f308e 100644 --- a/sys/arch/vax/boot/xxboot/start.s +++ b/sys/arch/vax/stand/xxboot/start.S @@ -1,5 +1,5 @@ -/* $OpenBSD: start.s,v 1.3 2000/11/25 21:33:08 hugh Exp $ */ -/* $NetBSD: start.s,v 1.2 1999/10/23 14:40:38 ragge Exp $ */ +/* $OpenBSD: start.S,v 1.1 2002/06/11 09:36:24 hugh Exp $ */ +/* $NetBSD: start.S,v 1.1 2002/02/24 01:04:26 matt Exp $ */ /* * Copyright (c) 1995 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -17,8 +17,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 * @@ -37,15 +37,17 @@ /* All bugs are subject to removal without further notice */ -#define _LOCORE +#define _LOCORE #include "sys/disklabel.h" #include "../include/mtpr.h" #include "../include/asm.h" -_start: .globl _start # this is the symbolic name for the start - # of code to be relocated. We can use this +_C_LABEL(_start): +_C_LABEL(start): + .globl _C_LABEL(start) # this is the symbolic name for the start + .globl _C_LABEL(_start) # of code to be relocated. We can use this # to get the actual/real adress (pc-rel) # or to get the relocated address (abs). @@ -53,7 +55,7 @@ _start: .globl _start # this is the symbolic name for the start brb from_0x00 # continue behind dispatch-block .org 0x02 # information used by uVAX-ROM - .byte (LABELOFFSET + d_end_)/2 # offset in words to identification area + .byte 0xff # offset in words to identification area .byte 1 # this byte must be 1 .word 0 # logical block number (word swapped) .word 0 # of the secondary image @@ -61,38 +63,53 @@ _start: .globl _start # this is the symbolic name for the start .org 0x08 # brb from_0x08 # skip ... -.org 0x0A # uVAX booted from disk starts here - brb from_0x0A # skip ... - .org 0x0C # 11/750 & 8200 starts here + movzbl $1,_C_LABEL(from)# We booted from "old" rom. brw cont_750 from_0x00: # uVAX from TK50 -from_0x0A: # uVAX from disk - brw start_uvax # all(?) uVAXen continue there - -from_0x08: # What comes here??? - halt + brw start_uvax # all uVAXen continue there -.org LABELOFFSET - 6 -regmask: .word 0x0fff # using a variable saves 3 bytes !!! -bootinfo: .long 0x0 # another 3 bytes if within byte-offset +from_0x08: # Any machine from VMB + movzbl $4,_C_LABEL(from) # Booted from full VMB + brw start_vmb # the complete area reserved for label # must be empty (i.e. filled with zeroes). # disklabel(8) checks that before installing # the bootblocks over existing label. +.org LABELOFFSET + .globl _C_LABEL(romlabel) +_C_LABEL(romlabel): + .long 0 + +.org LABELOFFSET + d_end_ +start_vmb: + /* + * Read in block 1-15. + */ + movl 52(r11), r7 # load iovec/bqo into %r7 + addl3 (r7), r7, r6 # load qio into %r6 + pushl r11 # base of rpb + pushl $0 # virtual-flag + pushl $33 # read-logical-block + pushl $1 # lbn to start reading + pushl $7680 # number of bytes to read + pushab start_uvax # buffer-address + calls $6, (r6) # call the qio-routine + brw start_uvax + /* * Parameter block for uVAX boot. */ -#define VOLINFO 0 /* 1=single-sided 81=double-sided volumes */ -#define SISIZE 16 /* size in blocks of secondary image */ -#define SILOAD 0 /* load offset (usually 0) from the default */ -#define SIOFF 0x0A /* byte offset into secondary image */ +#define VOLINFO 0 /* 1=single-sided 81=double-sided volumes */ +#define SISIZE 16 /* size in blocks of secondary image */ +#define SILOAD 0 /* load offset (usually 0) from the default */ +#define SIOFF 0x260 /* byte offset into secondary image */ -.org LABELOFFSET + d_end_ +.org 0x1fe .byte 0x18 # must be 0x18 .byte 0x00 # must be 0x00 (MBZ) .byte 0x00 # any value @@ -106,15 +123,21 @@ bootinfo: .long 0x0 # another 3 bytes if within byte-offset .long SISIZE # size in blocks of secondary image .long SILOAD # load offset (usually 0) - .long SIOFF # byte offset into secondary image + .long SIOFF # byte offset into secondary image .long (SISIZE + SILOAD + SIOFF) # sum of previous 3 + + .align 2 + .globl _C_LABEL(from) +_C_LABEL(from): + .long 0 + /* * After bootblock (LBN0) has been loaded into the first page * of good memory by 11/750's ROM-code (transfer address * of bootblock-code is: base of good memory + 0x0C) registers * are initialized as: - * R0: type of boot-device + * R0: type of boot-device * 0: Massbus device * 1: RK06/RK07 * 2: RL02 @@ -123,35 +146,39 @@ bootinfo: .long 0x0 # another 3 bytes if within byte-offset * 64: TU58 * R1: (UBA) address of UNIBUS I/O-page * (MBA) address of boot device's adapter - * R2: (UBA) address of the boot device's CSR + * R2: (UBA) address of the boot device's CSR * (MBA) controller number of boot device * R6: address of driver subroutine in ROM * * cont_750 reads in LBN1-15 for further execution. */ - .align 2 cont_750: - movl r0,r10 - clrl r5 - clrl r4 - movl $_start,sp -1: incl r4 - movl r4,r8 - addl2 $0x200,r5 - cmpl $16,r4 - beql 2f - pushl r5 - jsb (r6) - blbs r0,1b -2: movl r10, r0 - movl r11, r5 - brw start_all - - .org 0x300 + movl $_C_LABEL(start), sp # move stack to avoid clobbering the code + pushr $0x131 # save clobbered registers + clrl r4 # %r4 == # of blocks transferred + movab _C_LABEL(start),r5 # %r5 have base address for next transfer + pushl r5 # ...on stack also (Why?) +1: incl r4 # increment block count + movl r4,r8 # LBN is in %r8 for rom routine + addl2 $0x200,r5 # Increase address for next read + cmpl $16,r4 # read 15 blocks? + beql 2f # Yep + movl r5,(sp) # move address to stack also + jsb (r6) # read 512 bytes + blbs r0,1b # jump if read succeeded + halt # otherwise die... +2: tstl (sp)+ # remove boring arg from stack + popr $0x131 # restore clobbered registers + brw start_all # Ok, continue... + +/* uVAX main entry is at the start of the second disk block. This is + * needed for multi-arch CD booting where multiple architecture need + * to shove stuff in boot block 0. + */ + .org 0x260 # uVAX booted from disk starts here start_uvax: - mtpr $0, $PR_MAPEN # Turn off MM, please. - movl $_start, sp + movzbl $2,_C_LABEL(from) # Booted from subset-VMB brb start_all /* @@ -159,20 +186,23 @@ start_uvax: * to RELOC and loads boot. */ start_all: + movl $_C_LABEL(start), sp # move stack to a better pushr $0x1fff # save all regs, used later. - subl3 $_start, $_edata, r0 # get size of text+data (w/o bss) - moval _start, r1 # get actual base-address of code - subl3 $_start, $_end, r2 # get complete size (incl. bss) - movl $_start, r3 # get relocated base-address of code + subl3 $_C_LABEL(start), $_C_LABEL(edata), r0 + # get size of text+data (w/o bss) + moval _C_LABEL(start), r1 # get actual base-address of code + subl3 $_C_LABEL(start), $_C_LABEL(end), r2 + # get complete size (incl. bss) + movl $_C_LABEL(start), r3 # get relocated base-address of code movc5 r0, (r1), $0, r2, (r3) # copy code to new location - jsb 1f -1: movl $relocated, (sp) # return-address on top of stack - rsb # can be replaced with new address + movpsl -(sp) + movl $relocated, -(sp) # return-address on top of stack + rei # can be replaced with new address relocated: # now relocation is done !!! - movl sp, _bootregs - calls $0, _Xmain # call Xmain (gcc workaround)which is + movl sp, _C_LABEL(bootregs) + calls $0, _C_LABEL(Xmain) # call Xmain (gcc workaround)which is halt # not intended to return ... /* @@ -180,20 +210,32 @@ relocated: # now relocation is done !!! */ ENTRY(hoppabort, 0) movl 4(ap),r6 - movl 8(ap),r11 - movl 0xc(ap),r10 - movl _memsz, r8 - mnegl $1, ap # Hack to figure out boot device. - jmp 2(r6) -# calls $0,(r6) + movl _C_LABEL(rpb),r11 + mnegl $1,ap # Hack to figure out boot device. + movpsl -(sp) + pushab 2(r6) + mnegl $1,_C_LABEL(vax_load_failure) + rei +# calls $0,(r6) halt +ENTRY(unit_init, R6|R7|R8|R9|R10|R11) + mfpr $17,r7 # Wanted bu KDB + movl 4(ap),r0 # init routine address + movl 8(ap),r9 # RPB in %r9 + movl 12(ap),r1 # VMB argument list + callg (r1),(r0) + ret + # A bunch of functions unwanted in boot blocks. ENTRY(getchar, 0) halt +#ifndef USE_PRINTF ENTRY(putchar, 0) ret +#endif + ENTRY(panic, 0) halt diff --git a/sys/arch/vax/vax/autoconf.c b/sys/arch/vax/vax/autoconf.c index 58708618d03..6f1cf36f04c 100644 --- a/sys/arch/vax/vax/autoconf.c +++ b/sys/arch/vax/vax/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.17 2002/04/04 23:47:33 deraadt Exp $ */ +/* $OpenBSD: autoconf.c,v 1.18 2002/06/11 09:36:24 hugh Exp $ */ /* $NetBSD: autoconf.c,v 1.45 1999/10/23 14:56:05 ragge Exp $ */ /* @@ -64,8 +64,10 @@ void gencnslask(void); void setroot(void); /* rootfil.c */ struct cpu_dep *dep_call; +extern struct device *bootdv; + int mastercpu; /* chief of the system */ -struct device *booted_from; + #define MAINBUS 0 @@ -89,15 +91,6 @@ cpu_configure() cold = 0; - if (mountroot == NULL) { - if (B_TYPE(bootdev) >= BDEV_NET) { -#ifdef NFSCLIENT - mountroot = nfs_mountroot; -#endif - } else - mountroot = dk_mountroot; - } - if (dep_call->cpu_clrf) (*dep_call->cpu_clrf)(); } @@ -150,6 +143,12 @@ mainbus_attach(parent, self, hej) if (dep_call->cpu_subconf) (*dep_call->cpu_subconf)(self); + +#if 1 /* boot blocks too old */ + if (rpb.rpb_base == (void *)-1) + printf("\nWARNING: you must update your boot blocks.\n\n"); +#endif + } struct cfattach mainbus_ca = { @@ -160,4 +159,278 @@ struct cfdriver mainbus_cd = { NULL, "mainbus", DV_DULL }; +#include "sd.h" +#include "cd.h" +#if NRL > 0 +#include "rl.h" +#endif +#include "ra.h" +#include "hp.h" +#if NRY > 0 +#include "ry.h" +#endif + +static int ubtest(void *); +static int jmfr(char *, struct device *, int); +static int booted_qe(struct device *, void *); +static int booted_le(struct device *, void *); +static int booted_ze(struct device *, void *); +static int booted_de(struct device *, void *); +static int booted_ni(struct device *, void *); +#if NSD > 0 || NCD > 0 +static int booted_sd(struct device *, void *); +#endif +#if NRL > 0 +static int booted_rl(struct device *, void *); +#endif +#if NRA +static int booted_ra(struct device *, void *); +#endif +#if NHP +static int booted_hp(struct device *, void *); +#endif +#if NRD +static int booted_rd(struct device *, void *); +#endif + +int (*devreg[])(struct device *, void *) = { + booted_qe, + booted_le, + booted_ze, + booted_de, + booted_ni, +#if NSD > 0 || NCD > 0 + booted_sd, +#endif +#if NRL > 0 + booted_rl, +#endif +#if NRA + booted_ra, +#endif +#if NHP + booted_hp, +#endif +#if NRD + booted_hd, +#endif + 0, +}; + +#define ubreg(x) ((x) & 017777) + +void +device_register(struct device *dev, void *aux) +{ + int (**dp)(struct device *, void *) = devreg; + + /* If there's a synthetic RPB, we can't trust it */ + if (rpb.rpb_base == (void *)-1) + return; + + while (*dp) { + if ((*dp)(dev, aux)) { + bootdv = dev; + break; + } + dp++; + } +} + +/* + * Simple checks. Return 1 on fail. + */ +int +jmfr(char *n, struct device *dev, int nr) +{ + if (rpb.devtyp != nr) + return 1; + return strcmp(n, dev->dv_cfdata->cf_driver->cd_name); +} + +#include <arch/vax/qbus/ubavar.h> +int +ubtest(void *aux) +{ + paddr_t p; + + p = kvtophys(((struct uba_attach_args *)aux)->ua_ioh); + if (rpb.csrphy != p) + return 1; + return 0; +} + +#if 1 /* NNI */ +#include <arch/vax/bi/bivar.h> +int +booted_ni(struct device *dev, void *aux) +{ + struct bi_attach_args *ba = aux; + + if (jmfr("ni", dev, BDEV_NI) || (kvtophys(ba->ba_ioh) != rpb.csrphy)) + return 0; + + return 1; +} +#endif /* NNI */ + +#if 1 /* NDE */ +int +booted_de(struct device *dev, void *aux) +{ + + if (jmfr("de", dev, BDEV_DE) || ubtest(aux)) + return 0; + + return 1; +} +#endif /* NDE */ +int +booted_le(struct device *dev, void *aux) +{ + if (jmfr("le", dev, BDEV_LE)) + return 0; + return 1; +} + +int +booted_ze(struct device *dev, void *aux) +{ + if (jmfr("ze", dev, BDEV_ZE)) + return 0; + return 1; +} + +#if 1 /* NQE */ +int +booted_qe(struct device *dev, void *aux) +{ + if (jmfr("qe", dev, BDEV_QE) || ubtest(aux)) + return 0; + + return 1; +} +#endif /* NQE */ + +#if NSD > 0 || NCD > 0 +#include <scsi/scsi_all.h> +#include <scsi/scsiconf.h> +int +booted_sd(struct device *dev, void *aux) +{ + struct scsibus_attach_args *sa = aux; + struct device *ppdev; + + /* Is this a SCSI device? */ + if (jmfr("sd", dev, BDEV_SD) && jmfr("cd", dev, BDEV_SD) && + jmfr("sd", dev, BDEV_SDN) && jmfr("cd", dev, BDEV_SDN)) + return 0; + +#ifdef __NetBSD__ + if (sa->sa_periph->periph_channel->chan_bustype->bustype_type != + SCSIPI_BUSTYPE_SCSI) + return 0; /* ``Cannot happen'' */ +#endif + + if (sa->sa_sc_link->target != rpb.unit) + return 0; /* Wrong unit */ + + ppdev = dev->dv_parent->dv_parent; + + /* VS3100 NCR 53C80 (si) & VS4000 NCR 53C94 (asc) */ + if (((jmfr("ncr", ppdev, BDEV_SD) == 0) || /* old name */ + (jmfr("asc", ppdev, BDEV_SD) == 0) || + (jmfr("asc", ppdev, BDEV_SDN) == 0)) && + (ppdev->dv_cfdata->cf_loc[0] == rpb.csrphy)) + return 1; + + return 0; /* Where did we come from??? */ +} +#endif +#if NRL > 0 +#include <dev/qbus/rlvar.h> +int +booted_rl(struct device *dev, void *aux) +{ + struct rlc_attach_args *raa = aux; + static int ub; + + if (jmfr("rlc", dev, BDEV_RL) == 0) + ub = ubtest(aux); + if (ub) + return 0; + if (jmfr("rl", dev, BDEV_RL)) + return 0; + if (raa->hwid != rpb.unit) + return 0; /* Wrong unit number */ + return 1; +} +#endif + +#if NRA +#include <arch/vax/mscp/mscp.h> +#include <arch/vax/mscp/mscpreg.h> +#include <arch/vax/mscp/mscpvar.h> +int +booted_ra(struct device *dev, void *aux) +{ + struct drive_attach_args *da = aux; + struct mscp_softc *pdev = (void *)dev->dv_parent; + paddr_t ioaddr; + + if (jmfr("ra", dev, BDEV_UDA)) + return 0; + + if (da->da_mp->mscp_unit != rpb.unit) + return 0; /* Wrong unit number */ + + ioaddr = kvtophys(pdev->mi_iph); /* Get phys addr of CSR */ + if (rpb.devtyp == BDEV_UDA && rpb.csrphy == ioaddr) + return 1; /* Did match CSR */ + + return 0; +} +#endif +#if NHP +#include <vax/mba/mbavar.h> +int +booted_hp(struct device *dev, void *aux) +{ + static int mbaaddr; + + /* Save last adapter address */ + if (jmfr("mba", dev, BDEV_HP) == 0) { + struct sbi_attach_args *sa = aux; + + mbaaddr = kvtophys(sa->sa_ioh); + return 0; + } + + if (jmfr("hp", dev, BDEV_HP)) + return 0; + + if (((struct mba_attach_args *)aux)->ma_unit != rpb.unit) + return 0; + + if (mbaaddr != rpb.adpphy) + return 0; + + return 1; +} +#endif +#if NHD +int +booted_hd(struct device *dev, void *aux) +{ + int *nr = aux; /* XXX - use the correct attach struct */ + + if (jmfr("hd", dev, BDEV_RD)) + return 0; + + if (*nr != rpb.unit) + return 0; + + return 1; +} +#endif diff --git a/sys/arch/vax/vax/ka49.c b/sys/arch/vax/vax/ka49.c index 6cce9856707..80107401499 100644 --- a/sys/arch/vax/vax/ka49.c +++ b/sys/arch/vax/vax/ka49.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ka49.c,v 1.4 2002/03/14 01:26:48 millert Exp $ */ +/* $OpenBSD: ka49.c,v 1.5 2002/06/11 09:36:24 hugh Exp $ */ /* * Copyright (c) 1999 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -149,7 +149,6 @@ ka49_cache_enable() mtpr(mfpr(PR_BCEDSTS), PR_BCEDSTS); /* Clear error bits */ mtpr(mfpr(PR_NESTS), PR_NESTS); /* Clear error bits */ - start = 0x01400000; slut = 0x01440000; diff --git a/sys/arch/vax/vax/locore.c b/sys/arch/vax/vax/locore.c index 2709576b53d..c8df12d954d 100644 --- a/sys/arch/vax/vax/locore.c +++ b/sys/arch/vax/vax/locore.c @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.c,v 1.23 2002/03/14 01:26:48 millert Exp $ */ +/* $OpenBSD: locore.c,v 1.24 2002/06/11 09:36:24 hugh Exp $ */ /* $NetBSD: locore.c,v 1.43 2000/03/26 11:39:45 ragge Exp $ */ /* * Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden. @@ -49,8 +49,9 @@ #include <machine/pte.h> #include <machine/pmap.h> #include <machine/nexus.h> +#include <machine/rpb.h> -void start(void); +void start(struct rpb *); void main(void); extern paddr_t avail_end; @@ -84,7 +85,7 @@ extern struct cpu_dep ka680_calls; * management is disabled, and no interrupt system is active. */ void -start() +start(struct rpb *prpb) { extern char cpu_model[]; extern void *scratch; @@ -287,16 +288,30 @@ start() asm("halt"); } - /* - * Machines older than MicroVAX II have their boot blocks - * loaded directly or the boot program loaded from console - * media, so we need to figure out their memory size. - * This is not easily done on MicroVAXen, so we get it from - * VMB instead. - */ - if (avail_end == 0) - while (badaddr((caddr_t)avail_end, 4) == 0) - avail_end += VAX_NBPG * 128; + /* + * Machines older than MicroVAX II have their boot blocks + * loaded directly or the boot program loaded from console + * media, so we need to figure out their memory size. + * This is not easily done on MicroVAXen, so we get it from + * VMB instead. + * + * In post-1.4 a RPB is always provided from the boot blocks. + */ +#if 1 /* compat with old bootblocks */ + if (prpb == 0) { + bzero((caddr_t)proc0paddr + REDZONEADDR, sizeof(struct rpb)); + prpb = (struct rpb *)(proc0paddr + REDZONEADDR); + prpb->pfncnt = avail_end >> VAX_PGSHIFT; + prpb->rpb_base = (void *)-1; /* RPB is fake */ + } else +#endif + bcopy(prpb, (caddr_t)proc0paddr + REDZONEADDR, sizeof(struct rpb)); + if (prpb->pfncnt) + avail_end = prpb->pfncnt << VAX_PGSHIFT; + else + while (badaddr((caddr_t)avail_end, 4) == 0) + avail_end += VAX_NBPG * 128; + boothowto = prpb->rpb_bootr5; avail_end = TRUNC_PAGE(avail_end); /* be sure */ diff --git a/sys/arch/vax/vax/pmap.c b/sys/arch/vax/vax/pmap.c index d5b5e8b36f1..33bbc4f6738 100644 --- a/sys/arch/vax/vax/pmap.c +++ b/sys/arch/vax/vax/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.30 2002/03/14 01:26:49 millert Exp $ */ +/* $OpenBSD: pmap.c,v 1.31 2002/06/11 09:36:24 hugh Exp $ */ /* $NetBSD: pmap.c,v 1.74 1999/11/13 21:32:25 matt Exp $ */ /* * Copyright (c) 1994, 1998, 1999 Ludd, University of Lule}, Sweden. @@ -54,6 +54,7 @@ #include <machine/sid.h> #include <machine/cpu.h> #include <machine/scb.h> +#include <machine/rpb.h> #include <uvm/uvm_extern.h> @@ -224,7 +225,7 @@ pmap_bootstrap() /* Init SCB and set up stray vectors. */ avail_start = scb_init(avail_start); - bzero(0, VAX_NBPG >> 1); + bcopy((caddr_t)proc0paddr + REDZONEADDR, 0, sizeof(struct rpb)); if (dep_call->cpu_steal_pages) (*dep_call->cpu_steal_pages)(); @@ -271,6 +272,8 @@ pmap_bootstrap() avail_start >> PGSHIFT, avail_end >> PGSHIFT, VM_FREELIST_DEFAULT); mtpr(sysptsize, PR_SLR); + rpb.sbr = mfpr(PR_SBR); + rpb.slr = mfpr(PR_SLR); mtpr(1, PR_MAPEN); } diff --git a/sys/arch/vax/vax/rootfil.c b/sys/arch/vax/vax/rootfil.c index 639d302c258..8cff5e459f2 100644 --- a/sys/arch/vax/vax/rootfil.c +++ b/sys/arch/vax/vax/rootfil.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rootfil.c,v 1.11 2001/06/15 22:45:33 miod Exp $ */ +/* $OpenBSD: rootfil.c,v 1.12 2002/06/11 09:36:24 hugh Exp $ */ /* $NetBSD: rootfil.c,v 1.14 1996/10/13 03:35:58 christos Exp $ */ /* @@ -52,6 +52,9 @@ #include <sys/reboot.h> #include <sys/conf.h> #include <sys/device.h> +#include <sys/disklabel.h> + +#include <dev/cons.h> #include <machine/macros.h> #include <machine/nexus.h> @@ -66,13 +69,30 @@ #include "sd.h" #include "asc.h" -extern dev_t rootdev, dumpdev; +void setroot(void); +void diskconf(void); +static int getstr(char *, int); +struct device *parsedisk(char *, int, int, dev_t *); +static struct device *getdisk(char *, int, int, dev_t *); +int findblkmajor(struct device *); +char *findblkname(int); struct ngcconf { struct cfdriver *ng_cf; dev_t ng_root; }; +int findblkmajor(struct device *); + +struct device *bootdv; +int booted_partition; /* defaults to 0 (aka 'a' partition */ + +extern dev_t rootdev, dumpdev; + +#ifdef RAMDISK_HOOKS +static struct device fakerdrootdev = { DV_DISK, {}, NULL, 0, "rd0", NULL }; +#endif + /* * Attempt to find the device from which we were booted. * If we can do so, and not instructed not to do so, @@ -81,75 +101,368 @@ struct ngcconf { void setroot() { - int majdev, mindev, unit, part, controller, adaptor; - dev_t orootdev; + struct swdevt *swp; + int len, majdev, unit, part = 0; + dev_t nrootdev, nswapdev, temp; extern int boothowto; - char *uname; + struct device *dv; + char buf[128]; +#if defined(NFSCLIENT) + extern char *nfsbootdevname; +#endif - if ((bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) { - printf("RPB data looks bogus, prompting user\n"); - boothowto |= RB_ASKNAME; + if (rpb.rpb_base != (void *)-1) { +#if DEBUG + printf("booted from type %d unit %d csr 0x%lx adapter %lx slave %d\n", + rpb.devtyp, rpb.unit, rpb.csrphy, rpb.adpphy, rpb.slave); +#endif + bootdev = MAKEBOOTDEV(rpb.devtyp, 0, 0, rpb.unit, 0); } - if (((boothowto & RB_DFLTROOT) || (rootdev != NODEV)) - && !(boothowto & RB_ASKNAME)) - return; +#ifdef RAMDISK_HOOKS + bootdv = &fakerdrootdev; +#endif + + printf("booted from device: %s\n", + bootdv ? bootdv->dv_xname : "<unknown>"); + + if (bootdv == NULL) + boothowto |= RB_ASKNAME; if (boothowto & RB_ASKNAME) { - printf("root device selection is not currently supported\n"); + for (;;) { + printf("root device "); + if (bootdv != NULL) + printf("(default %s%c)", + bootdv->dv_xname, + bootdv->dv_class == DV_DISK + ? booted_partition + 'a' : ' '); + printf(": "); + len = getstr(buf, sizeof(buf)); + if (len == 0 && bootdv != NULL) { + strcpy(buf, bootdv->dv_xname); + len = strlen(buf); + } + if (len > 0 && buf[len - 1] == '*') { + buf[--len] = '\0'; + dv = getdisk(buf, len, 1, &nrootdev); + if (dv != NULL) { + bootdv = dv; + nswapdev = nrootdev; + goto gotswap; + } + } + dv = getdisk(buf, len, booted_partition, &nrootdev); + if (dv != NULL) { + bootdv = dv; + break; + } + } + + /* + * because swap must be on same device as root, for + * network devices this is easy. + */ + if (bootdv->dv_class == DV_IFNET) { + goto gotswap; + } + for (;;) { + printf("swap device "); + if (bootdv != NULL) + printf("(default %s%c)", + bootdv->dv_xname, + bootdv->dv_class == DV_DISK ? 'b' : ' '); + printf(": "); + len = getstr(buf, sizeof(buf)); + if (len == 0 && bootdv != NULL) { + switch (bootdv->dv_class) { + case DV_IFNET: + nswapdev = NODEV; + break; + case DV_DISK: + nswapdev = MAKEDISKDEV(major(nrootdev), + DISKUNIT(nrootdev), 1); + break; + case DV_TAPE: + case DV_TTY: + case DV_DULL: + case DV_CPU: + break; + } + break; + } + dv = getdisk(buf, len, 1, &nswapdev); + if (dv) { + if (dv->dv_class == DV_IFNET) + nswapdev = NODEV; + break; + } + } +gotswap: + rootdev = nrootdev; + dumpdev = nswapdev; + swdevt[0].sw_dev = nswapdev; + swdevt[1].sw_dev = NODEV; + + } else if (mountroot == NULL) { + /* + * `swap generic': Use the device the ROM told us to use. + */ + majdev = findblkmajor(bootdv); + if (majdev >= 0) { + /* + * Root and swap are on a disk. + * val[2] of the boot device is the partition number. + * Assume swap is on partition b. + */ + part = booted_partition; + unit = bootdv->dv_unit; + rootdev = MAKEDISKDEV(majdev, unit, part); + nswapdev = dumpdev = MAKEDISKDEV(major(rootdev), + DISKUNIT(rootdev), 1); + } else { + /* + * Root and swap are on a net. + */ + nswapdev = dumpdev = NODEV; + } + swdevt[0].sw_dev = nswapdev; + /* swdevt[1].sw_dev = NODEV; */ + + } else { + + /* + * `root DEV swap DEV': honour rootdev/swdevt. + * rootdev/swdevt/mountroot already properly set. + */ + if (bootdv->dv_class == DV_DISK) + printf("root on %s%c\n", bootdv->dv_xname, + part + 'a'); + majdev = major(rootdev); + unit = DISKUNIT(rootdev); + part = DISKPART(rootdev); + return; } - majdev = bdevtomaj(B_TYPE(bootdev)); - if (majdev >= nblkdev || majdev == -1) - return; - adaptor = B_ADAPTOR(bootdev); - controller = B_CONTROLLER(bootdev); - part = B_PARTITION(bootdev); - unit = B_UNIT(bootdev); - - switch (majdev) { - case 0: /* MBA disk */ -#if NHP - if ((mindev = hp_getdev(adaptor, unit, &uname)) < 0) + switch (bootdv->dv_class) { +#if defined(NFSCLIENT) + case DV_IFNET: + mountroot = nfs_mountroot; + nfsbootdevname = bootdv->dv_xname; + return; #endif - return; + case DV_DISK: + mountroot = dk_mountroot; + majdev = major(rootdev); + unit = DISKUNIT(rootdev); + part = DISKPART(rootdev); + printf("root on %s%c\n", bootdv->dv_xname, part + 'a'); break; + default: + printf("can't figure root, hope your kernel is right\n"); + return; + } + + /* + * Make the swap partition on the root drive the primary swap. + */ + temp = NODEV; + for (swp = swdevt; swp->sw_dev != NODEV; swp++) { + if (majdev == major(swp->sw_dev) && + unit == DISKUNIT(swp->sw_dev)) { + temp = swdevt[0].sw_dev; + swdevt[0].sw_dev = swp->sw_dev; + swp->sw_dev = temp; + break; + } + } + if (swp->sw_dev != NODEV) { + /* + * If dumpdev was the same as the old primary swap device, + * move it to the new primary swap device. + */ + if (temp == dumpdev) + dumpdev = swdevt[0].sw_dev; + } +} + +struct nam2blk { + char *name; + int maj; +} nam2blk[] = { + { "ra", 9 }, + { "rx", 12 }, + { "rl", 14 }, + { "sd", 20 }, + { "rd", 23 }, + { "raid", 25 }, + { "cd", 61 }, +}; + +int +findblkmajor(dv) + struct device *dv; +{ + char *name = dv->dv_xname; + int i; + + for (i = 0; i < sizeof(nam2blk)/sizeof(nam2blk[0]); ++i) + if (strncmp(name, nam2blk[i].name, strlen(nam2blk[i].name)) == 0) + return (nam2blk[i].maj); + return (-1); +} + +char * +findblkname(maj) + int maj; +{ + int i; + + for (i = 0; i < sizeof(nam2blk)/sizeof(nam2blk[0]); ++i) + if (nam2blk[i].maj == maj) + return (nam2blk[i].name); + return (NULL); +} - case 9: /* MSCP disk */ -#if NRA - if ((mindev = ra_getdev(adaptor, controller, unit, &uname)) < 0) + +static struct device * +getdisk(str, len, defpart, devp) + char *str; + int len, defpart; + dev_t *devp; +{ + struct device *dv; + + if ((dv = parsedisk(str, len, defpart, devp)) == NULL) { + printf("use one of:"); +#ifdef RAMDISK_HOOKS + printf(" %s[a-p]", fakerdrootdev.dv_xname); #endif - return; - break; + for (dv = alldevs.tqh_first; dv != NULL; + dv = dv->dv_list.tqe_next) { + if (dv->dv_class == DV_DISK) + printf(" %s[a-p]", dv->dv_xname); +#ifdef NFSCLIENT + if (dv->dv_class == DV_IFNET) + printf(" %s", dv->dv_xname); +#endif + } + printf("\n"); + } + return (dv); +} - case 20: /* SCSI disk */ -#if NASC || NSD - if((mindev = sd_getdev(adaptor, controller, part, unit, &uname)) < 0) +struct device * +parsedisk(str, len, defpart, devp) + char *str; + int len, defpart; + dev_t *devp; +{ + struct device *dv; + char *cp, c; + int majdev, unit, part; + + if (len == 0) + return (NULL); + cp = str + len - 1; + c = *cp; + if (c >= 'a' && (c - 'a') < MAXPARTITIONS) { + part = c - 'a'; + *cp = '\0'; + } else + part = defpart; + +#ifdef RAMDISK_HOOKS + if (strcmp(str, fakerdrootdev.dv_xname) == 0) { + dv = &fakerdrootdev; + goto gotdisk; + } #endif - return; - break; - default: - return; - } + for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next) { + if (dv->dv_class == DV_DISK && + strcmp(str, dv->dv_xname) == 0) { +#ifdef RAMDISK_HOOKS +gotdisk: +#endif + majdev = findblkmajor(dv); + unit = dv->dv_unit; + if (majdev < 0) + panic("parsedisk"); + *devp = MAKEDISKDEV(majdev, unit, part); + break; + } +#ifdef NFSCLIENT + if (dv->dv_class == DV_IFNET && + strcmp(str, dv->dv_xname) == 0) { + *devp = NODEV; + break; + } +#endif + } - mindev *= MAXPARTITIONS; - mindev += part; - orootdev = rootdev; - rootdev = makedev(majdev, mindev); - - swdevt[0].sw_dev = dumpdev = makedev(major(rootdev), 1); - - /* - * If the original rootdev is the same as the one - * just calculated, don't need to adjust the swap configuration. - */ - if (rootdev == orootdev) - printf("Setting root device to %s%c\n", uname, part + 'a'); - else - printf("Changing root device to %s%c\n", uname, part + 'a'); + *cp = c; + return (dv); } +static int +getstr(char *buf, int size) { + int len; + cnpollc(1); + len = getsn(buf, size); + cnpollc(0); + return (len); +} + +#if 0 +static int +getstr(cp, size) + char *cp; + int size; +{ + char *lp; + int c; + int len; + + lp = cp; + len = 0; + for (;;) { + c = cngetc(); + switch (c) { + case '\n': + case '\r': + printf("\n"); + *lp++ = '\0'; + return (len); + case '\b': + case '\177': + case '#': + if (len) { + --len; + --lp; + printf("\b \b"); + } + continue; + case '@': + case 'u'&037: + len = 0; + lp = cp; + printf("\n"); + continue; + default: + if (len + 1 >= size || c < ' ') { + printf("\007"); + continue; + } + printf("%c", c); + ++len; + *lp++ = c; + } + } +} + +#endif + /* * Configure swap space and related parameters. */ diff --git a/sys/arch/vax/vax/subr.s b/sys/arch/vax/vax/subr.s index 4dc1b812de3..38a705fb3bd 100644 --- a/sys/arch/vax/vax/subr.s +++ b/sys/arch/vax/vax/subr.s @@ -1,4 +1,4 @@ -/* $OpenBSD: subr.s,v 1.16 2002/01/23 23:24:40 miod Exp $ */ +/* $OpenBSD: subr.s,v 1.17 2002/06/11 09:36:24 hugh Exp $ */ /* $NetBSD: subr.s,v 1.32 1999/03/25 00:41:48 mrg Exp $ */ /* @@ -46,10 +46,7 @@ * First entry routine from boot. This should be in a file called locore. */ ASENTRY(start, 0) - movl r11,_boothowto # Howto boot (single etc...) - movl r10,_bootdev # From where? (see rpb.h) bisl3 $0x80000000,r9,_esym # End of loaded code - movl r8,_avail_end # Usable memory (from VMB) pushl $0x1f0000 # Push a nice PSL pushl $to # Address to jump to rei # change to kernel stack @@ -81,7 +78,19 @@ eskip: clrl IFTRAP(r0) mtpr $0,$PR_SCBB - calls $0,_start # Jump away. +# Copy the RPB to its new position +#if 1 /* compat with old bootblocks */ + tstl (ap) # Any arguments? + bneq 1f # Yes, called from new boot + movl r11,_boothowto # Howto boot (single etc...) +# movl r10,_bootdev # uninteresting, will complain + movl r8,_avail_end # Usable memory (from VMB) + clrl -(sp) # Have no RPB + brb 2f +#endif + +1: pushl 4(ap) # Address of old rpb +2: calls $1,_start # Jump away. /* NOTREACHED */ |