summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/mvme88k/conf/GENERIC4
-rw-r--r--sys/arch/mvme88k/conf/RAMDISK4
-rw-r--r--sys/arch/mvme88k/conf/files.mvme88k15
-rw-r--r--sys/arch/mvme88k/dev/bugio.c56
-rw-r--r--sys/arch/mvme88k/dev/cl.c60
-rw-r--r--sys/arch/mvme88k/dev/clock.c36
-rw-r--r--sys/arch/mvme88k/dev/if_ie.c99
-rw-r--r--sys/arch/mvme88k/dev/if_ve.c1345
-rw-r--r--sys/arch/mvme88k/dev/if_vereg.h218
-rw-r--r--sys/arch/mvme88k/dev/if_vevar.h146
-rw-r--r--sys/arch/mvme88k/dev/mainbus.c4
-rw-r--r--sys/arch/mvme88k/dev/memc.c4
-rw-r--r--sys/arch/mvme88k/dev/pcctwo.c4
-rw-r--r--sys/arch/mvme88k/dev/siop.c24
-rw-r--r--sys/arch/mvme88k/dev/vme.c176
-rw-r--r--sys/arch/mvme88k/dev/vme.h11
-rw-r--r--sys/arch/mvme88k/dev/vs.c758
-rw-r--r--sys/arch/mvme88k/dev/vsdma.c197
-rw-r--r--sys/arch/mvme88k/dev/vsreg.h695
-rw-r--r--sys/arch/mvme88k/dev/vsvar.h132
-rw-r--r--sys/arch/mvme88k/dev/vx.c1691
-rw-r--r--sys/arch/mvme88k/dev/vxreg.h530
-rw-r--r--sys/arch/mvme88k/include/board.h82
-rw-r--r--sys/arch/mvme88k/include/exec.h12
-rw-r--r--sys/arch/mvme88k/include/param.h6
-rw-r--r--sys/arch/mvme88k/include/pmap.h8
-rw-r--r--sys/arch/mvme88k/include/proc.h6
-rw-r--r--sys/arch/mvme88k/include/prom.h30
-rw-r--r--sys/arch/mvme88k/mvme88k/autoconf.c8
-rw-r--r--sys/arch/mvme88k/mvme88k/conf.c34
-rw-r--r--sys/arch/mvme88k/mvme88k/eh.S12
-rw-r--r--sys/arch/mvme88k/mvme88k/locore.S7
-rw-r--r--sys/arch/mvme88k/mvme88k/machdep.c57
-rw-r--r--sys/arch/mvme88k/mvme88k/pmap.c155
-rw-r--r--sys/arch/mvme88k/mvme88k/process_machdep.c20
-rw-r--r--sys/arch/mvme88k/mvme88k/trap.c270
-rw-r--r--sys/arch/mvme88k/mvme88k/vm_machdep.c57
-rw-r--r--sys/arch/mvme88k/stand/bootsd/Makefile8
-rw-r--r--sys/arch/mvme88k/stand/bootst/Makefile7
-rw-r--r--sys/arch/mvme88k/stand/bootxx/Makefile4
-rw-r--r--sys/arch/mvme88k/stand/netboot/Makefile4
-rw-r--r--sys/arch/mvme88k/stand/netboot/config.h4
42 files changed, 6559 insertions, 441 deletions
diff --git a/sys/arch/mvme88k/conf/GENERIC b/sys/arch/mvme88k/conf/GENERIC
index 51b4d91c961..bccdcd6a65f 100644
--- a/sys/arch/mvme88k/conf/GENERIC
+++ b/sys/arch/mvme88k/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.7 1998/12/15 06:02:54 smurph Exp $
+# $OpenBSD: GENERIC,v 1.8 1999/05/29 04:41:42 smurph Exp $
machine mvme88k
@@ -17,7 +17,7 @@ config bsd swap generic
mainbus0 at root
# ------------------------------ mainbus devices ------------------------
#bugtty0 at mainbus0
-sram0 at mainbus0 addr 0xffe00000
+#sram0 at mainbus0 addr 0xffe00000
pcctwo0 at mainbus0 addr 0xfff00000
# ------------------------------ pcctwo devices -------------------------
clock0 at pcctwo0 ipl 5
diff --git a/sys/arch/mvme88k/conf/RAMDISK b/sys/arch/mvme88k/conf/RAMDISK
index f51ea7ed1b0..21f811f6bf8 100644
--- a/sys/arch/mvme88k/conf/RAMDISK
+++ b/sys/arch/mvme88k/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.1 1998/12/15 06:02:55 smurph Exp $
+# $OpenBSD: RAMDISK,v 1.2 1999/05/29 04:41:42 smurph Exp $
machine mvme88k
@@ -17,7 +17,7 @@ config bsd root rd0 swap rd0
mainbus0 at root
# ------------------------------ mainbus devices ------------------------
#bugtty0 at mainbus0
-sram0 at mainbus0 addr 0xffe00000
+#sram0 at mainbus0 addr 0xffe00000
pcctwo0 at mainbus0 addr 0xfff00000
# ------------------------------ pcctwo devices -------------------------
clock0 at pcctwo0 ipl 5
diff --git a/sys/arch/mvme88k/conf/files.mvme88k b/sys/arch/mvme88k/conf/files.mvme88k
index 22cd80f2a4a..b739f0f14cd 100644
--- a/sys/arch/mvme88k/conf/files.mvme88k
+++ b/sys/arch/mvme88k/conf/files.mvme88k
@@ -1,4 +1,4 @@
-# $OpenBSD: files.mvme88k,v 1.3 1999/02/09 06:36:24 smurph Exp $
+# $OpenBSD: files.mvme88k,v 1.4 1999/05/29 04:41:42 smurph Exp $
#
maxpartitions 16
@@ -104,3 +104,16 @@ device ie: ifnet, ether
attach ie at pcctwo: ifnet, ether
file arch/mvme88k/dev/if_ie.c ie
+device ve: ether, ifnet, ifmedia
+attach ve at vmes
+file arch/mvme88k/dev/if_ve.c ve
+
+device vx: tty
+attach vx at vmes
+file arch/mvme88k/dev/vx.c vx needs-count
+
+device vs: scsi
+attach vs at vmes
+file arch/mvme88k/dev/vs.c vs
+file arch/mvme88k/dev/vsdma.c vs
+
diff --git a/sys/arch/mvme88k/dev/bugio.c b/sys/arch/mvme88k/dev/bugio.c
index be68ef99c17..3a3d085dd5e 100644
--- a/sys/arch/mvme88k/dev/bugio.c
+++ b/sys/arch/mvme88k/dev/bugio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bugio.c,v 1.2 1998/12/15 05:52:29 smurph Exp $ */
+/* $OpenBSD: bugio.c,v 1.3 1999/05/29 04:41:42 smurph Exp $ */
/* Copyright (c) 1998 Steve Murphree, Jr. */
#include <machine/bugio.h>
@@ -10,6 +10,7 @@
#define DSKRD "0x0010"
#define DSKWR "0x0011"
#define DSKCFIG "0x0012"
+#define NETCFG "0x001A"
#define NETCTRL "0x001D"
#define OUTCHR "0x0020"
#define OUTSTR "0x0021"
@@ -156,6 +157,15 @@ bugrtcrd(struct bugrtc *rtc)
OSCTXT();
}
+bugdelay(int delay)
+{
+ BUGCTXT();
+ asm("or r2,r0,%0" : : "r" (delay));
+ asm("or r9,r0, " DELAY);
+ asm("tb0 0,r0,0x1F0");
+ OSCTXT();
+}
+
bugreturn(void)
{
BUGCTXT();
@@ -183,3 +193,47 @@ bugnetctrl(struct bugniocall *niocall)
asm("tb0 0,r0,0x1F0");
/* OSCTXT();*/
}
+
+typedef struct netcnfgp {
+ unsigned int magic;
+ unsigned int nodemem;
+ unsigned int bfla;
+ unsigned int bfea;
+ unsigned int bfed;
+ unsigned int bfl;
+ unsigned int bfbo;
+ unsigned int tbuffer;
+ unsigned char cipa[4];
+ unsigned char sipa[4];
+ unsigned char netmask[4];
+ unsigned char broadcast[4];
+ unsigned char gipa[4];
+ unsigned char bootp_retry;
+ unsigned char tftp_retry;
+ unsigned char bootp_ctl;
+ unsigned char cnfgp_ctl;
+ unsigned char filename[64];
+ unsigned char argfname[64];
+} NETCNFGP;
+
+struct bugniotcall {
+ unsigned char clun;
+ unsigned char dlun;
+ unsigned char ci;
+ unsigned char cd;
+ NETCNFGP * netcfngp_p;
+ void * unused;
+#define NIOT_READ (1<<0)
+#define NIOT_WRITE (1<<1)
+#define NIOT_NVRAM (1<<2)
+ unsigned long cntrlflag;
+};
+
+bugnetcfg(struct bugniotcall *niotcall)
+{
+/* BUGCTXT();*/
+ asm("or r2,r0,%0" : : "r" (niotcall));
+ asm("or r9,r0, " NETCTRL);
+ asm("tb0 0,r0,0x1F0");
+/* OSCTXT();*/
+}
diff --git a/sys/arch/mvme88k/dev/cl.c b/sys/arch/mvme88k/dev/cl.c
index e568e853b99..6e738b5a4fa 100644
--- a/sys/arch/mvme88k/dev/cl.c
+++ b/sys/arch/mvme88k/dev/cl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cl.c,v 1.3 1999/01/11 05:11:42 millert Exp $ */
+/* $OpenBSD: cl.c,v 1.4 1999/05/29 04:41:43 smurph Exp $ */
/*
* Copyright (c) 1995 Dale Rahn. All rights reserved.
@@ -42,34 +42,16 @@
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/device.h>
-/* #include <sys/queue.h> */
#include <machine/cpu.h>
#include <machine/autoconf.h>
#include <dev/cons.h>
-#if defined(MVME187)
#include <mvme88k/dev/clreg.h>
-#else
-#include <mvme68k/dev/clreg.h>
-#endif
#include <sys/syslog.h>
#include "cl.h"
-
#include "pcctwo.h"
-
-#if NPCCTWO > 0
-#if defined(MVME187)
#include <mvme88k/dev/pcctworeg.h>
-#else
-#include <mvme68k/dev/pcctworeg.h>
-#endif
-#endif
-
-#if defined(MVME187)
#include <machine/psl.h>
#define splcl() splx(IPL_TTY)
-#else
-#define splcl() spl3()
-#endif
/* min timeout 0xa, what is a good value */
#define CL_TIMEOUT 0x10
@@ -234,7 +216,8 @@ struct tty * cltty(dev)
return sc->sc_cl[channel].tty;
}
-int clprobe(parent, self, aux)
+int
+clprobe(parent, self, aux)
struct device *parent;
void *self;
void *aux;
@@ -277,14 +260,14 @@ clattach(parent, self, aux)
if ((u_char *)ca->ca_paddr == (u_char *)cl_cons.cl_paddr) {
/* if this device is configured as console,
* line cl_cons.channel is the console */
- sc->sc_cl[cl_cons.channel].cl_consio = 1;
- printf(" console");
+ sc->sc_cl[0].cl_consio = 1;
+ printf(" console ");
} else {
/* reset chip only if we are not console device */
/* wait for GFRCR */
}
/* allow chip to settle before continuing */
- delay(100);
+ delay(800);
/* set up global registers */
sc->cl_reg->cl_tpr = CL_TIMEOUT;
@@ -357,25 +340,18 @@ clattach(parent, self, aux)
sc->sc_ih_r.ih_arg = sc;
sc->sc_ih_r.ih_ipl = ca->ca_ipl;
sc->sc_ih_r.ih_wantframe = 0;
- switch (ca->ca_bustype) {
- case BUS_PCCTWO:
- dopoll = 0;
- intr_establish(PCC2_VECT + SRXEIRQ, &sc->sc_ih_e);
- intr_establish(PCC2_VECT + SMOIRQ, &sc->sc_ih_m);
- intr_establish(PCC2_VECT + STxIRQ, &sc->sc_ih_t);
- intr_establish(PCC2_VECT + SRxIRQ, &sc->sc_ih_r);
- sc->sc_pcctwo = ca->ca_master;
- sc->sc_pcctwo->pcc2_sccerr = 0x01; /* clear errors */
-
- /* enable all interrupts at ca_ipl */
- sc->sc_pcctwo->pcc2_sccirq = 0x10 | (ca->ca_ipl & 0x7);
- sc->sc_pcctwo->pcc2_scctx = 0x10 | (ca->ca_ipl & 0x7);
- sc->sc_pcctwo->pcc2_sccrx = 0x10 | (ca->ca_ipl & 0x7);
- break;
- default:
- /* oops */
- panic ("cl driver on unknown bus");
- }
+ dopoll = 0;
+ intr_establish(PCC2_VECT + SRXEIRQ, &sc->sc_ih_e);
+ intr_establish(PCC2_VECT + SMOIRQ, &sc->sc_ih_m);
+ intr_establish(PCC2_VECT + STxIRQ, &sc->sc_ih_t);
+ intr_establish(PCC2_VECT + SRxIRQ, &sc->sc_ih_r);
+ sc->sc_pcctwo = ca->ca_master;
+ sc->sc_pcctwo->pcc2_sccerr = 0x01; /* clear errors */
+
+ /* enable all interrupts at ca_ipl */
+ sc->sc_pcctwo->pcc2_sccirq = 0x10 | (ca->ca_ipl & 0x7);
+ sc->sc_pcctwo->pcc2_scctx = 0x10 | (ca->ca_ipl & 0x7);
+ sc->sc_pcctwo->pcc2_sccrx = 0x10 | (ca->ca_ipl & 0x7);
evcnt_attach(&sc->sc_dev, "intr", &sc->sc_txintrcnt);
evcnt_attach(&sc->sc_dev, "intr", &sc->sc_rxintrcnt);
diff --git a/sys/arch/mvme88k/dev/clock.c b/sys/arch/mvme88k/dev/clock.c
index 3535f83d231..80a022fc263 100644
--- a/sys/arch/mvme88k/dev/clock.c
+++ b/sys/arch/mvme88k/dev/clock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clock.c,v 1.4 1998/12/15 05:52:29 smurph Exp $ */
+/* $OpenBSD: clock.c,v 1.5 1999/05/29 04:41:43 smurph Exp $ */
/*
* Copyright (c) 1995 Theo de Raadt
@@ -89,10 +89,13 @@
#include <machine/psl.h>
#include <machine/autoconf.h>
+#include <machine/bugio.h>
#include <machine/cpu.h>
#include <mvme88k/dev/pcctworeg.h>
+#include <mvme88k/dev/vme.h>
#include "pcctwo.h"
+extern struct vme2reg *sys_vme2;
/*
* Statistics clock interval and variance, in usec. Variance must be a
@@ -104,7 +107,7 @@
*/
int statvar = 8192;
int statmin; /* statclock interval - 1/2*variance */
-int timerok;
+int timerok = 0;
u_long delay_factor = 1;
@@ -203,6 +206,7 @@ clockintr(arg)
#if NBUGTTY > 0
bugtty_chkinput();
#endif /* NBUGTTY */
+ timerok = 1;
return (1);
}
@@ -287,18 +291,30 @@ statintr(cap)
return (1);
}
+
delay(us)
register int us;
{
volatile register int c;
-
+ unsigned long st;
/*
- * XXX MVME167 doesn't have a 3rd free-running timer,
- * so we use a stupid loop. Fix the code to watch t1:
- * the profiling timer.
+ * We use the vme system controller for the delay clock.
+ * Do not go to the real timer until vme device is present
*/
- c = 4 * us;
- while (--c > 0)
- ;
- return (0);
+ if (sys_vme2 == NULL) {
+ c = 5 * us;
+ while (--c > 0);
+ return(0);
+ }
+ sys_vme2->vme2_irql1 |= (0 << VME2_IRQL1_TIC1SHIFT);
+ sys_vme2->vme2_t1count = 0;
+ sys_vme2->vme2_tctl |= (VME2_TCTL1_CEN | VME2_TCTL1_COVF);
+
+ while (sys_vme2->vme2_t1count < us)
+ ;
+ sys_vme2->vme2_tctl &= ~(VME2_TCTL1_CEN | VME2_TCTL1_COVF);
+ return (0);
}
+
+
+
diff --git a/sys/arch/mvme88k/dev/if_ie.c b/sys/arch/mvme88k/dev/if_ie.c
index d3a5127976e..e8041125a1c 100644
--- a/sys/arch/mvme88k/dev/if_ie.c
+++ b/sys/arch/mvme88k/dev/if_ie.c
@@ -1,4 +1,4 @@
-/* $Id: if_ie.c,v 1.4 1999/03/03 22:10:32 jason Exp $ */
+/* $Id: if_ie.c,v 1.5 1999/05/29 04:41:43 smurph Exp $ */
/*-
* Copyright (c) 1998 Steve Murphree, Jr.
@@ -139,23 +139,8 @@ Mode of operation:
#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <machine/pmap.h>
-
-#if !defined(MVME187)
-#include "mc.h"
-#endif
#include "pcctwo.h"
-
-#if NMC > 0
-#include <mvme68k/dev/mcreg.h>
-#endif
-#if NPCCTWO > 0
-#if defined(MVME187)
#include <mvme88k/dev/pcctworeg.h>
-#else
-#include <mvme68k/dev/pcctworeg.h>
-#endif
-#endif
-
#include <mvme88k/dev/if_ie.h>
#include <mvme88k/dev/i82586.h>
#include <machine/board.h>
@@ -285,12 +270,7 @@ struct ie_softc {
#ifdef IEDEBUG
int sc_debug;
#endif
-#if NMC > 0
- struct mcreg *sc_mc;
-#endif
-#if NPCCTWO > 0
struct pcctworeg *sc_pcc2;
-#endif
};
static void ie_obreset __P((struct ie_softc *));
@@ -391,7 +371,6 @@ iematch(parent, vcf, args)
int ret;
if ((ret = badvaddr(IIOV(ca->ca_vaddr), 1)) <=0){
- printf("==> ie: failed address check returning %ld.\n", ret);
return(0);
}
return (1);
@@ -462,14 +441,16 @@ ieattach(parent, self, aux)
sc->sc_msize = etherlen;
sc->sc_reg = ca->ca_vaddr;
ieo = (volatile struct ieob *) sc->sc_reg;
-
- /* Are we the boot device? */
- if (ca->ca_paddr == bootaddr)
- bootdv = self;
-
+
+ /* Are we the boot device? */
+ if (ca->ca_paddr == bootaddr)
+ bootdv = self;
+
+ /* get the first avaliable etherbuf */
sc->sc_maddr = etherbuf; /* maddr = vaddr */
+ if (sc->sc_maddr == NULL) panic("ie: too many ethernet boards");
pa = pmap_extract(pmap_kernel(), (vm_offset_t)sc->sc_maddr);
- if (pa == 0) panic("ie pmap_extract");
+ if (pa == 0) panic("ie: pmap_extract");
sc->sc_iobase = (caddr_t)pa; /* iobase = paddr (24 bit) */
/*printf("maddrP %x iobaseV %x\n", sc->sc_maddr, sc->sc_iobase);*/
@@ -531,29 +512,13 @@ ieattach(parent, self, aux)
sc->sc_failih.ih_arg = sc;
sc->sc_failih.ih_ipl = pri;
- switch (sc->sc_bustype) {
-#if NMC > 0
- case BUS_MC:
- mcintr_establish(MCV_IE, &sc->sc_ih);
- sc->sc_mc = (struct mcreg *)ca->ca_master;
- sc->sc_mc->mc_ieirq = pri | MC_SC_SNOOP | MC_IRQ_IEN |
- MC_IRQ_ICLR;
- mcintr_establish(MCV_IEFAIL, &sc->sc_failih);
- sc->sc_mc->mc_iefailirq = pri | MC_IRQ_IEN | MC_IRQ_ICLR;
- break;
-#endif
-#if NPCCTWO > 0
- case BUS_PCCTWO:
- pcctwointr_establish(PCC2V_IE, &sc->sc_ih);
- sc->sc_pcc2 = (struct pcctworeg *)ca->ca_master;
- sc->sc_pcc2->pcc2_ieirq = pri | PCC2_SC_SNOOP |
- PCC2_IRQ_IEN | PCC2_IRQ_ICLR;
- pcctwointr_establish(PCC2V_IEFAIL, &sc->sc_failih);
- sc->sc_pcc2->pcc2_iefailirq = pri | PCC2_IRQ_IEN |
- PCC2_IRQ_ICLR;
- break;
-#endif
- }
+ pcctwointr_establish(PCC2V_IE, &sc->sc_ih);
+ sc->sc_pcc2 = (struct pcctworeg *)ca->ca_master;
+ sc->sc_pcc2->pcc2_ieirq = pri | PCC2_SC_SNOOP |
+ PCC2_IRQ_IEN | PCC2_IRQ_ICLR;
+ pcctwointr_establish(PCC2V_IEFAIL, &sc->sc_failih);
+ sc->sc_pcc2->pcc2_iefailirq = pri | PCC2_IRQ_IEN |
+ PCC2_IRQ_ICLR;
evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt);
}
@@ -580,22 +545,9 @@ void *v;
{
struct ie_softc *sc = v;
- switch (sc->sc_bustype) {
-#if NMC > 0
- case BUS_MC:
- sc->sc_mc->mc_ieirq |= MC_IRQ_ICLR; /* safe: clear irq */
- sc->sc_mc->mc_iefailirq |= MC_IRQ_ICLR; /* clear failure */
- sc->sc_mc->mc_ieerr = MC_IEERR_SCLR; /* reset error */
- break;
-#endif
-#if NPCCTWO > 0
- case BUS_PCCTWO:
- sc->sc_pcc2->pcc2_ieirq |= PCC2_IRQ_ICLR; /* safe: clear irq */
- sc->sc_pcc2->pcc2_iefailirq |= PCC2_IRQ_ICLR; /* clear failure */
- sc->sc_pcc2->pcc2_ieerr = PCC2_IEERR_SCLR; /* reset error */
- break;
-#endif
- }
+ sc->sc_pcc2->pcc2_ieirq |= PCC2_IRQ_ICLR; /* safe: clear irq */
+ sc->sc_pcc2->pcc2_iefailirq |= PCC2_IRQ_ICLR; /* clear failure */
+ sc->sc_pcc2->pcc2_ieerr = PCC2_IEERR_SCLR; /* reset error */
iereset(sc);
return (1);
@@ -617,18 +569,7 @@ void *v;
loop:
/* Ack interrupts FIRST in case we receive more during the ISR. */
ie_ack(sc, IE_ST_WHENCE & status);
- switch (sc->sc_bustype) {
-#if NMC > 0
- case BUS_MC:
- sc->sc_mc->mc_ieirq |= MC_IRQ_ICLR; /* clear irq */
- break;
-#endif
-#if NPCCTWO > 0
- case BUS_PCCTWO:
- sc->sc_pcc2->pcc2_ieirq |= PCC2_IRQ_ICLR; /* clear irq */
- break;
-#endif
- }
+ sc->sc_pcc2->pcc2_ieirq |= PCC2_IRQ_ICLR; /* clear irq */
if (status & (IE_ST_RECV | IE_ST_RNR)) {
#ifdef IEDEBUG
diff --git a/sys/arch/mvme88k/dev/if_ve.c b/sys/arch/mvme88k/dev/if_ve.c
new file mode 100644
index 00000000000..502be8e6143
--- /dev/null
+++ b/sys/arch/mvme88k/dev/if_ve.c
@@ -0,0 +1,1345 @@
+/* $OpenBSD: if_ve.c,v 1.1 1999/05/29 04:41:43 smurph Exp $ */
+/*-
+ * Copyright (c) 1999 Steve Murphree, Jr.
+ * Copyright (c) 1982, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. 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_ve.c - Motorola MVME376 vme bus ethernet driver. Based on if_le.c */
+
+#include "bpfilter.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/syslog.h>
+#include <sys/socket.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#endif
+
+#include <net/if_media.h>
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#include <net/bpfdesc.h>
+#endif
+
+#include <vm/vm.h>
+#include <vm/vm_map.h>
+#include <vm/vm_kern.h>
+
+#include <machine/autoconf.h>
+#include <machine/cpu.h>
+#include <machine/bugio.h>
+
+#include <mvme88k/dev/if_vereg.h>
+#include <mvme88k/dev/if_vevar.h>
+#include <mvme88k/dev/pcctworeg.h>
+#include <mvme88k/dev/vme.h>
+
+#define LEDEBUG 1
+
+
+#ifdef LEDEBUG
+void ve_recv_print __P((struct vam7990_softc *, int));
+void ve_xmit_print __P((struct vam7990_softc *, int));
+#endif
+
+integrate void ve_rint __P((struct vam7990_softc *));
+integrate void ve_tint __P((struct vam7990_softc *));
+
+integrate int ve_put __P((struct vam7990_softc *, int, struct mbuf *));
+integrate struct mbuf *ve_get __P((struct vam7990_softc *, int, int));
+integrate void ve_read __P((struct vam7990_softc *, int, int));
+
+hide void ve_shutdown __P((void *));
+
+#define ifp (&sc->sc_arpcom.ac_if)
+#ifndef ETHER_CMP
+#define ETHER_CMP(a, b) bcmp((a), (b), ETHER_ADDR_LEN)
+#endif
+#define LANCE_REVC_BUG 1
+/*
+ * Ethernet software status per interface.
+ *
+ * Each interface is referenced by a network interface structure,
+ * arpcom.ac_if, which the routing code uses to locate the interface.
+ * This structure contains the output queue for the interface, its address, ...
+ */
+struct ve_softc {
+ struct vam7990_softc sc_am7990; /* glue to MI code */
+ struct intrhand sc_ih; /* interrupt vectoring */
+ struct vereg1 *sc_r1; /* LANCE registers */
+ u_short csr; /* Control/Status reg image */
+ u_long board_addr;
+ struct evcnt sc_intrcnt;
+ struct evcnt sc_errcnt;
+ struct vme2reg *sc_vme2;
+ u_char sc_ipl;
+ u_char sc_vec;
+ int sc_flags;
+};
+
+struct cfdriver ve_cd = {
+ NULL, "ve", DV_IFNET
+};
+
+
+/* autoconfiguration driver */
+void veattach(struct device *, struct device *, void *);
+int vematch(struct device *, void *, void *);
+void veetheraddr(struct vam7990_softc *sc);
+
+struct cfattach ve_ca = {
+ sizeof(struct ve_softc), vematch, veattach
+};
+
+hide void vewrcsr __P((struct vam7990_softc *, u_int16_t, u_int16_t));
+hide u_int16_t verdcsr __P((struct vam7990_softc *, u_int16_t));
+
+/* send command to the nvram controller */
+nvram_cmd(sc, cmd, addr )
+struct vam7990_softc *sc;
+u_char cmd;
+u_short addr;
+{
+ int i;
+ u_char rcmd = 0;
+ u_char rcmd2= 0;
+ struct vereg1 *reg1 = ((struct ve_softc *)sc)->sc_r1;
+
+ rcmd = addr;
+ rcmd = rcmd << 3;
+ rcmd |= cmd;
+ for(i=0;i<8;i++){
+ reg1->ver1_ear=((cmd|(addr<<1))>>i);
+ CDELAY;
+ }
+}
+
+/* read nvram one bit at a time */
+u_int16_t
+nvram_read(sc, nvram_addr)
+struct vam7990_softc *sc;
+u_char nvram_addr;
+{
+ u_short val = 0, mask = 0x04000;
+ u_int16_t wbit;
+ /* these used by macros DO NOT CHANGE!*/
+ int i;
+ struct vereg1 *reg1 = ((struct ve_softc *)sc)->sc_r1;
+ sc->csr = 0x4f;
+ ENABLE_NVRAM;
+ nvram_cmd(sc, NVRAM_RCL, 0);
+ DISABLE_NVRAM;
+ CDELAY;
+ ENABLE_NVRAM;
+ nvram_cmd(sc, NVRAM_READ, nvram_addr);
+ for (wbit=0; wbit<15; wbit++) {
+ (reg1->ver1_ear & 0x01) ? (val = (val | mask)) : (val = (val & (~mask)));
+ mask = mask>>1;
+ CDELAY;
+ }
+ (reg1->ver1_ear & 0x01) ? (val = (val | 0x8000)) : (val = (val & 0x7FFF));
+ CDELAY;
+ DISABLE_NVRAM;
+ return (val);
+}
+
+hide void
+vewrcsr(sc, port, val)
+ struct vam7990_softc *sc;
+ u_int16_t port, val;
+{
+ register struct vereg1 *ve1 = ((struct ve_softc *)sc)->sc_r1;
+
+ ve1->ver1_rap = port;
+ ve1->ver1_rdp = val;
+}
+
+hide u_int16_t
+verdcsr(sc, port)
+ struct vam7990_softc *sc;
+ u_int16_t port;
+{
+ register struct vereg1 *ve1 = ((struct ve_softc *)sc)->sc_r1;
+ u_int16_t val;
+
+ ve1->ver1_rap = port;
+ val = ve1->ver1_rdp;
+ return (val);
+}
+
+/* reset MVME376, set ipl and vec */
+void
+vereset(sc)
+ struct vam7990_softc *sc;
+{
+ register struct vereg1 *reg1 = ((struct ve_softc *)sc)->sc_r1;
+ u_char vec = ((struct ve_softc *)sc)->sc_vec;
+ u_char ipl = ((struct ve_softc *)sc)->sc_ipl;
+ sc->csr = 0x4f;
+ WRITE_CSR_AND( ~ipl );
+ SET_VEC(vec);
+ return;
+}
+
+/* ack the intrrupt by reenableling interrupts */
+void
+ve_ackint(sc)
+struct vam7990_softc *sc;
+{
+ register struct vereg1 *reg1 = ((struct ve_softc *)sc)->sc_r1;
+ ENABLE_INTR;
+}
+
+int
+vematch(parent, vcf, args)
+ struct device *parent;
+ void *vcf, *args;
+{
+
+ struct confargs *ca = args;
+ if (!badvaddr(ca->ca_vaddr, 1)) {
+ if (ca->ca_vec & 0x03) {
+ printf("ve: bad vector 0x%x\n", ca->ca_vec);
+ return (0);
+ }
+ return(1);
+ } else {
+ 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
+veattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ register struct ve_softc *lesc = (struct ve_softc *)self;
+ struct vam7990_softc *sc = &lesc->sc_am7990;
+ struct confargs *ca = aux;
+ register int a;
+ int pri = ca->ca_ipl;
+ caddr_t addr;
+
+ char *cp;
+ int i, ipl;
+
+ addr = ca->ca_vaddr;
+
+ if (addr == 0) {
+ printf("\n%s: can't map LANCE registers\n",
+ sc->sc_dev.dv_xname);
+ return;
+ }
+
+ /* Are we the boot device? */
+ if (ca->ca_paddr == bootaddr)
+ bootdv = self;
+
+ lesc->sc_r1 = (struct vereg1 *)ca->ca_vaddr;
+ lesc->sc_ipl = ca->ca_ipl;
+ lesc->sc_vec = ca->ca_vec;
+
+ /* get the first avaliable etherbuf */
+ switch ((int)ca->ca_paddr) {
+ case 0xFFFF1200:
+ addr = (caddr_t)0xFD6C0000;
+ break;
+ case 0xFFFF1400:
+ addr = (caddr_t)0xFD700000;
+ break;
+ case 0xFFFF1600:
+ addr = (caddr_t)0xFD740000;
+ break;
+ default:
+ panic("ve: invalid address");
+ }
+ sc->sc_mem = (void *)mapiodev(addr, LEMEMSIZE);
+ if (sc->sc_mem == NULL) panic("ve: no more memory in external I/O map");
+ sc->sc_memsize = LEMEMSIZE;
+ sc->sc_conf3 = LE_C3_BSWP;
+ sc->sc_addr = kvtop(sc->sc_mem);
+
+ /* get ether address via bug call */
+ veetheraddr(sc);
+
+ evcnt_attach(&sc->sc_dev, "intr", &lesc->sc_intrcnt);
+ evcnt_attach(&sc->sc_dev, "errs", &lesc->sc_errcnt);
+
+ sc->sc_copytodesc = ve_copytobuf_contig;
+ sc->sc_copyfromdesc = ve_copyfrombuf_contig;
+ sc->sc_copytobuf = ve_copytobuf_contig;
+ sc->sc_copyfrombuf = ve_copyfrombuf_contig;
+ sc->sc_zerobuf = ve_zerobuf_contig;
+
+ sc->sc_rdcsr = verdcsr;
+ sc->sc_wrcsr = vewrcsr;
+ sc->sc_hwreset = vereset;
+ sc->sc_hwinit = NULL;
+ vereset(sc);
+
+ ve_config(sc);
+
+ /* connect the interrupt */
+ lesc->sc_ih.ih_fn = ve_intr;
+ lesc->sc_ih.ih_arg = sc;
+ lesc->sc_ih.ih_ipl = pri;
+ vmeintr_establish(ca->ca_vec + 0, &lesc->sc_ih);
+}
+
+void
+veetheraddr(sc)
+struct vam7990_softc *sc;
+{
+ u_char * cp = sc->sc_arpcom.ac_enaddr;
+ u_int16_t ival[3];
+ u_char i;
+
+ for (i=0; i<3; i++) {
+ ival[i] = nvram_read(sc, i);
+ }
+ memcpy(cp, &ival[0], 6);
+}
+
+void
+ve_config(sc)
+ struct vam7990_softc *sc;
+{
+ int mem;
+
+ /* Make sure the chip is stopped. */
+ ve_stop(sc);
+
+ /* Initialize ifnet structure. */
+ bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
+ ifp->if_softc = sc;
+ ifp->if_start = ve_start;
+ ifp->if_ioctl = ve_ioctl;
+ ifp->if_watchdog = ve_watchdog;
+ ifp->if_flags =
+ IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
+#ifdef LANCE_REVC_BUG
+ ifp->if_flags &= ~IFF_MULTICAST;
+#endif
+
+ /* Attach the interface. */
+ if_attach(ifp);
+ ether_ifattach(ifp);
+
+#if NBPFILTER > 0
+ bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
+#endif
+
+ if (sc->sc_memsize > 262144)
+ sc->sc_memsize = 262144;
+
+ switch (sc->sc_memsize) {
+ case 8192:
+ sc->sc_nrbuf = 4;
+ sc->sc_ntbuf = 1;
+ break;
+ case 16384:
+ sc->sc_nrbuf = 8;
+ sc->sc_ntbuf = 2;
+ break;
+ case 32768:
+ sc->sc_nrbuf = 16;
+ sc->sc_ntbuf = 4;
+ break;
+ case 65536:
+ sc->sc_nrbuf = 32;
+ sc->sc_ntbuf = 8;
+ break;
+ case 131072:
+ sc->sc_nrbuf = 64;
+ sc->sc_ntbuf = 16;
+ break;
+ case 262144:
+ sc->sc_nrbuf = 128;
+ sc->sc_ntbuf = 32;
+ break;
+ default:
+ panic("ve_config: weird memory size %d", sc->sc_memsize);
+ }
+
+ printf("\n%s: address %s\n", sc->sc_dev.dv_xname,
+ ether_sprintf(sc->sc_arpcom.ac_enaddr));
+ printf("%s: %d receive buffers, %d transmit buffers\n",
+ sc->sc_dev.dv_xname, sc->sc_nrbuf, sc->sc_ntbuf);
+
+ sc->sc_sh = shutdownhook_establish(ve_shutdown, sc);
+ if (sc->sc_sh == NULL)
+ panic("ve_config: can't establish shutdownhook");
+
+ mem = 0;
+ sc->sc_initaddr = mem;
+ mem += sizeof(struct veinit);
+ sc->sc_rmdaddr = mem;
+ mem += sizeof(struct vermd) * sc->sc_nrbuf;
+ sc->sc_tmdaddr = mem;
+ mem += sizeof(struct vetmd) * sc->sc_ntbuf;
+ sc->sc_rbufaddr = mem;
+ mem += LEBLEN * sc->sc_nrbuf;
+ sc->sc_tbufaddr = mem;
+ mem += LEBLEN * sc->sc_ntbuf;
+#ifdef notyet
+ if (mem > ...)
+ panic(...);
+#endif
+}
+
+void
+ve_reset(sc)
+ struct vam7990_softc *sc;
+{
+ int s;
+
+ s = splimp();
+ ve_init(sc);
+ splx(s);
+}
+
+/*
+ * Set up the initialization block and the descriptor rings.
+ */
+void
+ve_meminit(sc)
+ register struct vam7990_softc *sc;
+{
+ u_long a;
+ int bix;
+ struct veinit init;
+ struct vermd rmd;
+ struct vetmd tmd;
+
+#if NBPFILTER > 0
+ if (ifp->if_flags & IFF_PROMISC)
+ init.init_mode = LE_MODE_NORMAL | LE_MODE_PROM;
+ else
+#endif
+ init.init_mode = LE_MODE_NORMAL;
+ init.init_padr[0] =
+ (sc->sc_arpcom.ac_enaddr[1] << 8) | sc->sc_arpcom.ac_enaddr[0];
+ init.init_padr[1] =
+ (sc->sc_arpcom.ac_enaddr[3] << 8) | sc->sc_arpcom.ac_enaddr[2];
+ init.init_padr[2] =
+ (sc->sc_arpcom.ac_enaddr[5] << 8) | sc->sc_arpcom.ac_enaddr[4];
+ ve_setladrf(&sc->sc_arpcom, init.init_ladrf);
+
+ sc->sc_last_rd = 0;
+ sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0;
+
+ a = sc->sc_addr + LE_RMDADDR(sc, 0);
+ init.init_rdra = a;
+ init.init_rlen = (a >> 16) | ((ffs(sc->sc_nrbuf) - 1) << 13);
+
+ a = sc->sc_addr + LE_TMDADDR(sc, 0);
+ init.init_tdra = a;
+ init.init_tlen = (a >> 16) | ((ffs(sc->sc_ntbuf) - 1) << 13);
+
+ (*sc->sc_copytodesc)(sc, &init, LE_INITADDR(sc), sizeof(init));
+
+ /*
+ * Set up receive ring descriptors.
+ */
+ for (bix = 0; bix < sc->sc_nrbuf; bix++) {
+ a = sc->sc_addr + LE_RBUFADDR(sc, bix);
+ rmd.rmd0 = a;
+ rmd.rmd1_hadr = a >> 16;
+ rmd.rmd1_bits = LE_R1_OWN;
+ rmd.rmd2 = -LEBLEN | LE_XMD2_ONES;
+ rmd.rmd3 = 0;
+ (*sc->sc_copytodesc)(sc, &rmd, LE_RMDADDR(sc, bix),
+ sizeof(rmd));
+ }
+
+ /*
+ * Set up transmit ring descriptors.
+ */
+ for (bix = 0; bix < sc->sc_ntbuf; bix++) {
+ a = sc->sc_addr + LE_TBUFADDR(sc, bix);
+ tmd.tmd0 = a;
+ tmd.tmd1_hadr = a >> 16;
+ tmd.tmd1_bits = 0;
+ tmd.tmd2 = 0 | LE_XMD2_ONES;
+ tmd.tmd3 = 0;
+ (*sc->sc_copytodesc)(sc, &tmd, LE_TMDADDR(sc, bix),
+ sizeof(tmd));
+ }
+}
+
+void
+ve_stop(sc)
+ struct vam7990_softc *sc;
+{
+
+ (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_STOP);
+}
+
+/*
+ * Initialization of interface; set up initialization block
+ * and transmit/receive descriptor rings.
+ */
+void
+ve_init(sc)
+ register struct vam7990_softc *sc;
+{
+ register int timo;
+ u_long a;
+
+ (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_STOP);
+ DELAY(100);
+
+ /* Newer LANCE chips have a reset register */
+ if (sc->sc_hwreset)
+ (*sc->sc_hwreset)(sc);
+
+ /* Set the correct byte swapping mode, etc. */
+ (*sc->sc_wrcsr)(sc, LE_CSR3, sc->sc_conf3);
+
+ /* Set up LANCE init block. */
+ ve_meminit(sc);
+
+ /* Give LANCE the physical address of its init block. */
+ a = sc->sc_addr + LE_INITADDR(sc);
+ (*sc->sc_wrcsr)(sc, LE_CSR1, a);
+ (*sc->sc_wrcsr)(sc, LE_CSR2, a >> 16);
+
+ /* Try to initialize the LANCE. */
+ DELAY(100);
+ (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INIT);
+
+ /* Wait for initialization to finish. */
+ for (timo = 100000; timo; timo--)
+ if ((*sc->sc_rdcsr)(sc, LE_CSR0) & LE_C0_IDON)
+ break;
+
+ if ((*sc->sc_rdcsr)(sc, LE_CSR0) & LE_C0_IDON) {
+ /* Start the LANCE. */
+ (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_STRT |
+ LE_C0_IDON);
+ ifp->if_flags |= IFF_RUNNING;
+ ifp->if_flags &= ~IFF_OACTIVE;
+ ifp->if_timer = 0;
+ ve_start(ifp);
+ } else
+ printf("%s: controller failed to initialize\n", sc->sc_dev.dv_xname);
+ if (sc->sc_hwinit)
+ (*sc->sc_hwinit)(sc);
+}
+
+/*
+ * Routine to copy from mbuf chain to transmit buffer in
+ * network buffer memory.
+ */
+integrate int
+ve_put(sc, boff, m)
+ struct vam7990_softc *sc;
+ int boff;
+ register struct mbuf *m;
+{
+ register struct mbuf *n;
+ register int len, tlen = 0;
+
+ for (; m; m = n) {
+ len = m->m_len;
+ if (len == 0) {
+ MFREE(m, n);
+ continue;
+ }
+ (*sc->sc_copytobuf)(sc, mtod(m, caddr_t), boff, len);
+ boff += len;
+ tlen += len;
+ MFREE(m, n);
+ }
+ if (tlen < LEMINSIZE) {
+ (*sc->sc_zerobuf)(sc, boff, LEMINSIZE - tlen);
+ tlen = LEMINSIZE;
+ }
+ return (tlen);
+}
+
+/*
+ * Pull data off an interface.
+ * Len is length of data, with local net header stripped.
+ * We copy the data into mbufs. When full cluster sized units are present
+ * we copy into clusters.
+ */
+integrate struct mbuf *
+ve_get(sc, boff, totlen)
+ struct vam7990_softc *sc;
+ int boff, totlen;
+{
+ register struct mbuf *m;
+ struct mbuf *top, **mp;
+ int len, pad;
+
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == 0)
+ return (0);
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = totlen;
+ pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
+ m->m_data += pad;
+ len = MHLEN - pad;
+ top = 0;
+ mp = &top;
+
+ while (totlen > 0) {
+ if (top) {
+ MGET(m, M_DONTWAIT, MT_DATA);
+ if (m == 0) {
+ m_freem(top);
+ return 0;
+ }
+ len = MLEN;
+ }
+ if (top && totlen >= MINCLSIZE) {
+ MCLGET(m, M_DONTWAIT);
+ if (m->m_flags & M_EXT)
+ len = MCLBYTES;
+ }
+ m->m_len = len = min(totlen, len);
+ (*sc->sc_copyfrombuf)(sc, mtod(m, caddr_t), boff, len);
+ boff += len;
+ totlen -= len;
+ *mp = m;
+ mp = &m->m_next;
+ }
+
+ return (top);
+}
+
+/*
+ * Pass a packet to the higher levels.
+ */
+integrate void
+ve_read(sc, boff, len)
+ register struct vam7990_softc *sc;
+ int boff, len;
+{
+ struct mbuf *m;
+ struct ether_header *eh;
+
+ if (len <= sizeof(struct ether_header) ||
+ len > ETHERMTU + sizeof(struct ether_header)) {
+#ifdef LEDEBUG
+ printf("%s: invalid packet size %d; dropping\n",
+ sc->sc_dev.dv_xname, len);
+#endif
+ ifp->if_ierrors++;
+ return;
+ }
+
+ /* Pull packet off interface. */
+ m = ve_get(sc, boff, len);
+ if (m == 0) {
+ ifp->if_ierrors++;
+ return;
+ }
+
+ ifp->if_ipackets++;
+
+ /* We assume that the header fit entirely in one mbuf. */
+ eh = mtod(m, struct ether_header *);
+
+#if NBPFILTER > 0
+ /*
+ * Check if there's a BPF listener on this interface.
+ * If so, hand off the raw packet to BPF.
+ */
+ if (ifp->if_bpf)
+ bpf_mtap(ifp->if_bpf, m);
+#endif
+
+#ifdef LANCE_REVC_BUG
+ /*
+ * The old LANCE (Rev. C) chips have a bug which causes
+ * garbage to be inserted in front of the received packet.
+ * The work-around is to ignore packets with an invalid
+ * destination address (garbage will usually not match).
+ * Of course, this precludes multicast support...
+ */
+ if (ETHER_CMP(eh->ether_dhost, sc->sc_arpcom.ac_enaddr) &&
+ ETHER_CMP(eh->ether_dhost, etherbroadcastaddr)) {
+ m_freem(m);
+ return;
+ }
+#endif
+
+ /* Pass the packet up, with the ether header sort-of removed. */
+ m_adj(m, sizeof(struct ether_header));
+ ether_input(ifp, eh, m);
+}
+
+integrate void
+ve_rint(sc)
+ struct vam7990_softc *sc;
+{
+ register int bix;
+ int rp;
+ struct vermd rmd;
+
+ bix = sc->sc_last_rd;
+
+ /* Process all buffers with valid data. */
+ for (;;) {
+ rp = LE_RMDADDR(sc, bix);
+ (*sc->sc_copyfromdesc)(sc, &rmd, rp, sizeof(rmd));
+
+ if (rmd.rmd1_bits & LE_R1_OWN)
+ break;
+
+ if (rmd.rmd1_bits & LE_R1_ERR) {
+ if (rmd.rmd1_bits & LE_R1_ENP) {
+#ifdef LEDEBUG
+ if ((rmd.rmd1_bits & LE_R1_OFLO) == 0) {
+ if (rmd.rmd1_bits & LE_R1_FRAM)
+ printf("%s: framing error\n",
+ sc->sc_dev.dv_xname);
+ if (rmd.rmd1_bits & LE_R1_CRC)
+ printf("%s: crc mismatch\n",
+ sc->sc_dev.dv_xname);
+ }
+#endif
+ } else {
+ if (rmd.rmd1_bits & LE_R1_OFLO)
+ printf("%s: overflow\n",
+ sc->sc_dev.dv_xname);
+ }
+ if (rmd.rmd1_bits & LE_R1_BUFF)
+ printf("%s: receive buffer error\n",
+ sc->sc_dev.dv_xname);
+ ifp->if_ierrors++;
+ } else if ((rmd.rmd1_bits & (LE_R1_STP | LE_R1_ENP)) !=
+ (LE_R1_STP | LE_R1_ENP)) {
+ printf("%s: dropping chained buffer\n",
+ sc->sc_dev.dv_xname);
+ ifp->if_ierrors++;
+ } else {
+#ifdef LEDEBUG
+ if (sc->sc_debug)
+ ve_recv_print(sc, sc->sc_last_rd);
+#endif
+ ve_read(sc, LE_RBUFADDR(sc, bix),
+ (int)rmd.rmd3 - 4);
+ }
+
+ rmd.rmd1_bits = LE_R1_OWN;
+ rmd.rmd2 = -LEBLEN | LE_XMD2_ONES;
+ rmd.rmd3 = 0;
+ (*sc->sc_copytodesc)(sc, &rmd, rp, sizeof(rmd));
+
+#ifdef LEDEBUG
+ if (sc->sc_debug)
+ printf("sc->sc_last_rd = %x, rmd: "
+ "ladr %04x, hadr %02x, flags %02x, "
+ "bcnt %04x, mcnt %04x\n",
+ sc->sc_last_rd,
+ rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits,
+ rmd.rmd2, rmd.rmd3);
+#endif
+
+ if (++bix == sc->sc_nrbuf)
+ bix = 0;
+ }
+
+ sc->sc_last_rd = bix;
+}
+
+integrate void
+ve_tint(sc)
+ register struct vam7990_softc *sc;
+{
+ register int bix;
+ struct vetmd tmd;
+
+ bix = sc->sc_first_td;
+
+ for (;;) {
+ if (sc->sc_no_td <= 0)
+ break;
+
+ (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, bix),
+ sizeof(tmd));
+
+#ifdef LEDEBUG
+ if (sc->sc_debug)
+ printf("trans tmd: "
+ "ladr %04x, hadr %02x, flags %02x, "
+ "bcnt %04x, mcnt %04x\n",
+ tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits,
+ tmd.tmd2, tmd.tmd3);
+#endif
+
+ if (tmd.tmd1_bits & LE_T1_OWN)
+ break;
+
+ ifp->if_flags &= ~IFF_OACTIVE;
+
+ if (tmd.tmd1_bits & LE_T1_ERR) {
+ if (tmd.tmd3 & LE_T3_BUFF)
+ printf("%s: transmit buffer error\n",
+ sc->sc_dev.dv_xname);
+ else if (tmd.tmd3 & LE_T3_UFLO)
+ printf("%s: underflow\n", sc->sc_dev.dv_xname);
+ if (tmd.tmd3 & (LE_T3_BUFF | LE_T3_UFLO)) {
+ ve_reset(sc);
+ return;
+ }
+ if (tmd.tmd3 & LE_T3_LCAR) {
+ if (sc->sc_nocarrier)
+ (*sc->sc_nocarrier)(sc);
+ else
+ printf("%s: lost carrier\n",
+ sc->sc_dev.dv_xname);
+ }
+ if (tmd.tmd3 & LE_T3_LCOL)
+ ifp->if_collisions++;
+ if (tmd.tmd3 & LE_T3_RTRY) {
+ printf("%s: excessive collisions, tdr %d\n",
+ sc->sc_dev.dv_xname,
+ tmd.tmd3 & LE_T3_TDR_MASK);
+ ifp->if_collisions += 16;
+ }
+ ifp->if_oerrors++;
+ } else {
+ if (tmd.tmd1_bits & LE_T1_ONE)
+ ifp->if_collisions++;
+ else if (tmd.tmd1_bits & LE_T1_MORE)
+ /* Real number is unknown. */
+ ifp->if_collisions += 2;
+ ifp->if_opackets++;
+ }
+
+ if (++bix == sc->sc_ntbuf)
+ bix = 0;
+
+ --sc->sc_no_td;
+ }
+
+ sc->sc_first_td = bix;
+
+ ve_start(ifp);
+
+ if (sc->sc_no_td == 0)
+ ifp->if_timer = 0;
+}
+
+/*
+ * Controller interrupt.
+ */
+int
+ve_intr(arg)
+ register void *arg;
+{
+ register struct vam7990_softc *sc = arg;
+ register u_int16_t isr;
+
+ isr = (*sc->sc_rdcsr)(sc, LE_CSR0);
+#ifdef LEDEBUG
+ if (sc->sc_debug)
+ printf("%s: ve_intr entering with isr=%04x\n",
+ sc->sc_dev.dv_xname, isr);
+#endif
+ if ((isr & LE_C0_INTR) == 0)
+ return (0);
+
+ /* clear the interrupting condition */
+ (*sc->sc_wrcsr)(sc, LE_CSR0,
+ isr & (LE_C0_INEA | LE_C0_BABL | LE_C0_MISS | LE_C0_MERR |
+ LE_C0_RINT | LE_C0_TINT | LE_C0_IDON));
+ if (isr & LE_C0_ERR) {
+ if (isr & LE_C0_BABL) {
+#ifdef LEDEBUG
+ printf("%s: babble\n", sc->sc_dev.dv_xname);
+#endif
+ ifp->if_oerrors++;
+ }
+#if 0
+ if (isr & LE_C0_CERR) {
+ printf("%s: collision error\n", sc->sc_dev.dv_xname);
+ ifp->if_collisions++;
+ }
+#endif
+ if (isr & LE_C0_MISS) {
+#ifdef LEDEBUG
+ printf("%s: missed packet\n", sc->sc_dev.dv_xname);
+#endif
+ ifp->if_ierrors++;
+ }
+ if (isr & LE_C0_MERR) {
+ printf("%s: memory error\n", sc->sc_dev.dv_xname);
+ ve_reset(sc);
+ return (1);
+ }
+ }
+
+ if ((isr & LE_C0_RXON) == 0) {
+ printf("%s: receiver disabled\n", sc->sc_dev.dv_xname);
+ ifp->if_ierrors++;
+ ve_reset(sc);
+ return (1);
+ }
+ if ((isr & LE_C0_TXON) == 0) {
+ printf("%s: transmitter disabled\n", sc->sc_dev.dv_xname);
+ ifp->if_oerrors++;
+ ve_reset(sc);
+ return (1);
+ }
+
+ if (isr & LE_C0_RINT)
+ ve_rint(sc);
+ if (isr & LE_C0_TINT)
+ ve_tint(sc);
+ ve_ackint(sc);
+ return (1);
+}
+
+#undef ifp
+
+void
+ve_watchdog(ifp)
+ struct ifnet *ifp;
+{
+ struct vam7990_softc *sc = ifp->if_softc;
+
+ log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
+ ++ifp->if_oerrors;
+
+ ve_reset(sc);
+}
+
+/*
+ * Setup output on interface.
+ * Get another datagram to send off of the interface queue, and map it to the
+ * interface before starting the output.
+ * Called only at splimp or interrupt level.
+ */
+void
+ve_start(ifp)
+ register struct ifnet *ifp;
+{
+ register struct vam7990_softc *sc = ifp->if_softc;
+ register int bix;
+ register struct mbuf *m;
+ struct vetmd tmd;
+ int rp;
+ int len;
+
+ if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
+ return;
+
+ bix = sc->sc_last_td;
+
+ for (;;) {
+ rp = LE_TMDADDR(sc, bix);
+ (*sc->sc_copyfromdesc)(sc, &tmd, rp, sizeof(tmd));
+
+ if (tmd.tmd1_bits & LE_T1_OWN) {
+ ifp->if_flags |= IFF_OACTIVE;
+ printf("missing buffer, no_td = %d, last_td = %d\n",
+ sc->sc_no_td, sc->sc_last_td);
+ }
+
+ IF_DEQUEUE(&ifp->if_snd, m);
+ if (m == 0)
+ break;
+
+#if NBPFILTER > 0
+ /*
+ * If BPF is listening on this interface, let it see the packet
+ * before we commit it to the wire.
+ */
+ if (ifp->if_bpf)
+ bpf_mtap(ifp->if_bpf, m);
+#endif
+
+ /*
+ * Copy the mbuf chain into the transmit buffer.
+ */
+ len = ve_put(sc, LE_TBUFADDR(sc, bix), m);
+
+#ifdef LEDEBUG
+ if (len > ETHERMTU + sizeof(struct ether_header))
+ printf("packet length %d\n", len);
+#endif
+
+ ifp->if_timer = 5;
+
+ /*
+ * Init transmit registers, and set transmit start flag.
+ */
+ tmd.tmd1_bits = LE_T1_OWN | LE_T1_STP | LE_T1_ENP;
+ tmd.tmd2 = -len | LE_XMD2_ONES;
+ tmd.tmd3 = 0;
+
+ (*sc->sc_copytodesc)(sc, &tmd, rp, sizeof(tmd));
+
+#ifdef LEDEBUG
+ if (sc->sc_debug)
+ ve_xmit_print(sc, sc->sc_last_td);
+#endif
+
+ (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD);
+
+ if (++bix == sc->sc_ntbuf)
+ bix = 0;
+
+ if (++sc->sc_no_td == sc->sc_ntbuf) {
+ ifp->if_flags |= IFF_OACTIVE;
+ break;
+ }
+
+ }
+
+ sc->sc_last_td = bix;
+}
+
+/*
+ * Process an ioctl request.
+ */
+int
+ve_ioctl(ifp, cmd, data)
+ register struct ifnet *ifp;
+ u_long cmd;
+ caddr_t data;
+{
+ register struct vam7990_softc *sc = ifp->if_softc;
+ struct ifaddr *ifa = (struct ifaddr *)data;
+ struct ifreq *ifr = (struct ifreq *)data;
+ int s, error = 0;
+
+ s = splimp();
+
+ if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
+ splx(s);
+ return error;
+ }
+
+ switch (cmd) {
+
+ case SIOCSIFADDR:
+ ifp->if_flags |= IFF_UP;
+
+ switch (ifa->ifa_addr->sa_family) {
+#ifdef INET
+ case AF_INET:
+ ve_init(sc);
+ arp_ifinit(&sc->sc_arpcom, ifa);
+ break;
+#endif
+ default:
+ ve_init(sc);
+ break;
+ }
+ 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, then
+ * stop it.
+ */
+ ve_stop(sc);
+ ifp->if_flags &= ~IFF_RUNNING;
+ } else if ((ifp->if_flags & IFF_UP) != 0 &&
+ (ifp->if_flags & IFF_RUNNING) == 0) {
+ /*
+ * If interface is marked up and it is stopped, then
+ * start it.
+ */
+ ve_init(sc);
+ } else {
+ /*
+ * Reset the interface to pick up changes in any other
+ * flags that affect hardware registers.
+ */
+ /*ve_stop(sc);*/
+ ve_init(sc);
+ }
+#ifdef LEDEBUG
+ if (ifp->if_flags & IFF_DEBUG)
+ sc->sc_debug = 1;
+ else
+ sc->sc_debug = 0;
+#endif
+ break;
+
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ error = (cmd == SIOCADDMULTI) ?
+ ether_addmulti(ifr, &sc->sc_arpcom) :
+ ether_delmulti(ifr, &sc->sc_arpcom);
+
+ if (error == ENETRESET) {
+ /*
+ * Multicast list has changed; set the hardware filter
+ * accordingly.
+ */
+ ve_reset(sc);
+ error = 0;
+ }
+ break;
+
+ case SIOCGIFMEDIA:
+ case SIOCSIFMEDIA:
+ if (sc->sc_hasifmedia)
+ error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd);
+ else
+ error = EINVAL;
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+
+ splx(s);
+ return (error);
+}
+
+hide void
+ve_shutdown(arg)
+ void *arg;
+{
+
+ ve_stop((struct vam7990_softc *)arg);
+}
+
+#ifdef LEDEBUG
+void
+ve_recv_print(sc, no)
+ struct vam7990_softc *sc;
+ int no;
+{
+ struct vermd rmd;
+ u_int16_t len;
+ struct ether_header eh;
+
+ (*sc->sc_copyfromdesc)(sc, &rmd, LE_RMDADDR(sc, no), sizeof(rmd));
+ len = rmd.rmd3;
+ printf("%s: receive buffer %d, len = %d\n", sc->sc_dev.dv_xname, no,
+ len);
+ printf("%s: status %04x\n", sc->sc_dev.dv_xname,
+ (*sc->sc_rdcsr)(sc, LE_CSR0));
+ printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n",
+ sc->sc_dev.dv_xname,
+ rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits, rmd.rmd2, rmd.rmd3);
+ if (len >= sizeof(eh)) {
+ (*sc->sc_copyfrombuf)(sc, &eh, LE_RBUFADDR(sc, no), sizeof(eh));
+ printf("%s: dst %s", sc->sc_dev.dv_xname,
+ ether_sprintf(eh.ether_dhost));
+ printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost),
+ ntohs(eh.ether_type));
+ }
+}
+
+void
+ve_xmit_print(sc, no)
+ struct vam7990_softc *sc;
+ int no;
+{
+ struct vetmd tmd;
+ u_int16_t len;
+ struct ether_header eh;
+
+ (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, no), sizeof(tmd));
+ len = -tmd.tmd2;
+ printf("%s: transmit buffer %d, len = %d\n", sc->sc_dev.dv_xname, no,
+ len);
+ printf("%s: status %04x\n", sc->sc_dev.dv_xname,
+ (*sc->sc_rdcsr)(sc, LE_CSR0));
+ printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n",
+ sc->sc_dev.dv_xname,
+ tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits, tmd.tmd2, tmd.tmd3);
+ if (len >= sizeof(eh)) {
+ (*sc->sc_copyfrombuf)(sc, &eh, LE_TBUFADDR(sc, no), sizeof(eh));
+ printf("%s: dst %s", sc->sc_dev.dv_xname,
+ ether_sprintf(eh.ether_dhost));
+ printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost),
+ ntohs(eh.ether_type));
+ }
+}
+#endif /* LEDEBUG */
+
+/*
+ * Set up the logical address filter.
+ */
+void
+ve_setladrf(ac, af)
+ struct arpcom *ac;
+ u_int16_t *af;
+{
+ struct ifnet *ifp = &ac->ac_if;
+ struct ether_multi *enm;
+ register u_char *cp, c;
+ register u_int32_t crc;
+ register int i, len;
+ struct ether_multistep step;
+
+ /*
+ * Set up multicast address filter by passing all multicast addresses
+ * through a crc generator, and then using the high order 6 bits as an
+ * index into the 64 bit logical address filter. The high order bit
+ * selects the word, while the rest of the bits select the bit within
+ * the word.
+ */
+
+ if (ifp->if_flags & IFF_PROMISC)
+ goto allmulti;
+
+ af[0] = af[1] = af[2] = af[3] = 0x0000;
+ ETHER_FIRST_MULTI(step, ac, enm);
+ while (enm != NULL) {
+ if (ETHER_CMP(enm->enm_addrlo, enm->enm_addrhi)) {
+ /*
+ * We must listen to a range of multicast addresses.
+ * For now, just accept all multicasts, rather than
+ * trying to set only those filter bits needed to match
+ * the range. (At this time, the only use of address
+ * ranges is for IP multicast routing, for which the
+ * range is big enough to require all bits set.)
+ */
+ goto allmulti;
+ }
+
+ cp = enm->enm_addrlo;
+ crc = 0xffffffff;
+ for (len = sizeof(enm->enm_addrlo); --len >= 0;) {
+ c = *cp++;
+ for (i = 8; --i >= 0;) {
+ if ((crc & 0x01) ^ (c & 0x01)) {
+ crc >>= 1;
+ crc ^= 0xedb88320;
+ } else
+ crc >>= 1;
+ c >>= 1;
+ }
+ }
+ /* Just want the 6 most significant bits. */
+ crc >>= 26;
+
+ /* Set the corresponding bit in the filter. */
+ af[crc >> 4] |= 1 << (crc & 0xf);
+
+ ETHER_NEXT_MULTI(step, enm);
+ }
+ ifp->if_flags &= ~IFF_ALLMULTI;
+ return;
+
+allmulti:
+ ifp->if_flags |= IFF_ALLMULTI;
+ af[0] = af[1] = af[2] = af[3] = 0xffff;
+}
+
+
+/*
+ * Routines for accessing the transmit and receive buffers.
+ * The various CPU and adapter configurations supported by this
+ * driver require three different access methods for buffers
+ * and descriptors:
+ * (1) contig (contiguous data; no padding),
+ * (2) gap2 (two bytes of data followed by two bytes of padding),
+ * (3) gap16 (16 bytes of data followed by 16 bytes of padding).
+ */
+
+/*
+ * contig: contiguous data with no padding.
+ *
+ * Buffers may have any alignment.
+ */
+
+void
+ve_copytobuf_contig(sc, from, boff, len)
+ struct vam7990_softc *sc;
+ void *from;
+ int boff, len;
+{
+ volatile caddr_t buf = sc->sc_mem;
+
+ /*
+ * Just call bcopy() to do the work.
+ */
+ bcopy(from, buf + boff, len);
+}
+
+void
+ve_copyfrombuf_contig(sc, to, boff, len)
+ struct vam7990_softc *sc;
+ void *to;
+ int boff, len;
+{
+ volatile caddr_t buf = sc->sc_mem;
+
+ /*
+ * Just call bcopy() to do the work.
+ */
+ bcopy(buf + boff, to, len);
+}
+
+void
+ve_zerobuf_contig(sc, boff, len)
+ struct vam7990_softc *sc;
+ int boff, len;
+{
+ volatile caddr_t buf = sc->sc_mem;
+
+ /*
+ * Just let bzero() do the work
+ */
+ bzero(buf + boff, len);
+}
+
+
diff --git a/sys/arch/mvme88k/dev/if_vereg.h b/sys/arch/mvme88k/dev/if_vereg.h
new file mode 100644
index 00000000000..9b29b2b95d6
--- /dev/null
+++ b/sys/arch/mvme88k/dev/if_vereg.h
@@ -0,0 +1,218 @@
+/* $OpenBSD: if_vereg.h,v 1.1 1999/05/29 04:41:43 smurph Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. 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_lereg.h 8.2 (Berkeley) 10/30/93
+ */
+
+#define LEMEMSIZE 0x40000
+
+/*
+ * LANCE registers.
+ */
+struct vereg1 {
+ volatile u_int16_t ver1_csr; /* board control/status register */
+ volatile u_int16_t ver1_vec; /* interupt vector register */
+ volatile u_int16_t ver1_rdp; /* data port */
+ volatile u_int16_t ver1_rap; /* register select port */
+ volatile u_int16_t ver1_ear; /* ethernet address register */
+};
+
+#define NVRAM_EN 0x0008 /* NVRAM enable bit */
+#define INTR_EN 0x0010 /* Interrupt enable bit */
+#define PARITYB 0x0020 /* Parity clear bit */
+#define HW_RS 0x0040 /* Hardware reset bit */
+#define SYSFAILB 0x0080 /* SYSFAIL bit */
+#define NVRAM_RWEL 0xE0 /* Reset write enable latch */
+#define NVRAM_STO 0x60 /* Store ram to eeprom */
+#define NVRAM_SLP 0xA0 /* Novram into low power mode */
+#define NVRAM_WRITE 0x20 /* Writes word from location x */
+#define NVRAM_SWEL 0xC0 /* Set write enable latch */
+#define NVRAM_RCL 0x40 /* Recall eeprom data into ram */
+#define NVRAM_READ 0x00 /* Reads word from location x */
+
+#define CDELAY delay(10000)
+#define WRITE_CSR_OR(x) reg1->ver1_csr=sc->csr|=x
+#define WRITE_CSR_AND(x) reg1->ver1_csr=sc->csr&=x
+#define ENABLE_NVRAM WRITE_CSR_AND(~NVRAM_EN)
+#define DISABLE_NVRAM WRITE_CSR_OR(NVRAM_EN)
+#define ENABLE_INTR WRITE_CSR_AND(~INTR_EN)
+#define DISABLE_INTR WRITE_CSR_OR(INTR_EN)
+#define RESET_HW WRITE_CSR_AND(~0xFF00);WRITE_CSR_AND(~HW_RS);CDELAY
+#define SET_IPL(x) WRITE_CSR_AND(~x)
+#define SET_VEC(x) reg1->ver1_vec=0;reg1->ver1_vec |=x;
+#define PARITY_CL WRITE_CSR_AND(~PARITYB)
+#define SYSFAIL_CL WRITE_CSR_AND(~SYSFAILB)
+#define NVRAM_CMD(c,a) for(i=0;i<8;i++){ \
+ reg1->ver1_ear=((c|(a<<1))>>i); \
+ CDELAY; \
+ } \
+ CDELAY;
+
+#define LEBLEN 1536 /* ETHERMTU + header + CRC */
+#define LEMINSIZE 60 /* should be 64 if mode DTCR is set */
+
+/*
+ * Receive message descriptor
+ */
+struct vermd {
+ u_int16_t rmd0;
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int8_t rmd1_bits;
+ u_int8_t rmd1_hadr;
+#else
+ u_int8_t rmd1_hadr;
+ u_int8_t rmd1_bits;
+#endif
+ int16_t rmd2;
+ u_int16_t rmd3;
+};
+
+/*
+ * Transmit message descriptor
+ */
+struct vetmd {
+ u_int16_t tmd0;
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int8_t tmd1_bits;
+ u_int8_t tmd1_hadr;
+#else
+ u_int8_t tmd1_hadr;
+ u_int8_t tmd1_bits;
+#endif
+ int16_t tmd2;
+ u_int16_t tmd3;
+};
+
+/*
+ * Initialization block
+ */
+struct veinit {
+ u_int16_t init_mode; /* +0x0000 */
+ u_int16_t init_padr[3]; /* +0x0002 */
+ u_int16_t init_ladrf[4]; /* +0x0008 */
+ u_int16_t init_rdra; /* +0x0010 */
+ u_int16_t init_rlen; /* +0x0012 */
+ u_int16_t init_tdra; /* +0x0014 */
+ u_int16_t init_tlen; /* +0x0016 */
+ int16_t pad0[4]; /* Pad to 16 shorts */
+};
+
+#define LE_INITADDR(sc) (sc->sc_initaddr)
+#define LE_RMDADDR(sc, bix) (sc->sc_rmdaddr + sizeof(struct vermd) * (bix))
+#define LE_TMDADDR(sc, bix) (sc->sc_tmdaddr + sizeof(struct vetmd) * (bix))
+#define LE_RBUFADDR(sc, bix) (sc->sc_rbufaddr + LEBLEN * (bix))
+#define LE_TBUFADDR(sc, bix) (sc->sc_tbufaddr + LEBLEN * (bix))
+
+/* register addresses */
+#define LE_CSR0 0x0000 /* Control and status register */
+#define LE_CSR1 0x0001 /* low address of init block */
+#define LE_CSR2 0x0002 /* high address of init block */
+#define LE_CSR3 0x0003 /* Bus master and control */
+
+/* Control and status register 0 (csr0) */
+#define LE_C0_ERR 0x8000 /* error summary */
+#define LE_C0_BABL 0x4000 /* transmitter timeout error */
+#define LE_C0_CERR 0x2000 /* collision */
+#define LE_C0_MISS 0x1000 /* missed a packet */
+#define LE_C0_MERR 0x0800 /* memory error */
+#define LE_C0_RINT 0x0400 /* receiver interrupt */
+#define LE_C0_TINT 0x0200 /* transmitter interrupt */
+#define LE_C0_IDON 0x0100 /* initalization done */
+#define LE_C0_INTR 0x0080 /* interrupt condition */
+#define LE_C0_INEA 0x0040 /* interrupt enable */
+#define LE_C0_RXON 0x0020 /* receiver on */
+#define LE_C0_TXON 0x0010 /* transmitter on */
+#define LE_C0_TDMD 0x0008 /* transmit demand */
+#define LE_C0_STOP 0x0004 /* disable all external activity */
+#define LE_C0_STRT 0x0002 /* enable external activity */
+#define LE_C0_INIT 0x0001 /* begin initalization */
+
+#define LE_C0_BITS \
+ "\20\20ERR\17BABL\16CERR\15MISS\14MERR\13RINT\
+\12TINT\11IDON\10INTR\07INEA\06RXON\05TXON\04TDMD\03STOP\02STRT\01INIT"
+
+/* Control and status register 3 (csr3) */
+#define LE_C3_BSWP 0x0004 /* byte swap */
+#define LE_C3_ACON 0x0002 /* ALE control, eh? */
+#define LE_C3_BCON 0x0001 /* byte control */
+
+/* Initialzation block (mode) */
+#define LE_MODE_PROM 0x8000 /* promiscuous mode */
+/* 0x7f80 reserved, must be zero */
+#define LE_MODE_INTL 0x0040 /* internal loopback */
+#define LE_MODE_DRTY 0x0020 /* disable retry */
+#define LE_MODE_COLL 0x0010 /* force a collision */
+#define LE_MODE_DTCR 0x0008 /* disable transmit CRC */
+#define LE_MODE_LOOP 0x0004 /* loopback mode */
+#define LE_MODE_DTX 0x0002 /* disable transmitter */
+#define LE_MODE_DRX 0x0001 /* disable receiver */
+#define LE_MODE_NORMAL 0 /* none of the above */
+
+/* Receive message descriptor 1 (rmd1_bits) */
+#define LE_R1_OWN 0x80 /* LANCE owns the packet */
+#define LE_R1_ERR 0x40 /* error summary */
+#define LE_R1_FRAM 0x20 /* framing error */
+#define LE_R1_OFLO 0x10 /* overflow error */
+#define LE_R1_CRC 0x08 /* CRC error */
+#define LE_R1_BUFF 0x04 /* buffer error */
+#define LE_R1_STP 0x02 /* start of packet */
+#define LE_R1_ENP 0x01 /* end of packet */
+
+#define LE_R1_BITS \
+ "\20\10OWN\7ERR\6FRAM\5OFLO\4CRC\3BUFF\2STP\1ENP"
+
+/* Transmit message descriptor 1 (tmd1_bits) */
+#define LE_T1_OWN 0x80 /* LANCE owns the packet */
+#define LE_T1_ERR 0x40 /* error summary */
+#define LE_T1_MORE 0x10 /* multiple collisions */
+#define LE_T1_ONE 0x08 /* single collision */
+#define LE_T1_DEF 0x04 /* defferred transmit */
+#define LE_T1_STP 0x02 /* start of packet */
+#define LE_T1_ENP 0x01 /* end of packet */
+
+#define LE_T1_BITS \
+ "\20\10OWN\7ERR\6RES\5MORE\4ONE\3DEF\2STP\1ENP"
+
+/* Transmit message descriptor 3 (tmd3) */
+#define LE_T3_BUFF 0x8000 /* buffer error */
+#define LE_T3_UFLO 0x4000 /* underflow error */
+#define LE_T3_LCOL 0x1000 /* late collision */
+#define LE_T3_LCAR 0x0800 /* loss of carrier */
+#define LE_T3_RTRY 0x0400 /* retry error */
+#define LE_T3_TDR_MASK 0x03ff /* time domain reflectometry counter */
+
+#define LE_XMD2_ONES 0xf000
+
+#define LE_T3_BITS \
+ "\20\20BUFF\17UFLO\16RES\15LCOL\14LCAR\13RTRY"
diff --git a/sys/arch/mvme88k/dev/if_vevar.h b/sys/arch/mvme88k/dev/if_vevar.h
new file mode 100644
index 00000000000..4c7de6d0571
--- /dev/null
+++ b/sys/arch/mvme88k/dev/if_vevar.h
@@ -0,0 +1,146 @@
+/* $OpenBSD: if_vevar.h,v 1.1 1999/05/29 04:41:43 smurph Exp $ */
+
+/*
+ * Copyright (c) 1995 Charles M. Hannum. 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 Charles M. Hannum.
+ * 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.
+ */
+
+#define LEDEBUG 1
+
+#ifdef DDB
+#define integrate
+#define hide
+#else
+#define integrate static __inline
+#define hide static
+#endif
+
+/*
+ * Ethernet software status per device.
+ *
+ * Each interface is referenced by a network interface structure,
+ * arpcom.ac_if, which the routing code uses to locate the interface.
+ * This structure contains the output queue for the interface, its address, ...
+ *
+ * NOTE: this structure MUST be the first element in machine-dependent
+ * le_softc structures! This is designed SPECIFICALLY to make it possible
+ * to simply cast a "void *" to "struct le_softc *" or to
+ * "struct ve_softc *". Among other things, this saves a lot of hair
+ * in the interrupt handlers.
+ */
+struct vam7990_softc {
+ struct device sc_dev; /* base device glue */
+ struct arpcom sc_arpcom; /* Ethernet common part */
+
+ /*
+ * Memory functions:
+ *
+ * copy to/from descriptor
+ * copy to/from buffer
+ * zero bytes in buffer
+ */
+ void (*sc_copytodesc)
+ __P((struct vam7990_softc *, void *, int, int));
+ void (*sc_copyfromdesc)
+ __P((struct vam7990_softc *, void *, int, int));
+ void (*sc_copytobuf)
+ __P((struct vam7990_softc *, void *, int, int));
+ void (*sc_copyfrombuf)
+ __P((struct vam7990_softc *, void *, int, int));
+ void (*sc_zerobuf)
+ __P((struct vam7990_softc *, int, int));
+
+ /*
+ * Machine-dependent functions:
+ *
+ * read/write CSR
+ * hardware reset hook - may be NULL
+ * hardware init hook - may be NULL
+ * no carrier hook - may be NULL
+ */
+ u_int16_t (*sc_rdcsr)
+ __P((struct vam7990_softc *, u_int16_t));
+ void (*sc_wrcsr)
+ __P((struct vam7990_softc *, u_int16_t, u_int16_t));
+ void (*sc_hwreset) __P((struct vam7990_softc *));
+ void (*sc_hwinit) __P((struct vam7990_softc *));
+ void (*sc_nocarrier) __P((struct vam7990_softc *));
+
+ int sc_hasifmedia;
+ struct ifmedia sc_ifmedia;
+
+ void *sc_sh; /* shutdownhook cookie */
+
+ u_int16_t sc_conf3; /* CSR3 value */
+
+ void *sc_mem; /* base address of RAM -- CPU's view */
+ u_long sc_addr; /* base address of RAM -- LANCE's view */
+
+ u_long sc_memsize; /* size of RAM */
+
+ int sc_nrbuf; /* number of receive buffers */
+ int sc_ntbuf; /* number of transmit buffers */
+ int sc_last_rd;
+ int sc_first_td, sc_last_td, sc_no_td;
+
+ int sc_initaddr;
+ int sc_rmdaddr;
+ int sc_tmdaddr;
+ int sc_rbufaddr;
+ int sc_tbufaddr;
+ unsigned short csr;
+#ifdef LEDEBUG
+ int sc_debug;
+#endif
+};
+
+/* Export this to machine-dependent drivers. */
+extern struct cfdriver ve_cd;
+
+void ve_config __P((struct vam7990_softc *));
+void ve_init __P((struct vam7990_softc *));
+int ve_ioctl __P((struct ifnet *, u_long, caddr_t));
+void ve_meminit __P((struct vam7990_softc *));
+void ve_reset __P((struct vam7990_softc *));
+void ve_setladrf __P((struct arpcom *, u_int16_t *));
+void ve_start __P((struct ifnet *));
+void ve_stop __P((struct vam7990_softc *));
+void ve_watchdog __P((struct ifnet *));
+int ve_intr __P((void *));
+
+/*
+ * The following functions are only useful on certain cpu/bus
+ * combinations. They should be written in assembly language for
+ * maximum efficiency, but machine-independent versions are provided
+ * for drivers that have not yet been optimized.
+ */
+void ve_copytobuf_contig __P((struct vam7990_softc *, void *, int, int));
+void ve_copyfrombuf_contig __P((struct vam7990_softc *, void *, int, int));
+void ve_zerobuf_contig __P((struct vam7990_softc *, int, int));
+
+
+
diff --git a/sys/arch/mvme88k/dev/mainbus.c b/sys/arch/mvme88k/dev/mainbus.c
index 49e002f1075..2892a076d48 100644
--- a/sys/arch/mvme88k/dev/mainbus.c
+++ b/sys/arch/mvme88k/dev/mainbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mainbus.c,v 1.2 1998/12/15 05:52:30 smurph Exp $ */
+/* $OpenBSD: mainbus.c,v 1.3 1999/05/29 04:41:44 smurph Exp $ */
/* Copyright (c) 1998 Steve Murphree, Jr. */
#include <sys/param.h>
#include <sys/systm.h>
@@ -67,7 +67,7 @@ mainbus_attach(parent, self, args)
struct device *parent, *self;
void *args;
{
- printf (" machine type %x\n", cputyp);
+ printf (" machine type MVME%x\n", cputyp);
/* XXX
* should have a please-attach-first list for mainbus,
diff --git a/sys/arch/mvme88k/dev/memc.c b/sys/arch/mvme88k/dev/memc.c
index f07337d3aec..5805f1e42c9 100644
--- a/sys/arch/mvme88k/dev/memc.c
+++ b/sys/arch/mvme88k/dev/memc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: memc.c,v 1.2 1998/12/15 05:52:30 smurph Exp $ */
+/* $OpenBSD: memc.c,v 1.3 1999/05/29 04:41:44 smurph Exp $ */
/*
* Copyright (c) 1995 Theo de Raadt
@@ -84,7 +84,7 @@ memcmatch(parent, vcf, args)
struct confargs *ca = args;
struct memcreg *memc = (struct memcreg *)ca->ca_vaddr;
- if (badvaddr(memc, 1))
+ if (badvaddr(memc, 4))
return (0);
if (memc->memc_chipid==MEMC_CHIPID || memc->memc_chipid==MCECC_CHIPID)
return (1);
diff --git a/sys/arch/mvme88k/dev/pcctwo.c b/sys/arch/mvme88k/dev/pcctwo.c
index 4156a8f440e..415c8aae3b4 100644
--- a/sys/arch/mvme88k/dev/pcctwo.c
+++ b/sys/arch/mvme88k/dev/pcctwo.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: pcctwo.c,v 1.5 1998/12/15 05:52:30 smurph Exp $ */
+/* $OpenBSD: pcctwo.c,v 1.6 1999/05/29 04:41:44 smurph Exp $ */
/*
* Copyright (c) 1995 Theo de Raadt
@@ -87,7 +87,7 @@ pcctwomatch(parent, vcf, args)
struct pcctworeg *pcc2;
/* Bomb if wrong cpu */
- if (cputyp != CPU_187){
+ if (!(cputyp == CPU_187 || cputyp == CPU_188)){
printf("==> pcctwo: wrong CPU type %x.\n", cputyp);
return (0);
}
diff --git a/sys/arch/mvme88k/dev/siop.c b/sys/arch/mvme88k/dev/siop.c
index ba95e2bd449..4fbb54c51e3 100644
--- a/sys/arch/mvme88k/dev/siop.c
+++ b/sys/arch/mvme88k/dev/siop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: siop.c,v 1.2 1998/12/15 05:52:31 smurph Exp $ */
+/* $OpenBSD: siop.c,v 1.3 1999/05/29 04:41:44 smurph Exp $ */
/*
* Copyright (c) 1994 Michael L. Hitch
@@ -184,6 +184,19 @@ void siop_dump_trace __P((void));
int kludge_city = 1;
/*
+ * dummy routine to debug while loops
+ */
+void
+wdummy(void)
+{
+ static int wcount;
+ wcount++;
+ if (wcount > 400000) {
+ wcount = 0;
+ }
+}
+
+/*
* default minphys routine for siop based controllers
*/
void
@@ -213,8 +226,9 @@ siop_scsicmd(xs)
slp = xs->sc_link;
sc = slp->adapter_softc;
flags = xs->flags;
-
- /* XXXX ?? */
+ xs->error = XS_NOERROR;
+
+ /* XXXX ?? */
if (flags & SCSI_DATA_UIO)
panic("siop: scsi data uio requested");
@@ -921,7 +935,9 @@ siop_checkintr(sc, istat, dstat, sstat0, status)
* Flush DMA and SCSI FIFOs.
*/
rp->siop_ctest8 |= SIOP_CTEST8_CLF;
- while ((rp->siop_ctest1 & SIOP_CTEST1_FMT) != SIOP_CTEST1_FMT)
+ while ((rp->siop_ctest1 & SIOP_CTEST1_FMT) != SIOP_CTEST1_FMT){
+ wdummy();
+ }
;
rp->siop_ctest8 &= ~SIOP_CTEST8_CLF;
#ifdef DEBUG
diff --git a/sys/arch/mvme88k/dev/vme.c b/sys/arch/mvme88k/dev/vme.c
index 7e8b14fe3c9..958077067a1 100644
--- a/sys/arch/mvme88k/dev/vme.c
+++ b/sys/arch/mvme88k/dev/vme.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vme.c,v 1.2 1998/12/15 05:52:31 smurph Exp $ */
+/* $OpenBSD: vme.c,v 1.3 1999/05/29 04:41:44 smurph Exp $ */
/*
* Copyright (c) 1995 Theo de Raadt
@@ -43,9 +43,13 @@
#include <sys/syslog.h>
#include <sys/fcntl.h>
#include <sys/device.h>
-#include <machine/autoconf.h>
-#include <machine/cpu.h>
-#include <machine/frame.h>
+#include <vm/vm.h>
+#include <vm/vm_map.h>
+#include <vm/vm_kern.h>
+#include "machine/autoconf.h"
+#include "machine/cpu.h"
+#include "machine/frame.h"
+#include "machine/pmap.h"
#include "pcctwo.h"
@@ -60,6 +64,11 @@ u_long vme2chip_map __P((u_long base, int len, int dwidth));
int vme2abort __P((struct frame *frame));
static int vmebustype;
+volatile vm_offset_t master1va;
+volatile vm_offset_t master2va;
+volatile vm_offset_t master3va;
+volatile vm_offset_t master4va;
+struct vme2reg *sys_vme2 = NULL;
struct cfattach vme_ca = {
sizeof(struct vmesoftc), vmematch, vmeattach
@@ -86,9 +95,9 @@ vmematch(parent, cf, args)
}
#endif
return (1);
- }
+}
-#if defined(MVME162) || defined(MVME167) || defined(MVME177) || defined (MVME187)
+#ifndef BUGMAP
/*
* make local addresses 1G-2G correspond to VME addresses 3G-4G,
* as D32
@@ -104,8 +113,31 @@ vmematch(parent, cf, args)
*/
#define VME2_D16STARTPHYS (3*1024*1024*1024UL)
#define VME2_D16ENDPHYS (3*1024*1024*1024UL + 768*1024*1024UL)
+
+#else
+
+/*
+ * make local addresses 1G-2G correspond to VME addresses 3G-4G,
+ * as D32
+ */
+
+#define VME2_D32STARTPHYS (1*1024*1024*1024UL)
+#define VME2_D32ENDPHYS (2*1024*1024*1024UL)
+#define VME2_D32STARTVME (3*1024*1024*1024UL)
+#define VME2_D32BITSVME (3*1024*1024*1024UL)
+
+/*
+ * make local addresses 3G-3.75G correspond to VME addresses 3G-3.75G,
+ * as D16
+ */
+#define VME2_D16STARTPHYS (3*1024*1024*1024UL)
+#define VME2_D16ENDPHYS (3*1024*1024*1024UL + 768*1024*1024UL)
+#define VME2_A32D16STARTPHYS (0xFF000000UL)
+#define VME2_A32D16ENDPHYS (0xFF7FFFFFUL)
+
#endif
+
/*
* Returns a physical address mapping for a VME address & length.
* Note: on some hardware it is not possible to create certain
@@ -161,34 +193,24 @@ vmepmap(sc, vmeaddr, len, bustype)
case BUS_MC:
case BUS_PCCTWO:
switch (bustype) {
- case BUS_VMES:
- /*printf("base %x len %d\n", base, len);*/
- if (base > VME2_A16BASE &&
- (base+len-VME2_A16BASE) < VME2_A16D16LEN) {
- /* XXX busted? */
- base = base - VME2_A16BASE + VME2_A16D16BASE;
- } else if (base > VME2_A24BASE &&
- (base+len-VME2_A24BASE) < VME2_A24D16LEN) {
- base = base - VME2_A24BASE + VME2_D16STARTPHYS;
- } else if ((base+len) < VME2_A32D16LEN) {
- /* XXX busted? */
- base = base + VME2_A32D16BASE;
- } else {
- printf("vme2chip_map\n");
- base = vme2chip_map(base, len, 16);
- if (base == NULL)
- return (NULL);
+ case BUS_VMES: /* D16 VME Transfers */
+ /*printf("base 0x%8x/0x%8x len 0x%x\n", vmeaddr, base, len);*/
+ base = vme2chip_map(base, len, 16);
+ if (base == NULL){
+ printf("%s: cannot map pa 0x%x len 0x%x\n",
+ sc->sc_dev.dv_xname, base, len);
+ return (NULL);
}
break;
- case BUS_VMEL:
-#if 0
- if (base > VME2_A16BASE &&
- (base+len-VME2_A16BASE) < VME2_A16D32LEN)
- base = base - VME2_A16BASE + VME2_A16D32BASE;
-#endif
+ case BUS_VMEL: /* D32 VME Transfers */
+ printf("base 0x%8x/0x%8x len 0x%x\n",
+ vmeaddr, base, len);
base = vme2chip_map(base, len, 32);
- if (base == NULL)
+ if (base == NULL){
+ printf("%s: cannot map pa 0x%x len 0x%x\n",
+ sc->sc_dev.dv_xname, base, len);
return (NULL);
+ }
break;
}
break;
@@ -271,6 +293,7 @@ vmeprint(args, bus)
struct confargs *ca = args;
printf(" addr 0x%x", ca->ca_offset);
+ printf(" vaddr 0x%x", ca->ca_vaddr);
if (ca->ca_vec > 0)
printf(" vec 0x%x", ca->ca_vec);
if (ca->ca_ipl > 0)
@@ -345,7 +368,7 @@ vmeattach(parent, self, args)
case BUS_PCC:
vme1 = (struct vme1reg *)sc->sc_vaddr;
scon = (vme1->vme1_scon & VME1_SCON_SWITCH);
- printf(": %sscon\n", scon ? "" : "not ");
+ printf(": %ssystem controller\n", scon ? "" : "not ");
vme1chip_init(sc);
break;
#endif
@@ -354,7 +377,8 @@ vmeattach(parent, self, args)
case BUS_PCCTWO:
vme2 = (struct vme2reg *)sc->sc_vaddr;
scon = (vme2->vme2_tctl & VME2_TCTL_SCON);
- printf(": %sscon\n", scon ? "" : "not ");
+ printf(": %ssystem controller\n", scon ? "" : "not ");
+ if (scon) sys_vme2 = vme2;
vme2chip_init(sc);
break;
#endif
@@ -424,7 +448,7 @@ vme1chip_init(sc)
#endif
-#if defined(MVME162) || defined(MVME167) || defined(MVME177) || defined (MVME187)
+#ifndef BUGMAP
/*
* XXX what AM bits should be used for the D32/D16 mappings?
@@ -444,7 +468,7 @@ vme2chip_init(sc)
/* unused decoders 1 */
vme2->vme2_master1 = 0;
ctl &= ~(VME2_MASTERCTL_ALL << VME2_MASTERCTL_1SHIFT);
- printf("%s: 1phys 0x%08x-0x%08x to VMExxx 0x%08x-0x%08x\n",
+ printf("%s: 1phys 0x%08x-0x%08x to VME 0x%08x-0x%08x\n",
sc->sc_dev.dv_xname,
vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000,
vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000);
@@ -452,7 +476,7 @@ vme2chip_init(sc)
/* unused decoders 2 */
vme2->vme2_master2 = 0;
ctl &= ~(VME2_MASTERCTL_ALL << VME2_MASTERCTL_2SHIFT);
- printf("%s: 2phys 0x%08x-0x%08x to VMExxx 0x%08x-0x%08x\n",
+ printf("%s: 2phys 0x%08x-0x%08x to VME 0x%08x-0x%08x\n",
sc->sc_dev.dv_xname,
vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000,
vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000);
@@ -463,7 +487,7 @@ vme2chip_init(sc)
ctl &= ~(VME2_MASTERCTL_ALL << VME2_MASTERCTL_3SHIFT);
ctl |= (VME2_MASTERCTL_D16 | VME2_MASTERCTL_AM24UD) <<
VME2_MASTERCTL_3SHIFT;
- printf("%s: 3phys 0x%08x-0x%08x to VMED16 0x%08x-0x%08x\n",
+ printf("%s: 3phys 0x%08x-0x%08x to VME 0x%08x-0x%08x\n",
sc->sc_dev.dv_xname,
vme2->vme2_master3 << 16, vme2->vme2_master3 & 0xffff0000,
vme2->vme2_master3 << 16, vme2->vme2_master3 & 0xffff0000);
@@ -476,7 +500,7 @@ vme2chip_init(sc)
ctl &= ~(VME2_MASTERCTL_ALL << VME2_MASTERCTL_4SHIFT);
ctl |= (VME2_MASTERCTL_AM32UD) <<
VME2_MASTERCTL_4SHIFT;
- printf("%s: 4phys 0x%08x-0x%08x to VMED32 0x%08x-0x%08x\n",
+ printf("%s: 4phys 0x%08x-0x%08x to VME 0x%08x-0x%08x\n",
sc->sc_dev.dv_xname,
vme2->vme2_master4 << 16, vme2->vme2_master4 & 0xffff0000,
vme2->vme2_master4 << 16, vme2->vme2_master4 & 0xffff0000);
@@ -513,6 +537,71 @@ vme2chip_init(sc)
vme2->vme2_irql4);
#if NPCCTWO > 0
+ if (vmebustype == BUS_PCCTWO) {
+ sc->sc_abih.ih_fn = vme2abort;
+ sc->sc_abih.ih_arg = 0;
+ sc->sc_abih.ih_ipl = 7;
+ sc->sc_abih.ih_wantframe = 1;
+
+ intr_establish(110, &sc->sc_abih); /* XXX 110 */
+ vme2->vme2_irqen |= VME2_IRQ_AB;
+ }
+#endif
+ vme2->vme2_irqen = vme2->vme2_irqen | VME2_IRQ_ACF;
+}
+
+#else /* BUGMAP */
+
+int
+vme2chip_init(sc)
+ struct vmesoftc *sc;
+{
+ struct vme2reg *vme2 = (struct vme2reg *)sc->sc_vaddr;
+ u_long ctl, addr, vasize;
+
+ /* turn off SYSFAIL LED */
+ vme2->vme2_tctl &= ~VME2_TCTL_SYSFAIL;
+
+ ctl = vme2->vme2_masterctl;
+ printf("%s: using BUG parameters\n", sc->sc_dev.dv_xname);
+ /* setup a A32D16 space */
+ printf("%s: 1phys 0x%08x-0x%08x to VME 0x%08x-0x%08x\n",
+ sc->sc_dev.dv_xname,
+ vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000,
+ vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000);
+
+ /* setup a A32D32 space */
+ printf("%s: 2phys 0x%08x-0x%08x to VME 0x%08x-0x%08x\n",
+ sc->sc_dev.dv_xname,
+ vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000,
+ vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000);
+
+ /* setup a A24D16 space */
+ printf("%s: 3phys 0x%08x-0x%08x to VME 0x%08x-0x%08x\n",
+ sc->sc_dev.dv_xname,
+ vme2->vme2_master3 << 16, vme2->vme2_master3 & 0xffff0000,
+ vme2->vme2_master3 << 16, vme2->vme2_master3 & 0xffff0000);
+
+ /* setup a XXXXXX space */
+ printf("%s: 4phys 0x%08x-0x%08x to VME 0x%08x-0x%08x\n",
+ sc->sc_dev.dv_xname,
+ vme2->vme2_master4 << 16, vme2->vme2_master4 & 0xffff0000,
+ vme2->vme2_master4 << 16 + vme2->vme2_master4mod << 16,
+ vme2->vme2_master4 & 0xffff0000 + vme2->vme2_master4 & 0xffff0000);
+ /*
+ * Map the VME irq levels to the cpu levels 1:1.
+ * This is rather inflexible, but much easier.
+ */
+ vme2->vme2_irql4 = (7 << VME2_IRQL4_VME7SHIFT) |
+ (6 << VME2_IRQL4_VME6SHIFT) | (5 << VME2_IRQL4_VME5SHIFT) |
+ (4 << VME2_IRQL4_VME4SHIFT) | (3 << VME2_IRQL4_VME3SHIFT) |
+ (2 << VME2_IRQL4_VME2SHIFT) | (1 << VME2_IRQL4_VME1SHIFT);
+ printf("%s: vme to cpu irq level 1:1\n",sc->sc_dev.dv_xname);
+ /*
+ printf("%s: vme2_irql4 = 0x%08x\n", sc->sc_dev.dv_xname,
+ vme2->vme2_irql4);
+ */
+#if NPCCTWO > 0
if (vmebustype == BUS_PCCTWO){
/*
* pseudo driver, abort interrupt handler
@@ -530,6 +619,9 @@ vme2chip_init(sc)
#endif
vme2->vme2_irqen = vme2->vme2_irqen | VME2_IRQ_ACF;
}
+#endif /* BUGMAP */
+
+#if defined(MVME162) || defined(MVME167) || defined(MVME177) || defined (MVME187) || defined (MVME188)
/*
* A32 accesses on the MVME1[678]x require setting up mappings in
@@ -544,14 +636,12 @@ vme2chip_map(base, len, dwidth)
{
switch (dwidth) {
case 16:
- if (base < VME2_D16STARTPHYS ||
- base + (u_long)len > VME2_D16ENDPHYS)
- return (NULL);
return (base);
case 32:
- if (base < VME2_D32STARTVME)
+ if (base < VME2_D32STARTPHYS ||
+ base + (u_long)len > VME2_D32ENDPHYS)
return (NULL);
- return (base - VME2_D32STARTVME + VME2_D32STARTPHYS);
+ return (base);
}
}
@@ -573,3 +663,5 @@ vme2abort(frame)
}
#endif
#endif /* MVME1[678]x */
+
+
diff --git a/sys/arch/mvme88k/dev/vme.h b/sys/arch/mvme88k/dev/vme.h
index f0663440e3d..d143d53f791 100644
--- a/sys/arch/mvme88k/dev/vme.h
+++ b/sys/arch/mvme88k/dev/vme.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vme.h,v 1.2 1998/12/15 05:52:31 smurph Exp $ */
+/* $OpenBSD: vme.h,v 1.3 1999/05/29 04:41:44 smurph Exp $ */
/*
* Copyright (c) 1995 Theo de Raadt
@@ -188,8 +188,8 @@ struct vme2reg {
#define VME2_MASTERCTL_AM24UB 0x3b /* A24 Non-priv. Block Transfer */
#define VME2_MASTERCTL_AM24UP 0x3a /* A24 Non-priv. Program Access */
#define VME2_MASTERCTL_AM24UD 0x39 /* A24 Non-priv. Data Access */
-#define VME2_MASTERCTL_AM16S 0x2d /* A16 Supervisory Access */
-#define VME2_MASTERCTL_AM16U 0x29 /* A16 Non-priv. Access */
+#define VME2_MASTERCTL_AM16S 0x2d /* A16 Supervisory Access */
+#define VME2_MASTERCTL_AM16U 0x29 /* A16 Non-priv. Access */
#define VME2_MASTERCTL_AM32SB 0x0f /* A32 Supervisory Block Transfer */
#define VME2_MASTERCTL_AM32SP 0x0e /* A32 Supervisory Program Access */
#define VME2_MASTERCTL_AM32SD 0x0d /* A32 Supervisory Data Access */
@@ -228,6 +228,10 @@ struct vme2reg {
/*58*/ volatile u_long vme2_t2cmp;
/*5c*/ volatile u_long vme2_t2count;
/*60*/ volatile u_long vme2_tctl;
+#define VME2_TCTL1_CEN 0x01
+#define VME2_TCTL1_COC 0x02
+#define VME2_TCTL1_COVF 0x04
+#define VME2_TCTL1_OVF 0xf0
#define VME2_TCTL_SCON 0x40000000 /* we are SCON */
#define VME2_TCTL_SYSFAIL 0x20000000 /* light SYSFAIL led */
#define VME2_TCTL_SRST 0x00800000 /* system reset */
@@ -306,6 +310,7 @@ struct vme2reg {
#define VME2_IRQL4_VME2SHIFT 4
#define VME2_IRQL4_VME1SHIFT 0
/*88*/ volatile u_long vme2_vbr;
+#define VME2_SYSFAIL (1 << 22)
#define VME2_VBR_0SHIFT 28
#define VME2_VBR_1SHIFT 24
#define VME2_VBR_GPOXXXX 0x00ffffff
diff --git a/sys/arch/mvme88k/dev/vs.c b/sys/arch/mvme88k/dev/vs.c
new file mode 100644
index 00000000000..a92f1bf6211
--- /dev/null
+++ b/sys/arch/mvme88k/dev/vs.c
@@ -0,0 +1,758 @@
+/* $OpenBSD: vs.c,v 1.1 1999/05/29 04:41:44 smurph Exp $ */
+
+/*
+ * Copyright (c) 1999 Steve Murphree, Jr.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Van Jacobson of Lawrence Berkeley Laboratory.
+ *
+ * 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.
+ */
+
+/*
+ * MVME328 scsi adaptor driver
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/disklabel.h>
+#include <sys/dkstat.h>
+#include <sys/buf.h>
+#include <sys/malloc.h>
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+#include <machine/autoconf.h>
+#include <machine/param.h>
+#if defined(MVME187)
+#include <mvme88k/dev/vsreg.h>
+#include <mvme88k/dev/vsvar.h>
+#include "machine/mmu.h"
+#else
+#include <mvme68k/dev/vsreg.h>
+#include <mvme68k/dev/vsvar.h>
+#endif /* MVME187 */
+
+int vs_checkintr __P((struct vs_softc *, struct scsi_xfer *, int *));
+int vs_chksense __P((struct scsi_xfer *));
+void vs_reset __P((struct vs_softc *));
+void vs_resync __P((struct vs_softc *));
+void vs_initialize __P((struct vs_softc *));
+int vs_intr __P((struct vs_softc *));
+int vs_poll __P((struct vs_softc *, struct scsi_xfer *));
+void vs_scsidone __P((struct scsi_xfer *, int));
+M328_CQE * vs_getcqe __P((struct vs_softc *));
+M328_IOPB * vs_getiopb __P((struct vs_softc *));
+
+extern int cold;
+extern u_int kvtop();
+
+/*
+ * default minphys routine for MVME328 based controllers
+ */
+void
+vs_minphys(bp)
+ struct buf *bp;
+{
+ /*
+ * No max transfer at this level.
+ */
+ minphys(bp);
+}
+
+int do_vspoll(sc, to)
+ struct vs_softc *sc;
+ int to;
+{
+ int i;
+ if (to <= 0 ) to = 50000;
+ /* use cmd_wait values? */
+ i = 50000;
+ /*spl0();*/
+ while(!(CRSW & (M_CRSW_CRBV | M_CRSW_CC))){
+ if (--i <= 0) {
+#ifdef DEBUG
+ printf ("waiting: timeout %d crsw 0x%x\n", to, CRSW);
+#endif
+ i = 50000;
+ --to;
+ if (to <= 0) {
+ /*splx(s);*/
+ vs_reset(sc);
+ vs_resync(sc);
+ printf ("timed out: timeout %d crsw 0x%x\n", to, CRSW);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+int
+vs_poll(sc, xs)
+ struct vs_softc *sc;
+ struct scsi_xfer *xs;
+{
+ M328_CIB *cib = (M328_CIB *)&sc->sc_vsreg->sh_CIB;
+ M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE;
+ M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB;
+ M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB;
+ M328_IOPB *miopb = (M328_IOPB *)&sc->sc_vsreg->sh_MCE_IOPB;
+ M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB;
+ M328_CQE *cqep;
+ M328_IOPB *iopb;
+ int i;
+ int status;
+ int s;
+ int to;
+
+ /*s = splbio();*/
+ to = xs->timeout / 1000;
+ for (;;) {
+ if (do_vspoll(sc, to)) break;
+ if (vs_checkintr(sc, xs, &status)) {
+ vs_scsidone(xs, status);
+ }
+ if (CRSW & M_CRSW_ER)
+ CRB_CLR_ER(CRSW);
+ CRB_CLR_DONE(CRSW);
+ if (xs->flags & ITSDONE) break;
+ }
+ return (COMPLETE);
+}
+
+void thaw_queue(sc, target)
+ struct vs_softc *sc;
+ u_int8_t target;
+{
+ u_short t;
+ t = target << 8;
+ t |= 0x0001;
+ THAW_REG = t;
+ /* loop until thawed */
+ while (THAW_REG & 0x01);
+}
+
+void
+vs_scsidone (xs, stat)
+struct scsi_xfer *xs;
+int stat;
+{
+ struct scsi_link *slp = xs->sc_link;
+ struct vs_softc *sc = slp->adapter_softc;
+ M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB;
+ xs->status = stat;
+ while (xs->status == SCSI_CHECK) {
+ vs_chksense(xs);
+ thaw_queue(sc, slp->target + 1);
+ }
+ xs->flags |= ITSDONE;
+ /*sc->sc_tinfo[slp->target].cmds++;*/
+ if (CRSW & M_CRSW_ER)
+ CRB_CLR_ER(CRSW);
+ CRB_CLR_DONE(CRSW);
+ thaw_queue(sc, slp->target + 1);
+ bzero(riopb, sizeof(M328_IOPB));
+ scsi_done(xs);
+}
+
+int
+vs_scsicmd(xs)
+ struct scsi_xfer *xs;
+{
+ struct scsi_link *slp = xs->sc_link;
+ struct vs_softc *sc = slp->adapter_softc;
+ int flags, s, i;
+ unsigned long buf, len;
+ u_short iopb_len;
+ M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE;
+ M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB;
+ M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB;
+ M328_IOPB *miopb = (M328_IOPB *)&sc->sc_vsreg->sh_MCE_IOPB;
+ M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB;
+ M328_CQE *cqep;
+ M328_IOPB *iopb;
+
+ /* If the target doesn't exist, abort */
+ if (!sc->sc_tinfo[slp->target].avail) {
+ xs->error = XS_SELTIMEOUT;
+ xs->status = -1;
+ xs->flags |= ITSDONE;
+ scsi_done(xs);
+ }
+
+ slp->quirks |= SDEV_NOLUNS;
+ flags = xs->flags;
+#ifdef SDEBUG
+ printf("scsi_cmd() ");
+ if (xs->cmd->opcode == 0){
+ printf("TEST_UNIT_READY ");
+ } else if (xs->cmd->opcode == REQUEST_SENSE) {
+ printf("REQUEST_SENSE ");
+ } else if (xs->cmd->opcode == INQUIRY) {
+ printf("INQUIRY ");
+ } else if (xs->cmd->opcode == MODE_SELECT) {
+ printf("MODE_SELECT ");
+ } else if (xs->cmd->opcode == MODE_SENSE) {
+ printf("MODE_SENSE ");
+ } else if (xs->cmd->opcode == START_STOP) {
+ printf("START_STOP ");
+ } else if (xs->cmd->opcode == RESERVE) {
+ printf("RESERVE ");
+ } else if (xs->cmd->opcode == RELEASE) {
+ printf("RELEASE ");
+ } else if (xs->cmd->opcode == PREVENT_ALLOW) {
+ printf("PREVENT_ALLOW ");
+ } else if (xs->cmd->opcode == POSITION_TO_ELEMENT) {
+ printf("POSITION_TO_EL ");
+ } else if (xs->cmd->opcode == CHANGE_DEFINITION) {
+ printf("CHANGE_DEF ");
+ } else if (xs->cmd->opcode == MODE_SENSE_BIG) {
+ printf("MODE_SENSE_BIG ");
+ } else if (xs->cmd->opcode == MODE_SELECT_BIG) {
+ printf("MODE_SELECT_BIG ");
+ } else if (xs->cmd->opcode == 0x25) {
+ printf("READ_CAPACITY ");
+ } else if (xs->cmd->opcode == 0x08) {
+ printf("READ_COMMAND ");
+ }
+#endif
+ if (flags & SCSI_POLL){
+ cqep = mc;
+ iopb = miopb;
+ }else{
+ cqep = vs_getcqe(sc);
+ iopb = vs_getiopb(sc);
+ }
+ if (cqep == NULL) {
+ xs->error = XS_DRIVER_STUFFUP;
+ return(TRY_AGAIN_LATER);
+ }
+
+/* s = splbio();*/
+ iopb_len = sizeof(M328_short_IOPB) + xs->cmdlen;
+ bzero(iopb, sizeof(M328_IOPB));
+
+ bcopy(xs->cmd, &iopb->iopb_SCSI[0], xs->cmdlen);
+ iopb->iopb_CMD = IOPB_SCSI;
+ LV(iopb->iopb_BUFF, kvtop(xs->data));
+ LV(iopb->iopb_LENGTH, xs->datalen);
+ iopb->iopb_UNIT = slp->lun << 3;
+ iopb->iopb_UNIT |= slp->target;
+ iopb->iopb_NVCT = (u_char)sc->sc_nvec;
+ iopb->iopb_EVCT = (u_char)sc->sc_evec;
+
+ /*
+ * Since the 187 doesn't support cache snooping, we have
+ * to flush the cache for a write and flush with inval for
+ * a read, prior to starting the IO.
+ */
+ if (xs->flags & SCSI_DATA_IN) { /* read */
+#if defined(MVME187)
+ dma_cachectl((vm_offset_t)xs->data, xs->datalen,
+ DMA_CACHE_SYNC_INVAL);
+#endif
+ iopb->iopb_OPTION |= OPT_READ;
+ } else { /* write */
+#if defined(MVME187)
+ dma_cachectl((vm_offset_t)xs->data, xs->datalen,
+ DMA_CACHE_SYNC);
+#endif
+ iopb->iopb_OPTION |= OPT_WRITE;
+ }
+
+ if (flags & SCSI_POLL) {
+ iopb->iopb_OPTION |= OPT_INTDIS;
+ iopb->iopb_LEVEL = 0;
+ } else {
+ iopb->iopb_OPTION |= OPT_INTEN;
+ iopb->iopb_LEVEL = sc->sc_ipl;
+ }
+ iopb->iopb_ADDR = ADDR_MOD;
+
+ /*
+ * Wait until we can use the command queue entry.
+ * Should only have to wait if the master command
+ * queue entry is busy.
+ */
+ while(cqep->cqe_QECR & M_QECR_GO);
+
+ cqep->cqe_IOPB_ADDR = OFF(iopb);
+ cqep->cqe_IOPB_LENGTH = iopb_len;
+ if (flags & SCSI_POLL){
+ cqep->cqe_WORK_QUEUE = slp->target + 1;
+ }else{
+ cqep->cqe_WORK_QUEUE = slp->target + 1;
+ }
+ LV(cqep->cqe_CTAG, xs);
+
+ if (crb->crb_CRSW & M_CRSW_AQ) {
+ cqep->cqe_QECR = M_QECR_AA;
+ }
+ VL(buf, iopb->iopb_BUFF);
+ VL(len, iopb->iopb_LENGTH);
+#ifdef SDEBUG
+ printf("tgt %d lun %d buf %x len %d wqn %d ipl %d\n", slp->target,
+ slp->lun, buf, len, cqep->cqe_WORK_QUEUE, iopb->iopb_LEVEL);
+#endif
+ cqep->cqe_QECR |= M_QECR_GO;
+
+ if (flags & SCSI_POLL){
+ /* poll for the command to complete */
+/* splx(s);*/
+ vs_poll(sc, xs);
+ return (COMPLETE);
+ }
+/* splx(s);*/
+ return(SUCCESSFULLY_QUEUED);
+}
+
+int
+vs_chksense(xs)
+ struct scsi_xfer *xs;
+{
+ int flags, s, i;
+ struct scsi_link *slp = xs->sc_link;
+ struct vs_softc *sc = slp->adapter_softc;
+ struct scsi_sense *ss;
+ M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE;
+ M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB;
+ M328_IOPB *miopb = (M328_IOPB *)&sc->sc_vsreg->sh_MCE_IOPB;
+
+ /* ack and clear the error */
+ CRB_CLR_DONE(CRSW);
+ CRB_CLR_ER(CRSW);
+ xs->status = 0;
+
+ bzero(miopb, sizeof(M328_IOPB));
+ /* This is a command, so point to it */
+ ss = (void *)&miopb->iopb_SCSI[0];
+ bzero(ss, sizeof(*ss));
+ ss->opcode = REQUEST_SENSE;
+ ss->byte2 = slp->lun << 5;
+ ss->length = sizeof(struct scsi_sense_data);
+
+ miopb->iopb_CMD = IOPB_SCSI;
+ miopb->iopb_OPTION = OPT_READ;
+ miopb->iopb_NVCT = (u_char)sc->sc_nvec;
+ miopb->iopb_EVCT = (u_char)sc->sc_evec;
+ miopb->iopb_LEVEL = 0; /*sc->sc_ipl;*/
+ miopb->iopb_ADDR = ADDR_MOD;
+ LV(miopb->iopb_BUFF, kvtop(&xs->sense));
+ LV(miopb->iopb_LENGTH, sizeof(struct scsi_sense_data));
+
+ bzero(mc, sizeof(M328_CQE));
+ mc->cqe_IOPB_ADDR = OFF(miopb);
+ mc->cqe_IOPB_LENGTH = sizeof(M328_short_IOPB) + sizeof(struct scsi_sense);
+ mc->cqe_WORK_QUEUE = 0;
+ mc->cqe_QECR = M_QECR_GO;
+ /* poll for the command to complete */
+ s = splbio();
+ do_vspoll(sc, 0);
+ /*
+ if (xs->cmd->opcode != PREVENT_ALLOW) {
+ xs->error = XS_SENSE;
+ }
+ */
+ xs->status = riopb->iopb_STATUS >> 8;
+#ifdef SDEBUG
+ scsi_print_sense(xs, 2);
+#endif
+ splx(s);
+}
+
+M328_CQE *
+vs_getcqe(sc)
+ struct vs_softc *sc;
+{
+ M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB;
+ M328_CQE *cqep;
+
+ cqep = (M328_CQE *)&sc->sc_vsreg->sh_CQE[mcsb->mcsb_QHDP];
+
+ if (cqep->cqe_QECR & M_QECR_GO)
+ return NULL; /* Hopefully, this will never happen */
+ mcsb->mcsb_QHDP++;
+ if (mcsb->mcsb_QHDP == NUM_CQE) mcsb->mcsb_QHDP = 0;
+ bzero(cqep, sizeof(M328_CQE));
+ return cqep;
+}
+
+M328_IOPB *
+vs_getiopb(sc)
+ struct vs_softc *sc;
+{
+ M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB;
+ M328_IOPB *iopb;
+ int slot;
+
+ if (mcsb->mcsb_QHDP == 0) {
+ slot = NUM_CQE;
+ } else {
+ slot = mcsb->mcsb_QHDP - 1;
+ }
+ iopb = (M328_IOPB *)&sc->sc_vsreg->sh_IOPB[slot];
+ bzero(iopb, sizeof(M328_IOPB));
+ return iopb;
+}
+
+void
+vs_initialize(sc)
+ struct vs_softc *sc;
+{
+ M328_CIB *cib = (M328_CIB *)&sc->sc_vsreg->sh_CIB;
+ M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE;
+ M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB;
+ M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB;
+ M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB;
+ M328_IOPB *iopb;
+ M328_WQCF *wiopb = (M328_WQCF *)&sc->sc_vsreg->sh_MCE_IOPB;
+ u_short i, crsw;
+ int failed = 0;
+
+ bzero(cib, sizeof(M328_CIB));
+ mcsb->mcsb_QHDP = 0;
+ sc->sc_qhp = 0;
+ cib->cib_NCQE = 10;
+ cib->cib_BURST = 0;
+ cib->cib_NVECT = sc->sc_ipl << 8;
+ cib->cib_NVECT |= sc->sc_nvec;
+ cib->cib_EVECT = sc->sc_ipl << 8;
+ cib->cib_EVECT |= sc->sc_evec;
+ cib->cib_PID = 0x07;
+ cib->cib_SID = 0x00;
+ cib->cib_CRBO = OFF(crb);
+ cib->cib_SELECT_msw = HI(SELECTION_TIMEOUT);
+ cib->cib_SELECT_lsw = LO(SELECTION_TIMEOUT);
+ cib->cib_WQ0TIMO_msw = HI(4);
+ cib->cib_WQ0TIMO_lsw = LO(4);
+ cib->cib_VMETIMO_msw = 0; /*HI(VME_BUS_TIMEOUT);*/
+ cib->cib_VMETIMO_lsw = 0; /*LO(VME_BUS_TIMEOUT);*/
+ cib->cib_SBRIV = sc->sc_ipl << 8;
+ cib->cib_SBRIV |= sc->sc_evec;
+ cib->cib_SOF0 = 0x15;
+ cib->cib_SRATE0 = 100/4;
+ cib->cib_SOF1 = 0x0;
+ cib->cib_SRATE1 = 0x0;
+
+ iopb = (M328_IOPB *)&sc->sc_vsreg->sh_MCE_IOPB;
+ bzero(iopb, sizeof(M328_IOPB));
+ iopb->iopb_CMD = CNTR_INIT;
+ iopb->iopb_OPTION = 0;
+ iopb->iopb_NVCT = (u_char)sc->sc_nvec;
+ iopb->iopb_EVCT = (u_char)sc->sc_evec;
+ iopb->iopb_LEVEL = 0; /*sc->sc_ipl;*/
+ iopb->iopb_ADDR = SHIO_MOD;
+ LV(iopb->iopb_BUFF, OFF(cib));
+ LV(iopb->iopb_LENGTH, sizeof(M328_CIB));
+
+ bzero(mc, sizeof(M328_CQE));
+ mc->cqe_IOPB_ADDR = OFF(iopb);
+ mc->cqe_IOPB_LENGTH = sizeof(M328_IOPB);
+ mc->cqe_WORK_QUEUE = 0;
+ mc->cqe_QECR = M_QECR_GO;
+ /* poll for the command to complete */
+ do_vspoll(sc, 0);
+ CRB_CLR_DONE(CRSW);
+
+ /* initialize work queues */
+ for (i=1; i<8; i++) {
+ bzero(wiopb, sizeof(M328_IOPB));
+ wiopb->wqcf_CMD = CNTR_INIT_WORKQ;
+ wiopb->wqcf_OPTION = 0;
+ wiopb->wqcf_NVCT = (u_char)sc->sc_nvec;
+ wiopb->wqcf_EVCT = (u_char)sc->sc_evec;
+ wiopb->wqcf_ILVL = 0; /*sc->sc_ipl;*/
+ wiopb->wqcf_WORKQ = i;
+ wiopb->wqcf_WOPT = (WQO_FOE | WQO_INIT);
+ wiopb->wqcf_SLOTS = JAGUAR_MAX_Q_SIZ;
+ LV(wiopb->wqcf_CMDTO, 2);
+
+ bzero(mc, sizeof(M328_CQE));
+ mc->cqe_IOPB_ADDR = OFF(wiopb);
+ mc->cqe_IOPB_LENGTH = sizeof(M328_IOPB);
+ mc->cqe_WORK_QUEUE = 0;
+ mc->cqe_QECR = M_QECR_GO;
+ /* poll for the command to complete */
+ do_vspoll(sc, 0);
+ if (CRSW & M_CRSW_ER) {
+ printf("error: queue %d status = 0x%x\n", i, riopb->iopb_STATUS);
+ /*failed = 1;*/
+ CRB_CLR_ER(CRSW);
+ }
+ CRB_CLR_DONE(CRSW);
+ delay(1000);
+ }
+ /* start queue mode */
+ CRSW = 0;
+ mcsb->mcsb_MCR |= M_MCR_SQM;
+ crsw = CRSW;
+ do_vspoll(sc, 0);
+ if (CRSW & M_CRSW_ER) {
+ printf("error: status = 0x%x\n", riopb->iopb_STATUS);
+ CRB_CLR_ER(CRSW);
+ }
+ CRB_CLR_DONE(CRSW);
+
+ if (failed) {
+ printf(": failed!\n");
+ return;
+ }
+ /* reset SCSI bus */
+ vs_reset(sc);
+ /* sync all devices */
+ vs_resync(sc);
+ printf(": target %d\n", sc->sc_link.adapter_target);
+}
+
+void
+vs_resync(sc)
+ struct vs_softc *sc;
+{
+ M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE;
+ M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB;
+ M328_DRCF *devreset = (M328_DRCF *)&sc->sc_vsreg->sh_MCE_IOPB;
+ u_short i;
+
+ for (i=0; i<7; i++) {
+ bzero(devreset, sizeof(M328_DRCF));
+ devreset->drcf_CMD = CNTR_DEV_REINIT;
+ devreset->drcf_OPTION = 0x00; /* no interrupts yet... */
+ devreset->drcf_NVCT = sc->sc_nvec;
+ devreset->drcf_EVCT = sc->sc_evec;
+ devreset->drcf_ILVL = 0;
+ devreset->drcf_UNIT = i;
+
+ bzero(mc, sizeof(M328_CQE));
+ mc->cqe_IOPB_ADDR = OFF(devreset);
+ mc->cqe_IOPB_LENGTH = sizeof(M328_DRCF);
+ mc->cqe_WORK_QUEUE = 0;
+ mc->cqe_QECR = M_QECR_GO;
+ /* poll for the command to complete */
+ do_vspoll(sc, 0);
+ if (riopb->iopb_STATUS) {
+ sc->sc_tinfo[i].avail = 0;
+ } else {
+ sc->sc_tinfo[i].avail = 1;
+ }
+ if (CRSW & M_CRSW_ER) {
+ CRB_CLR_ER(CRSW);
+ }
+ CRB_CLR_DONE(CRSW);
+ }
+}
+
+void
+vs_reset(sc)
+ struct vs_softc *sc;
+{
+ struct vsreg * rp;
+ u_int s;
+ u_char i;
+ struct iopb_reset* iopr;
+ struct cqe *cqep;
+ struct iopb_scsi *iopbs;
+ struct scsi_sense *ss;
+ M328_CIB *cib = (M328_CIB *)&sc->sc_vsreg->sh_CIB;
+ M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE;
+ M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB;
+ M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB;
+ M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB;
+ M328_SRCF *reset = (M328_SRCF *)&sc->sc_vsreg->sh_MCE_IOPB;
+ M328_IOPB *iopb;
+
+ bzero(reset, sizeof(M328_SRCF));
+ reset->srcf_CMD = IOPB_RESET;
+ reset->srcf_OPTION = 0x00; /* no interrupts yet... */
+ reset->srcf_NVCT = sc->sc_nvec;
+ reset->srcf_EVCT = sc->sc_evec;
+ reset->srcf_ILVL = 0;
+ reset->srcf_BUSID = 0;
+ s = splbio();
+
+ bzero(mc, sizeof(M328_CQE));
+ mc->cqe_IOPB_ADDR = OFF(reset);
+ mc->cqe_IOPB_LENGTH = sizeof(M328_SRCF);
+ mc->cqe_WORK_QUEUE = 0;
+ mc->cqe_QECR = M_QECR_GO;
+ /* poll for the command to complete */
+ while(1){
+ do_vspoll(sc, 0);
+ /* ack & clear scsi error condition cause by reset */
+ if (CRSW & M_CRSW_ER) {
+ CRB_CLR_ER(CRSW);
+ CRB_CLR_DONE(CRSW);
+ riopb->iopb_STATUS = 0;
+ break;
+ }
+ CRB_CLR_DONE(CRSW);
+ }
+ /* thaw all work queues */
+ thaw_queue(sc, 0xFF);
+ splx (s);
+}
+
+
+/*
+ * Process an interrupt from the MVME328
+ * We'll generally update: xs->{flags,resid,error,sense,status} and
+ * occasionally xs->retries.
+ */
+
+int
+vs_checkintr(sc, xs, status)
+ struct vs_softc *sc;
+ struct scsi_xfer *xs;
+ int *status;
+{
+ struct vsreg * rp = sc->sc_vsreg;
+ int target = -1;
+ int lun = -1;
+ M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB;
+ M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB;
+ struct scsi_generic *cmd;
+ u_long buf;
+ u_long len;
+ u_char error;
+
+ target = xs->sc_link->target;
+ lun = xs->sc_link->lun;
+ cmd = (struct scsi_generic *)&riopb->iopb_SCSI[0];
+
+ VL(buf, riopb->iopb_BUFF);
+ VL(len, riopb->iopb_LENGTH);
+ *status = riopb->iopb_STATUS >> 8;
+ error = riopb->iopb_STATUS & 0xFF;
+
+#ifdef SDEBUG
+ printf("scsi_chk() ");
+
+ if (xs->cmd->opcode == 0){
+ printf("TEST_UNIT_READY ");
+ } else if (xs->cmd->opcode == REQUEST_SENSE) {
+ printf("REQUEST_SENSE ");
+ } else if (xs->cmd->opcode == INQUIRY) {
+ printf("INQUIRY ");
+ } else if (xs->cmd->opcode == MODE_SELECT) {
+ printf("MODE_SELECT ");
+ } else if (xs->cmd->opcode == MODE_SENSE) {
+ printf("MODE_SENSE ");
+ } else if (xs->cmd->opcode == START_STOP) {
+ printf("START_STOP ");
+ } else if (xs->cmd->opcode == RESERVE) {
+ printf("RESERVE ");
+ } else if (xs->cmd->opcode == RELEASE) {
+ printf("RELEASE ");
+ } else if (xs->cmd->opcode == PREVENT_ALLOW) {
+ printf("PREVENT_ALLOW ");
+ } else if (xs->cmd->opcode == POSITION_TO_ELEMENT) {
+ printf("POSITION_TO_EL ");
+ } else if (xs->cmd->opcode == CHANGE_DEFINITION) {
+ printf("CHANGE_DEF ");
+ } else if (xs->cmd->opcode == MODE_SENSE_BIG) {
+ printf("MODE_SENSE_BIG ");
+ } else if (xs->cmd->opcode == MODE_SELECT_BIG) {
+ printf("MODE_SELECT_BIG ");
+ } else if (xs->cmd->opcode == 0x25) {
+ printf("READ_CAPACITY ");
+ } else if (xs->cmd->opcode == 0x08) {
+ printf("READ_COMMAND ");
+ }
+
+ printf("tgt %d lun %d buf %x len %d status %x ", target, lun, buf, len, riopb->iopb_STATUS);
+
+ if (CRSW & M_CRSW_EX) {
+ printf("[ex]");
+ }
+ if (CRSW & M_CRSW_QMS) {
+ printf("[qms]");
+ }
+ if (CRSW & M_CRSW_SC) {
+ printf("[sc]");
+ }
+ if (CRSW & M_CRSW_SE) {
+ printf("[se]");
+ }
+ if (CRSW & M_CRSW_AQ) {
+ printf("[aq]");
+ }
+ if (CRSW & M_CRSW_ER) {
+ printf("[er]");
+ }
+ printf("\n");
+#endif
+ if (len != xs->datalen) {
+ xs->resid = xs->datalen - len;
+ } else {
+ xs->resid = 0;
+ }
+
+ if (error == SCSI_SELECTION_TO) {
+ xs->error = XS_SELTIMEOUT;
+ xs->status = -1;
+ *status = -1;
+ }
+ return 1;
+}
+
+int
+vs_intr (sc)
+ register struct vs_softc *sc;
+{
+ M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB;
+ struct scsi_xfer *xs;
+ unsigned long loc;
+ int status;
+ int s;
+ s = splbio();
+ /* Got a valid interrupt on this device */
+
+ VL(loc, crb->crb_CTAG);
+#ifdef SDEBUG
+ printf("Interrupt!!! ");
+ printf("loc == 0x%x\n", loc);
+#endif
+ /*
+ * If this is a controller error, there won't be a scsi_xfer
+ * pointer in the CTAG feild. Bad things happen if you try
+ * to point to address 0. Controller error should be handeled
+ * in m328dma.c I'll change this soon - steve.
+ */
+ if (loc) {
+ xs = (struct scsi_xfer *)loc;
+ if (vs_checkintr (sc, xs, &status)) {
+ vs_scsidone(xs, status);
+ }
+ }
+ splx(s);
+}
+
+
diff --git a/sys/arch/mvme88k/dev/vsdma.c b/sys/arch/mvme88k/dev/vsdma.c
new file mode 100644
index 00000000000..c8a3186d0ab
--- /dev/null
+++ b/sys/arch/mvme88k/dev/vsdma.c
@@ -0,0 +1,197 @@
+/* $OpenBSD: vsdma.c,v 1.1 1999/05/29 04:41:44 smurph Exp $ */
+/*
+ * Copyright (c) 1999 Steve Murphree, Jr.
+ * 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.
+ *
+ * @(#)vsdma.c
+ */
+
+/*
+ * MVME328 scsi adaptor driver
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+#include <machine/autoconf.h>
+
+#if defined(MVME187)
+#include <machine/board.h>
+#include <mvme88k/dev/vsreg.h>
+#include <mvme88k/dev/vsvar.h>
+#include <mvme88k/dev/vme.h>
+#include "machine/mmu.h"
+#else
+#include <mvme68k/dev/vsreg.h>
+#include <mvme68k/dev/vsvar.h>
+#include <mvme68k/dev/vme.h>
+#endif /* defined(MVME187) */
+
+int vsmatch __P((struct device *, void *, void *));
+void vsattach __P((struct device *, struct device *, void *));
+int vsprint __P((void *auxp, char *));
+void vs_initialize __P((struct vs_softc *));
+int vs_intr __P((struct vs_softc *));
+int vs_nintr __P((struct vs_softc *));
+int vs_eintr __P((struct vs_softc *));
+
+struct scsi_adapter vs_scsiswitch = {
+ vs_scsicmd,
+ vs_minphys,
+ 0, /* no lun support */
+ 0, /* no lun support */
+};
+
+struct scsi_device vs_scsidev = {
+ NULL, /* use default error handler */
+ NULL, /* do not have a start function */
+ NULL, /* have no async handler */
+ NULL, /* Use default done routine */
+};
+
+struct cfattach vs_ca = {
+ sizeof(struct vs_softc), vsmatch, vsattach,
+};
+
+struct cfdriver vs_cd = {
+ NULL, "vs", DV_DULL, 0
+};
+
+int
+vsmatch(pdp, vcf, args)
+ struct device *pdp;
+ void *vcf, *args;
+{
+ struct cfdata *cf = vcf;
+ struct confargs *ca = args;
+ if (!badvaddr(ca->ca_vaddr, 1)) {
+ if (ca->ca_vec & 0x03) {
+ printf("vs: bad vector 0x%x\n", ca->ca_vec);
+ return (0);
+ }
+ return(1);
+ } else {
+ return (0);
+ }
+}
+
+void
+vsattach(parent, self, auxp)
+ struct device *parent, *self;
+ void *auxp;
+{
+ struct vs_softc *sc = (struct vs_softc *)self;
+ struct confargs *ca = auxp;
+ struct vsreg * rp;
+ int tmp;
+ extern int cpuspeed;
+
+ sc->sc_vsreg = rp = ca->ca_vaddr;
+
+ sc->sc_ipl = ca->ca_ipl;
+ sc->sc_nvec = ca->ca_vec + 0;
+ sc->sc_evec = ca->ca_vec + 1;
+ sc->sc_link.adapter_softc = sc;
+ sc->sc_link.adapter_target = 7;
+ sc->sc_link.adapter = &vs_scsiswitch;
+ sc->sc_link.device = &vs_scsidev;
+ sc->sc_link.openings = 1;
+
+ sc->sc_ih_n.ih_fn = vs_nintr;
+ sc->sc_ih_n.ih_arg = sc;
+ sc->sc_ih_n.ih_ipl = ca->ca_ipl;
+
+
+ sc->sc_ih_e.ih_fn = vs_eintr;
+ sc->sc_ih_e.ih_arg = sc;
+ sc->sc_ih_e.ih_ipl = ca->ca_ipl;
+
+ vs_initialize(sc);
+
+ vmeintr_establish(sc->sc_nvec, &sc->sc_ih_n);
+ vmeintr_establish(sc->sc_evec, &sc->sc_ih_e);
+ evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt_n);
+ evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt_e);
+
+ /*
+ * attach all scsi units on us, watching for boot device
+ * (see dk_establish).
+ */
+ tmp = bootpart;
+ if (ca->ca_paddr != bootaddr)
+ bootpart = -1; /* invalid flag to dk_establish */
+ config_found(self, &sc->sc_link, scsiprint);
+ bootpart = tmp; /* restore old value */
+}
+
+/*
+ * print diag if pnp is NULL else just extra
+ */
+int
+vsprint(auxp, pnp)
+ void *auxp;
+ char *pnp;
+{
+ if (pnp == NULL)
+ return (UNCONF);
+ return (QUIET);
+}
+
+/* normal interrupt function */
+int
+vs_nintr(sc)
+ struct vs_softc *sc;
+{
+#ifdef SDEBUG
+ printf("Normal Interrupt!!!\n");
+#endif
+ vs_intr(sc);
+ sc->sc_intrcnt_n.ev_count++;
+ return (1);
+}
+
+/* error interrupt function */
+int
+vs_eintr(sc)
+ struct vs_softc *sc;
+{
+#ifdef SDEBUG
+ printf("Error Interrupt!!!\n");
+#endif
+ vs_intr(sc);
+ sc->sc_intrcnt_e.ev_count++;
+ return (1);
+}
+
+
diff --git a/sys/arch/mvme88k/dev/vsreg.h b/sys/arch/mvme88k/dev/vsreg.h
new file mode 100644
index 00000000000..d722d62e7ea
--- /dev/null
+++ b/sys/arch/mvme88k/dev/vsreg.h
@@ -0,0 +1,695 @@
+/* $OpenBSD: vsreg.h,v 1.1 1999/05/29 04:41:44 smurph Exp $ */
+/*
+ * Copyright (c) 1999 Steve Murphree, Jr.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from source contributed by Mark Bellon.
+ *
+ * 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 !defined(_M328REG_H_)
+#define _M328REG_H_
+
+typedef struct LONGV
+{
+ u_short msw;
+ u_short lsw;
+} LONGV;
+
+#define MSW(x) ((x).msw)
+#define LSW(x) ((x).lsw)
+
+/*
+ * macro to convert a unsigned long to a LONGV
+ */
+
+#define LV( a, b) \
+{ \
+ MSW( a ) = ( (( (unsigned long)(b) ) >> 16) & 0xffff ); \
+ LSW( a ) = ( ( (unsigned long)(b) ) & 0xffff); \
+}
+
+/*
+ * macro to convert a LONGV to a unsigned long
+ */
+
+#define VL( a, b) \
+{ \
+ a = ( (((unsigned long) MSW(b)) << 16 ) | (((unsigned long) LSW(b)) & 0x0ffff) ); \
+}
+
+#define COUGAR 0x4220 /* board type (config. status area) */
+#define JAGUAR 0
+
+/*
+ * JAGUAR specific device limits.
+ */
+
+#define JAGUAR_MIN_Q_SIZ 2 /* got'a have at least one! */
+#define JAGUAR_MAX_Q_SIZ 2 /* can't have more */
+#define JAGUAR_MAX_CTLR_CMDS 80 /* Interphase says so */
+
+/*
+ * COUGAR specific device limits.
+ */
+
+#define COUGAR_MIN_Q_SIZ 2 /* got'a have at least one! */
+#define COUGAR_CMDS_PER_256K 42 /* Interphase says so */
+
+/*
+ * Structures
+ */
+
+#define NUM_CQE 10
+#define MAX_IOPB 64
+#define NUM_IOPB NUM_CQE
+#define S_IOPB_RES (MAX_IOPB - sizeof(M328_short_IOPB))
+#define S_SHORTIO 2048
+#define S_IOPB sizeof(M328_IOPB)
+#define S_CIB sizeof(M328_CIB)
+#define S_MCSB sizeof(M328_MCSB)
+#define S_MCE sizeof(M328_CQE)
+#define S_CQE (sizeof(M328_CQE) * NUM_CQE)
+#define S_HIOPB (sizeof(M328_IOPB) * NUM_IOPB)
+#define S_HSB sizeof(M328_HSB)
+#define S_CRB sizeof(M328_CRB)
+#define S_CSS sizeof(M328_CSB)
+#define S_NOT_HOST (S_MCSB + S_MCE + S_CQE + S_HIOPB + S_IOPB + \
+ S_CIB + S_HSB + S_CRB + S_IOPB + S_CSS)
+#define S_HUS_FREE (S_SHORTIO - S_NOT_HOST)
+
+#define S_WQCF sizeof(M328_WQCF)
+
+#define HOST_ID 0x4321
+
+
+/**************** Master Control Status Block (MCSB) *******************/
+
+/*
+ * defines for Master Status Register
+ */
+
+#define M_MSR_QFC 0x0004 /* queue flush complete */
+#define M_MSR_BOK 0x0002 /* board OK */
+#define M_MSR_CNA 0x0001 /* controller not available */
+
+/*
+ * defines for Master Control Register
+ */
+
+#define M_MCR_SFEN 0x2000 /* sysfail enable */
+#define M_MCR_RES 0x1000 /* reset controller */
+#define M_MCR_FLQ 0x0800 /* flush queue */
+#define M_MCR_FLQR 0x0004 /* flush queue and report */
+#define M_MCR_SQM 0x0001 /* start queue mode */
+
+/*
+ * defines for Interrupt on Queue Available Register
+ */
+
+#define M_IQAR_IQEA 0x8000 /* interrupt on queue entry avail */
+#define M_IQAR_IQEH 0x4000 /* interrupt on queue half empty */
+#define M_IQAR_ILVL 0x0700 /* interrupt lvl on queue avaliable */
+#define M_IQAR_IVCT 0x00FF /* interrupt vector on queue avail */
+
+/*
+ * defines for Thaw Work Queue Register
+ */
+
+#define M_THAW_TWQN 0xff00 /* thaw work queue number */
+#define M_THAW_TWQE 0x0001 /* thaw work queue enable */
+
+typedef struct mcsb
+{ /* Master control/Status Block */
+ volatile u_short mcsb_MSR; /* Master status register */
+ volatile u_short mcsb_MCR; /* Master Control register */
+ volatile u_short mcsb_IQAR; /* Interrupt on Queue Available Reg */
+ volatile u_short mcsb_QHDP; /* Queue head pointer */
+ volatile u_short mcsb_THAW; /* Thaw work Queue */
+ volatile u_short mcsb_RES0; /* Reserved word 0 */
+ volatile u_short mcsb_RES1; /* Reserved word 1 */
+ volatile u_short mcsb_RES2; /* Reserved word 2 */
+} M328_MCSB;
+
+/**************** END Master Control Status Block (MCSB) *******************/
+
+
+/**************** Host Semaphore Block (HSB) *******************/
+
+typedef struct hsb
+{ /* Host Semaphore Block */
+ volatile u_short hsb_INITQ; /* Init MCE Flag */
+ volatile u_short hsb_WORKQ; /* Work Queue number */
+ volatile u_short hsb_MAGIC; /* Magic word */
+ volatile u_short hsb_RES0; /* Reserved word */
+} M328_HSB;
+
+/**************** END Host Semaphore Block (HSB) *******************/
+
+/**************** Perform Diagnostics Command Format *******************/
+
+typedef struct pdcf
+{ /* Perform Diagnostics Cmd Format */
+ volatile u_short pdcf_CMD; /* Command normally 0x40 */
+ volatile u_short pdcf_RES0; /* Reserved word */
+ volatile u_short pdcf_STATUS; /* Return Status */
+ volatile u_short pdcf_RES1; /* Reserved Word */
+ volatile u_short pdcf_ROM; /* ROM Test Results */
+ volatile u_short pdcf_BUFRAM; /* Buffer RAM results */
+ volatile u_short pdcf_EVENT_RAM; /* Event Ram test Results */
+ volatile u_short pdcf_SCSI_PRI_PORT; /* SCSI Primary Port Reg test */
+ volatile u_short pdcf_SCSI_SEC_PORT; /* SCSI Secondary Port Reg test */
+} M328_PDCF;
+
+#define PDCF_SUCCESS 0xFFFF
+
+/**************** END Perform Diagnostics Command Format *******************/
+
+/*************** Controller Initialization Block (CIB) *****************/
+
+/*
+ * defines for Interrupt Vectors
+ */
+
+#define M_VECT_ILVL 0x0700 /* Interrupt Level */
+#define M_VECT_IVCT 0x00FF /* Interrupt Vector */
+
+/*
+ * defines for SCSI Bus ID Registers
+ */
+
+#define M_PSID_DFT 0x0008 /* default ID enable */
+#define M_PSID_ID 0x0007 /* Primary/Secondary SCSI ID */
+
+/*
+ * Error recovery flags.
+ */
+
+#define M_ERRFLGS_FOSR 0x0001 /* Freeze on SCSI bus reset */
+#define M_ERRFLGS_RIN 0x0002 /* SCSI bus reset interrupt */
+#define M_ERRFLGS_RSE 0x0004 /* Report COUGAR SCSI errors */
+
+/*
+ * Controller Initialization Block
+ */
+
+typedef struct cib
+{
+ volatile u_short cib_NCQE; /* Number of Command Queue Entries */
+ volatile u_short cib_BURST; /* DMA Burst count */
+ volatile u_short cib_NVECT; /* Normal Completion Vector */
+ volatile u_short cib_EVECT; /* Error Completion Vector */
+ volatile u_short cib_PID; /* Primary SCSI Bus ID */
+ volatile u_short cib_SID; /* Secondary SCSI Bus ID */
+ volatile u_short cib_CRBO; /* Command Response Block Offset */
+ volatile u_short cib_SELECT_msw;/* Selection timeout in milli_second */
+ volatile u_short cib_SELECT_lsw;/* Selection timeout in milli_second */
+ volatile u_short cib_WQ0TIMO_msw;/* Work Q - timeout in 256 ms */
+ volatile u_short cib_WQ0TIMO_lsw;/* Work Q - timeout in 256 ms */
+ volatile u_short cib_VMETIMO_msw;/* VME Time out in 32 ms */
+ volatile u_short cib_VMETIMO_lsw;/* VME Time out in 32 ms */
+ volatile u_short cib_RES0[2]; /* Reserved words */
+ volatile u_short cib_OBMT; /* offbrd CRB mtype/xfer type/ad mod */
+ volatile u_short cib_OBADDR_msw;/* host mem address for offboard CRB */
+ volatile u_short cib_OBADDR_lsw;/* host mem address for offboard CRB */
+ volatile u_short cib_ERR_FLGS; /* error recovery flags */
+ volatile u_short cib_RES1; /* reserved word */
+ volatile u_short cib_RES2; /* reserved word */
+ volatile u_short cib_SBRIV; /* SCSI Bus Reset Interrupt Vector */
+ volatile u_char cib_SOF0; /* Synchronous offset (Bus 0) */
+ volatile u_char cib_SRATE0; /* Sync negotiation rate (Bus 0) */
+ volatile u_char cib_SOF1; /* Synchronous offset (Bus 1) */
+ volatile u_char cib_SRATE1; /* Sync negotiation rate (Bus 1) */
+} M328_CIB;
+
+/**************** END Controller Initialization Block (CIB) *****************/
+
+/**************** Command Queue Entry (CQE) *******************/
+
+/*
+ * defines for Queue Entry Control Register
+ */
+
+#define M_QECR_IOPB 0x0F00 /* IOPB type (must be zero) */
+#define M_QECR_HPC 0x0004 /* High Priority command */
+#define M_QECR_AA 0x0002 /* abort acknowledge */
+#define M_QECR_GO 0x0001 /* Go/Busy */
+
+#define CQE_GO(qecr) ((qecr) |= M_QECR_GO)
+#define CQE_AA_GO(qecr) ((qecr) |= (M_QECR_GO + M_QECR_AA))
+
+typedef struct cqe
+{ /* Command Queue Entry */
+ volatile u_short cqe_QECR; /* Queue Entry Control Register */
+ volatile u_short cqe_IOPB_ADDR; /* IOPB Address */
+ volatile LONGV cqe_CTAG; /* Command Tag */
+ volatile u_char cqe_IOPB_LENGTH;/* IOPB Length */
+ volatile u_char cqe_WORK_QUEUE; /* Work Queue Number */
+ volatile u_short cqe_RES0; /* Reserved word */
+} M328_CQE;
+
+/**************** END Command Queue Entry (CQE) *******************/
+
+/**************** Command Response Block (CRB) *******************/
+
+/*
+ * defines for Command Response Status Word
+ */
+
+#define M_CRSW_SE 0x0800 /* SCSI error (COUGAR) */
+#define M_CRSW_RST 0x0400 /* SCSI Bus reset (COUGAR) */
+#define M_CRSW_SC 0x0080 /* status change */
+#define M_CRSW_CQA 0x0040 /* Command queue entry available */
+#define M_CRSW_QMS 0x0020 /* queue mode started */
+#define M_CRSW_AQ 0x0010 /* abort queue */
+#define M_CRSW_EX 0x0008 /* exception */
+#define M_CRSW_ER 0x0004 /* error */
+#define M_CRSW_CC 0x0002 /* command complete */
+#define M_CRSW_CRBV 0x0001 /* cmd response block valid/clear */
+
+#define CRB_CLR_DONE(crsw) ((crsw) = 0)
+#define CRB_CLR_ER(crsw) ((crsw) &= ~M_CRSW_ER)
+
+typedef struct crb
+{ /* Command Response Block */
+ volatile u_short crb_CRSW; /* Command Response Status Word */
+ volatile u_short crb_RES0; /* Reserved word */
+ volatile LONGV crb_CTAG; /* Command Tag */
+ volatile u_char crb_IOPB_LENGTH;/* IOPB Length */
+ volatile u_char crb_WORK_QUEUE; /* Work Queue Number */
+ volatile u_short crb_RES1; /* Reserved word */
+} M328_CRB;
+
+/**************** END Command Response Block (CRB) *******************/
+
+/*********** Controller Error Vector Status Block (CEVSB) **************/
+
+typedef struct cevsb
+{ /* Command Response Block */
+ volatile u_short cevsb_CRSW; /* Command Response Status Word */
+ volatile u_char cevsb_TYPE; /* IOPB type */
+ volatile u_char cevsb_RES0; /* Reserved byte */
+ volatile LONGV cevsb_CTAG; /* Command Tag */
+ volatile u_char cevsb_IOPB_LENGTH;/* IOPB Length */
+ volatile u_char cevsb_WORK_QUEUE;/* Work Queue Number */
+ volatile u_short cevsb_RES1; /* Reserved word */
+ volatile u_char cevsb_RES2; /* Reserved byte */
+ volatile u_char cevsb_ERROR; /* error code */
+ volatile u_short cevsb_AUXERR; /* COUGAR error code */
+} M328_CEVSB;
+
+/*********** END Controller Error Vector Status Block (CEVSB) **************/
+
+/**************** Configuration Status Block (CSB) *******************/
+
+typedef struct csb
+{ /* Configuration Status Blk */
+ volatile u_short csb_TYPE; /* 0x0=JAGUAR, 0x4220=COUGAR */
+ volatile u_char csb_RES1; /* Reserved byte */
+ volatile u_char csb_PCODE[3]; /* Product Code */
+ volatile u_short csb_RES2; /* Reserved word */
+ volatile u_char csb_RES3; /* Reserved byte */
+ volatile u_char csb_PVAR; /* Product Variation */
+ volatile u_short csb_RES4; /* Reserved word */
+ volatile u_char csb_RES5; /* Reserved byte */
+ volatile u_char csb_FREV[3]; /* Firmware Revision level */
+ volatile u_short csb_RES6; /* Reserved word */
+ volatile u_char csb_FDATE[8]; /* Firmware Release date */
+ volatile u_short csb_SSIZE; /* System memory size in Kbytes */
+ volatile u_short csb_BSIZE; /* Buffer memory size in Kbytes */
+ volatile u_short csb_RES8; /* Reserved word */
+ volatile u_char csb_PFECID; /* Primary Bus FEC ID */
+ volatile u_char csb_SFECID; /* Secondard Bus FEC ID */
+ volatile u_char csb_PID; /* Primary Bus ID */
+ volatile u_char csb_SID; /* Secondary Bus ID */
+ volatile u_char csb_LPDS; /* Last Primary Device Selected */
+ volatile u_char csb_LSDS; /* Last Secondary Device Selected */
+ volatile u_char csb_PPS; /* Primary Phase Sense */
+ volatile u_char csb_SPS; /* Secondary Phase Sense */
+ volatile u_char csb_RES10; /* Reserved byte */
+ volatile u_char csb_DBID; /* Daughter Board ID */
+ volatile u_char csb_RES11; /* Reserved byte */
+ volatile u_char csb_SDS; /* Software DIP Switch */
+ volatile u_short csb_RES12; /* Reserved word */
+ volatile u_short csb_FWQR; /* Frozen Work Queues Register */
+ volatile u_char csb_RES13[72]; /* Reserved bytes */
+} M328_CSB;
+
+/**************** END Configuration Status Block (CSB) *******************/
+
+/**************** IOPB Format (IOPB) *******************/
+
+/*
+ * defines for IOPB Option Word
+ */
+
+#define M_OPT_HEAD_TAG 0x3000 /* head of queue command queue tag */
+#define M_OPT_ORDERED_TAG 0x2000 /* order command queue tag */
+#define M_OPT_SIMPLE_TAG 0x1000 /* simple command queue tag */
+#define M_OPT_GO_WIDE 0x0800 /* use WIDE transfers */
+#define M_OPT_DIR 0x0100 /* VME direction bit */
+#define M_OPT_SG_BLOCK 0x0008 /* scatter/gather in 512 byte blocks */
+#define M_OPT_SS 0x0004 /* Suppress synchronous transfer */
+#define M_OPT_SG 0x0002 /* scatter/gather bit */
+#define M_OPT_IE 0x0001 /* Interrupt enable */
+
+/*
+ * defines for IOPB Address Type and Modifier
+ */
+
+#define M_ADR_TRANS 0x0C00 /* transfer type */
+#define M_ADR_MEMT 0x0300 /* memory type */
+#define M_ADR_MOD 0x00FF /* VME address modifier */
+
+/*
+ * defines for IOPB Unit Address on SCSI Bus
+ */
+
+#define M_UNIT_EXT_LUN 0xFF00 /* Extended Address */
+#define M_UNIT_EXT 0x0080 /* Extended Address Enable */
+#define M_UNIT_BUS 0x0040 /* SCSI Bus Selection */
+#define M_UNIT_LUN 0x0038 /* Logical Unit Number */
+#define M_UNIT_ID 0x0007 /* SCSI Device ID */
+
+typedef struct short_iopb
+{
+ volatile u_short iopb_CMD; /* IOPB Command code */
+ volatile u_short iopb_OPTION; /* IOPB Option word */
+ volatile u_short iopb_STATUS; /* IOPB Return Status word */
+ volatile u_short iopb_RES0; /* IOPB Reserved word */
+ volatile u_char iopb_NVCT; /* IOPB Normal completion Vector */
+ volatile u_char iopb_EVCT; /* IOPB Error completion Vector */
+ volatile u_short iopb_LEVEL; /* IOPB Interrupt Level */
+ volatile u_short iopb_RES1; /* IOPB Reserved word */
+ volatile u_short iopb_ADDR; /* IOPB Address type and modifer */
+ volatile LONGV iopb_BUFF; /* IOPB Buffer Address */
+ volatile LONGV iopb_LENGTH; /* IOPB Max-Transfer Length */
+ volatile u_short iopb_RES2; /* IOPB Reserved word */
+ volatile u_short iopb_RES3; /* IOPB Reserved word */
+ volatile u_short iopb_RES4; /* IOPB Reserved word */
+ volatile u_short iopb_UNIT; /* IOPB Unit address on SCSI bus */
+} M328_short_IOPB;
+
+typedef struct iopb
+{
+ volatile u_short iopb_CMD; /* IOPB Command code */
+ volatile u_short iopb_OPTION; /* IOPB Option word */
+ volatile u_short iopb_STATUS; /* IOPB Return Status word */
+ volatile u_short iopb_RES0; /* IOPB Reserved word */
+ volatile u_char iopb_NVCT; /* IOPB Normal completion Vector */
+ volatile u_char iopb_EVCT; /* IOPB Error completion Vector */
+ volatile u_short iopb_LEVEL; /* IOPB Interrupt Level */
+ volatile u_short iopb_RES1; /* IOPB Reserved word */
+ volatile u_short iopb_ADDR; /* IOPB Address type and modifer */
+ volatile LONGV iopb_BUFF; /* IOPB Buffer Address */
+ volatile LONGV iopb_LENGTH; /* IOPB Max-Transfer Length */
+ volatile u_short iopb_RES2; /* IOPB Reserved word */
+ volatile u_short iopb_RES3; /* IOPB Reserved word */
+ volatile u_short iopb_RES4; /* IOPB Reserved word */
+ volatile u_short iopb_UNIT; /* IOPB Unit address on SCSI bus */
+ u_short iopb_SCSI[S_IOPB_RES/2]; /* IOPB SCSI words for pass thru */
+} M328_IOPB;
+
+/**************** END IOPB Format (IOPB) *******************/
+
+/**************** Initialize Work Queue Command Format (WQCF) ***********/
+
+#define M_WOPT_IWQ 0x8000 /* initialize work queue */
+#define M_WOPT_PE 0x0008 /* parity check enable */
+#define M_WOPT_FE 0x0004 /* freeze on error enable */
+#define M_WOPT_TM 0x0002 /* target mode enable */
+#define M_WOPT_AE 0x0001 /* abort enable */
+
+typedef struct wqcf
+{ /* Initialize Work Queue Cmd Format*/
+ volatile u_short wqcf_CMD; /* Command Normally (0x42) */
+ volatile u_short wqcf_OPTION; /* Command Options */
+ volatile u_short wqcf_STATUS; /* Return Status */
+ volatile u_short wqcf_RES0; /* Reserved word */
+ volatile u_char wqcf_NVCT; /* Normal Completion Vector */
+ volatile u_char wqcf_EVCT; /* Error Completion Vector */
+ volatile u_short wqcf_ILVL; /* Interrupt Level */
+ volatile u_short wqcf_RES1[8]; /* Reserved words */
+ volatile u_short wqcf_WORKQ; /* Work Queue Number */
+ volatile u_short wqcf_WOPT; /* Work Queue Options */
+ volatile u_short wqcf_SLOTS; /* Number of slots in Work Queues */
+ volatile u_short wqcf_RES2; /* Reserved word */
+ volatile LONGV wqcf_CMDTO; /* Command timeout */
+ volatile u_short wqcf_RES3; /* Reserved word */
+} M328_WQCF;
+
+/**************** END Initialize Work Queue Command Format (WQCF) ***********/
+
+/**************** SCSI Reset Command Format (SRCF) ***********/
+
+typedef struct srcf
+{ /* SCSI Reset Cmd Format*/
+ volatile u_short srcf_CMD; /* Command Normally (0x22) */
+ volatile u_short srcf_OPTION; /* Command Options */
+ volatile u_short srcf_STATUS; /* Return Status */
+ volatile u_short srcf_RES0; /* Reserved word */
+ volatile u_char srcf_NVCT; /* Normal Completion Vector */
+ volatile u_char srcf_EVCT; /* Error Completion Vector */
+ volatile u_short srcf_ILVL; /* Interrupt Level */
+ volatile u_short srcf_RES1[8]; /* Reserved words */
+ volatile u_short srcf_BUSID; /* SCSI bus ID to reset */
+} M328_SRCF;
+
+/**************** END SCSI Reset Command Format (SRCF) ***********/
+
+/**************** Device Reinitialize Command Format (DRCF) ***********/
+
+typedef struct drcf
+{ /* Device Reinitialize Cmd Format*/
+ volatile u_short drcf_CMD; /* Command Normally (0x4C) */
+ volatile u_short drcf_OPTION; /* Command Options */
+ volatile u_short drcf_STATUS; /* Return Status */
+ volatile u_short drcf_RES0; /* Reserved word */
+ volatile u_char drcf_NVCT; /* Normal Completion Vector */
+ volatile u_char drcf_EVCT; /* Error Completion Vector */
+ volatile u_short drcf_ILVL; /* Interrupt Level */
+ volatile u_short drcf_RES1[9]; /* Reserved words */
+ volatile u_short drcf_UNIT; /* Unit Address */
+} M328_DRCF;
+
+/**************** END SCSI Reset Command Format (SRCF) ***********/
+
+/**************** Host Down Loadable Firmware (HDLF) ***********/
+
+typedef struct hdlf
+{ /* Host Down Loadable Firmware cmd */
+ volatile u_short hdlf_CMD; /* Command Normally (0x4F) */
+ volatile u_short hdlf_OPTION; /* Command Options */
+ volatile u_short hdlf_STATUS; /* Return Status */
+ volatile u_short hdlf_RES0; /* Reserved word */
+ volatile u_char hdlf_NVCT; /* Normal Completion Vector */
+ volatile u_char hdlf_EVCT; /* Error Completion Vector */
+ volatile u_short hdlf_ILVL; /* Interrupt Level */
+ volatile u_short hdlf_RES1; /* Reserved word */
+ volatile u_short hdlf_ADDR; /* Address type and modifer */
+ volatile LONGV hdlf_BUFF; /* Buffer Address */
+ volatile LONGV hdlf_LENGTH; /* Max-Transfer Length */
+ volatile LONGV hdlf_CSUM; /* Checksum */
+ volatile u_short hdlf_RES2; /* Reserved word */
+ volatile u_short hdlf_SEQ; /* Sequence number */
+ volatile u_short hdlf_RES3[6]; /* Reserved words */
+} M328_HDLF;
+
+#define M328_INITIALIZE_DOWNLOAD 0x0010
+#define M328_TRANSFER_PACKET 0x0020
+#define M328_PROGRAM_FLASH 0x0040
+#define M328_MOTOROLA_S_RECORDS 0x1000
+
+/**************** END SCSI Reset Command Format (SRCF) ***********/
+
+/**************** Short I/O Format *******************/
+
+struct vsreg
+{
+ M328_MCSB sh_MCSB; /* Master Control / Status Block */
+ M328_CQE sh_MCE; /* Master Command Entry */
+ M328_CQE sh_CQE[NUM_CQE]; /* Command Queue Entry */
+ M328_IOPB sh_IOPB[NUM_IOPB]; /* Host IOPB Space */
+ M328_IOPB sh_MCE_IOPB; /* Host MCE IOPB Space */
+ M328_CIB sh_CIB; /* Controller Initialization Block */
+ volatile u_char sh_HUS[S_HUS_FREE];/* Host Usable Space */
+ M328_HSB sh_HSB; /* Host Semaphore Block */
+ M328_CRB sh_CRB; /* Command Response Block */
+ M328_IOPB sh_RET_IOPB; /* Returned IOPB */
+ M328_CSB sh_CSS; /* Controller Specific Space/Block */
+};
+
+#define CRSW sc->sc_vsreg->sh_CRB.crb_CRSW
+#define THAW_REG sc->sc_vsreg->sh_MCSB.mcsb_THAW
+#define THAW(x) THAW_REG=((u_char)x << 8);THAW_REG |= M_THAW_TWQE
+#define QUEUE_FZN(x) (sc->sc_vsreg->sh_CSS.csb_FWQR & (1 << x))
+#define SELECTION_TIMEOUT 250 /* milliseconds */
+#define VME_BUS_TIMEOUT 0xF /* units of 30ms */
+#define M328_INFINITE_TIMEOUT 0 /* wait forever */
+
+/**************** END Short I/O Format *******************/
+
+/*
+ * Scatter gather structure
+ */
+
+typedef struct ipsg
+{
+ volatile u_short sg_count; /* byte/entry count */
+ volatile u_short sg_addrhi; /* datablock/entry address high */
+ volatile u_short sg_addrlo; /* datablock/entry address low */
+ volatile u_short sg_meminfo; /* memory information */
+}IPSG;
+
+#define MACSI_SG 256 /* number of MACSI scat/gat entries */
+#define S_MACSI_SG (MACSI_SG * sizeof(IPSG))
+#define MACSI_SG_RSIZE 65535 /* max len of each scatter/gather entry */
+
+/*
+ * SCSI IOPB definitions
+ */
+
+#define IOPB_PASS_THRU 0x20 /* SCSI Pass Through commands */
+#define IOPB_PASS_THRU_EXT 0x21 /* SCSI Pass Through Extended commands */
+#define IOPB_RESET 0x22 /* SCSI Reset bus */
+
+/*
+ * SCSI Control IOPB's
+ */
+
+#define CNTR_DIAG 0x40 /* Perform Diagnostics */
+#define CNTR_INIT 0x41 /* Initialize Controller */
+#define CNTR_INIT_WORKQ 0x42 /* Initialize Work Queue */
+#define CNTR_DUMP_INIT 0x43 /* Dump Initialization Parameters */
+#define CNTR_DUMP_WORDQ 0x44 /* Dump work Queue Parameters */
+#define CNTR_CANCEL_IOPB 0x48 /* Cancel command tag */
+#define CNTR_FLUSH_WORKQ 0x49 /* Flush Work Queue */
+#define CNTR_DEV_REINIT 0x4C /* Reinitialize Device */
+#define CNTR_ISSUE_ABORT 0x4E /* An abort has been issued */
+#define CNTR_DOWNLOAD_FIRMWARE 0x4F /* Download firmware (COUGAR) */
+
+/*
+ * Memory types
+ */
+
+#define MEMT_16BIT 1 /* 16 Bit Memory type */
+#define MEMT_32BIT 2 /* 32 Bit Memory type */
+#define MEMT_SHIO 3 /* Short I/O Memory type */
+#define MEMTYPE MEMT_32BIT /* do 32-bit transfers */
+
+/*
+ * Transfer types
+ */
+
+#define TT_NORMAL 0 /* Normal Mode Tranfers */
+#define TT_BLOCK 1 /* block Mode Tranfers */
+#define TT_DISABLE_INC_ADDR 2 /* Disable Incrementing Addresses */
+#define TT_D64 3 /* D64 Mode Transfers */
+
+/*
+ * Error codes.
+ */
+
+#define MACSI_GOOD_STATUS 0x00 /* Good status */
+#define MACSI_QUEUE_FULL 0x01 /* The work queue is full */
+#define MACSI_CMD_CODE_ERR 0x04 /* The IOPB command field is invalid */
+#define MACSI_QUEUE_NUMBER_ERR 0x05 /* Invalid queue number */
+
+#define RESET_BUS_STATUS 0x11 /* SCSI bus reset IOPB forced this */
+#define NO_SECONDARY_PORT 0x12 /* second SCSI bus not available */
+#define SCSI_DEVICE_IS_RESET 0x14 /* device has been reset */
+#define CMD_ABORT_BY_RESET 0x15 /* device has been reset */
+
+#define VME_BUS_ERROR 0x20 /* There was a VME BUS error */
+#define VME_BUS_ACC_TIMEOUT 0x21
+#define VME_BUS_BAD_ADDR 0x23
+#define VME_BUS_BAD_MEM_TYPE 0x24
+#define VME_BUS_BAD_COUNT 0x25
+#define VME_BUS_FETCH_ERROR 0x26
+#define VME_BUS_FETCH_TIMEOUT 0x27
+#define VME_BUS_POST_ERROR 0x28
+#define VME_BUS_POST_TIMEOUT 0x29
+#define VME_BUS_BAD_FETCH_ADDR 0x2A
+#define VME_BUS_BAD_POST_ADDR 0x2B
+#define VME_BUS_SG_FETCH 0x2C
+#define VME_BUS_SG_TIMEOUT 0x2D
+#define VME_BUS_SG_COUNT 0x2E
+
+#define SCSI_SELECTION_TO 0x30 /* select time out */
+#define SCSI_DISCONNECT_TIMEOUT 0x31 /* disconnect timeout */
+#define SCSI_ABNORMAL_SEQ 0x32 /* abnormal sequence */
+#define SCSI_DISCONNECT_ERR 0x33 /* disconnect error */
+#define SCSI_XFER_EXCEPTION 0x34 /* transfer cnt exception */
+#define SCSI_PARITY_ERROR 0x35 /* parity error */
+
+#define DEVICE_NO_IOPB 0x82 /* IOPB no available */
+#define IOPB_CTLR_EHX 0x83 /* IOPB counter exhausted */
+#define IOPB_DIR_ERROR 0x84 /* IOPB direction wrong */
+#define COUGAR_ERROR 0x86 /* COUGAR unrecoverable error */
+#define MACSI_INCORRECT_HARDWARE 0x90 /* Insufficient memory */
+#define MACSI_ILGL_IOPB_VAL 0x92 /* Invalid field in the IOPB */
+#define MACSI_ILLEGAL_IMAGE 0x9C /* Submitted fails reuested action */
+#define IOPB_TYPE_ERR 0xC0 /* IOPB type not 0 */
+#define IOPB_TIMEOUT 0xC1 /* IOPB timed out */
+
+#define COUGAR_PANIC 0xFF /* COUGAR paniced */
+
+#define MACSI_INVALID_TIMEOUT 0x843 /* The SCSI byte to byte timer expired */
+
+/*
+ * Handy vector macro.
+ */
+
+#define VEC(c, vec) (((c) -> mc_ipl << 8) + (vec))
+
+/*
+ * VME addressing modes
+ */
+
+#define ADRM_STD_S_P 0x3E /* Standard Supervisory Program */
+#define ADRM_STD_S_D 0x3D /* Standard Supervisory Data */
+#define ADRM_STD_N_P 0x3A /* Standard Normal Program */
+#define ADRM_STD_N_D 0x39 /* Standard Normal Data */
+#define ADRM_SHT_S_IO 0x2D /* Short Supervisory IO */
+#define ADRM_SHT_N_IO 0x29 /* Short Normal IO */
+#define ADRM_EXT_S_P 0x0E /* Extended Supervisory Program */
+#define ADRM_EXT_S_D 0x0D /* Extended Supervisory Data */
+#define ADRM_EXT_N_P 0x0A /* Extended Normal Program */
+#define ADRM_EXT_N_D 0x09 /* Extended Normal Data */
+#define ADRM_EXT_S_BM 0x0F /* Extended Supervisory Block Mode */
+#define ADRM_EXT_S_D64 0x0C /* Extended Supervisory D64 Mode */
+
+#define ADDR_MOD ( (TT_NORMAL << 10) | (MEMTYPE << 8) | ADRM_EXT_S_D )
+#define BLOCK_MOD ( (TT_BLOCK << 10) | (MEMTYPE << 8) | ADRM_EXT_S_BM )
+#define D64_MOD ( (TT_D64 << 10) | (MEMTYPE << 8) | ADRM_EXT_S_D64 )
+#define SHIO_MOD ( (TT_NORMAL << 10) | (MEMT_SHIO << 8) | ADRM_SHT_N_IO)
+
+#endif /* _M328REG_H_ */
diff --git a/sys/arch/mvme88k/dev/vsvar.h b/sys/arch/mvme88k/dev/vsvar.h
new file mode 100644
index 00000000000..e645971095c
--- /dev/null
+++ b/sys/arch/mvme88k/dev/vsvar.h
@@ -0,0 +1,132 @@
+/* $OpenBSD: vsvar.h,v 1.1 1999/05/29 04:41:44 smurph Exp $ */
+/*
+ * Copyright (c) 1999 Steve Murphree, Jr.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Van Jacobson of Lawrence Berkeley Laboratory.
+ *
+ * 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.
+ */
+#ifndef _VSVAR_H_
+#define _VSVAR_H_
+
+/*
+ * The largest single request will be MAXPHYS bytes which will require
+ * at most MAXPHYS/NBPG+1 chain elements to describe, i.e. if none of
+ * the buffer pages are physically contiguous (MAXPHYS/NBPG) and the
+ * buffer is not page aligned (+1).
+ */
+#define DMAMAXIO (MAXPHYS/NBPG+1)
+#define LO(x) (u_short)((unsigned long)x & 0x0000FFFF)
+#define HI(x) (u_short)((unsigned long)x >> 16)
+#define OFF(x) (u_short)((long)kvtop(x) - (long)kvtop(sc->sc_vsreg))
+
+struct vs_tinfo {
+ int cmds; /* #commands processed */
+ int dconns; /* #disconnects */
+ int touts; /* #timeouts */
+ int perrs; /* #parity errors */
+ int senses; /* #request sense commands sent */
+ ushort lubusy; /* What local units/subr. are busy? */
+ u_char flags;
+ u_char period; /* Period suggestion */
+ u_char offset; /* Offset suggestion */
+ int avail; /* Is there a device there */
+} tinfo_t;
+
+struct vs_softc {
+ struct device sc_dev;
+ struct intrhand sc_ih_e;
+ struct intrhand sc_ih_n;
+ struct evcnt sc_intrcnt_e;
+ struct evcnt sc_intrcnt_n;
+ u_short sc_ipl;
+ u_short sc_evec;
+ u_short sc_nvec;
+ struct scsi_link sc_link; /* proto for sub devices */
+ u_long sc_chnl; /* channel 0 or 1 for dual bus cards */
+ u_long sc_qhp; /* Command queue head pointer */
+ struct vsreg *sc_vsreg;
+#define SIOP_NACB 8
+ struct vs_tinfo sc_tinfo[8];
+ u_char sc_flags;
+ u_char sc_sien;
+ u_char sc_dien;
+ u_char sc_minsync;
+ struct map *hus_map;
+ /* one for each target */
+ struct syncpar {
+ u_char state;
+ u_char sxfer;
+ u_char sbcl;
+ } sc_sync[8];
+};
+
+/* sync states */
+#define SYNC_START 0 /* no sync handshake started */
+#define SYNC_SENT 1 /* we sent sync request, no answer yet */
+#define SYNC_DONE 2 /* target accepted our (or inferior) settings,
+ or it rejected the request and we stay async */
+
+#define IOPB_SCSI 0x20
+#define IOPB_RESET 0x22
+#define IOPB_INIT 0x41
+#define IOPB_WQINIT 0x42
+#define IOPB_DEV_RESET 0x4D
+
+#define OPT_INTEN 0x0001
+#define OPT_INTDIS 0x0000
+#define OPT_SG 0x0002
+#define OPT_SST 0x0004
+#define OPT_SIT 0x0040
+#define OPT_READ 0x0000
+#define OPT_WRITE 0x0100
+
+#define AM_S32 0x01
+#define AM_S16 0x05
+#define AM_16 0x0100
+#define AM_32 0x0200
+#define AM_SHORT 0x0300
+#define AM_NORMAL 0x0000
+#define AM_BLOCK 0x0400
+#define AM_D64BLOCK 0x0C00
+
+#define WQO_AE 0x0001 /* abort enable bit */
+#define WQO_FOE 0x0004 /* freeze on error */
+#define WQO_PE 0x0008 /* parity enable bit */
+#define WQO_ARE 0x0010 /* autosense recovery enable bit */
+#define WQO_RFWQ 0x0020 /* report frozen work queue bit */
+#define WQO_INIT 0x8000 /* work queue init bit */
+
+void vs_minphys __P((struct buf *bp));
+int vs_scsicmd __P((struct scsi_xfer *));
+
+#endif /* _M328VAR_H */
diff --git a/sys/arch/mvme88k/dev/vx.c b/sys/arch/mvme88k/dev/vx.c
new file mode 100644
index 00000000000..60aba6197ad
--- /dev/null
+++ b/sys/arch/mvme88k/dev/vx.c
@@ -0,0 +1,1691 @@
+/* $OpenBSD: vx.c,v 1.1 1999/05/29 04:41:45 smurph Exp $ */
+/*
+ * Copyright (c) 1999 Steve Murphree, Jr.
+ * 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 Dale Rahn.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/callout.h>
+#include <sys/conf.h>
+#include <sys/ioctl.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/uio.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <sys/device.h>
+#include <machine/cpu.h>
+#include <machine/autoconf.h>
+#include <dev/cons.h>
+#include <mvme88k/dev/vxreg.h>
+#include <sys/syslog.h>
+#include "pcctwo.h"
+#if NPCCTWO > 0
+ #include <mvme88k/dev/pcctworeg.h>
+ #include <mvme88k/dev/vme.h>
+#endif
+
+#include <machine/psl.h>
+#define splvx() spltty()
+
+#ifdef DEBUG
+ #undef DEBUG
+#endif
+#define DEBUG_KERN 1
+
+struct vx_info {
+ struct tty *tty;
+ u_char vx_swflags;
+ int vx_linestatus;
+ int open;
+ int waiting;
+ u_char vx_consio;
+ u_char vx_speed;
+ u_char read_pending;
+ struct wring *wringp;
+ struct rring *rringp;
+};
+
+struct vxsoftc {
+ struct device sc_dev;
+ struct evcnt sc_intrcnt;
+ struct evcnt sc_sintrcnt;
+ struct vx_info sc_info[9];
+ struct vxreg *vx_reg;
+ unsigned int board_addr;
+ struct channel *channel;
+ char channel_number;
+ struct packet sc_bppwait_pkt;
+ void *sc_bppwait_pktp;
+ struct intrhand sc_ih_c;
+ struct intrhand sc_ih_s;
+ struct vme2reg *sc_vme2;
+ int sc_ipl;
+ int sc_vec;
+ int sc_flags;
+ struct envelope *elist_head, *elist_tail;
+ struct packet *plist_head, *plist_tail;
+};
+
+extern int cold; /* var in autoconf.c that is set in machdep.c when booting */
+
+/* prototypes */
+
+void *get_next_envelope __P((struct envelope *thisenv));
+struct envelope *get_status_head __P((struct vxsoftc *sc));
+void set_status_head __P((struct vxsoftc *sc, void *envp));
+struct packet *get_packet __P((struct vxsoftc *sc, struct envelope *thisenv));
+struct envelope *find_status_packet __P((struct vxsoftc *sc, struct packet * pktp));
+
+void read_wakeup __P((struct vxsoftc *sc, int port));
+int bpp_send __P((struct vxsoftc *sc, void *pkt, int wait_flag));
+
+int create_channels __P((struct vxsoftc *sc));
+void *memcpy2 __P((void *dest, const void *src, size_t size));
+void *get_free_envelope __P((struct vxsoftc *sc));
+void put_free_envelope __P((struct vxsoftc *sc, void *envp));
+void *get_free_packet __P((struct vxsoftc *sc));
+void put_free_packet __P((struct vxsoftc *sc, void *pktp));
+
+int vx_init __P((struct vxsoftc *sc));
+int vx_event __P((struct vxsoftc *sc, struct packet *evntp));
+
+void vx_unblock __P((struct tty *tp));
+int vx_ccparam __P((struct vxsoftc *sc, struct termios *par, int port));
+
+int vx_param __P((struct tty *tp, struct termios *t));
+int vx_intr __P((struct vxsoftc *sc));
+int vx_sintr __P((struct vxsoftc *sc));
+int vx_poll __P((struct vxsoftc *sc, struct packet *wpktp));
+void vx_overflow __P((struct vxsoftc *sc, int port, long *ptime, u_char *msg));
+void vx_frame __P((struct vxsoftc *sc, int port));
+void vx_break __P(( struct vxsoftc *sc, int port));
+int vx_mctl __P((dev_t dev, int bits, int how));
+
+int vxmatch __P((struct device *parent, void *self, void *aux));
+void vxattach __P((struct device *parent, struct device *self, void *aux));
+
+int vxopen __P((dev_t dev, int flag, int mode, struct proc *p));
+int vxclose __P((dev_t dev, int flag, int mode, struct proc *p));
+int vxread __P((dev_t dev, struct uio *uio, int flag));
+int vxwrite __P((dev_t dev, struct uio *uio, int flag));
+int vxioctl __P((dev_t dev, int cmd, caddr_t data, int flag, struct proc *p));
+void vxstart __P((struct tty *tp));
+int vxstop __P((struct tty *tp, int flag));
+
+static void vxputc __P((struct vxsoftc *sc, int port, u_char c));
+static u_char vxgetc __P((struct vxsoftc *sc, int *port));
+
+struct cfattach vx_ca = {
+ sizeof(struct vxsoftc), vxmatch, vxattach
+};
+
+struct cfdriver vx_cd = {
+ NULL, "vx", DV_TTY, 0
+};
+
+#define VX_UNIT(x) (int)(minor(x) / 9)
+#define VX_PORT(x) (int)(minor(x) % 9)
+
+extern int cputyp;
+struct envelope *bpp_wait;
+unsigned int board_addr;
+
+struct tty * vxtty(dev)
+dev_t dev;
+{
+ int unit, port;
+ struct vxsoftc *sc;
+ unit = VX_UNIT(dev);
+ if (unit >= vx_cd.cd_ndevs ||
+ (sc = (struct vxsoftc *) vx_cd.cd_devs[unit]) == NULL) {
+ return (NULL);
+ }
+ port = VX_PORT(dev);
+ return sc->sc_info[port].tty;
+}
+
+int
+vxmatch(parent, self, aux)
+struct device *parent;
+void *self;
+void *aux;
+{
+ struct vxreg *vx_reg;
+ struct vxsoftc *sc = self;
+ struct confargs *ca = aux;
+ int ret;
+ if (cputyp != CPU_187)
+ return 0;
+#ifdef OLD_MAPPINGS
+ ca->ca_vaddr = ca->ca_paddr;
+#endif
+ ca->ca_len = 0x10000; /* we know this. */
+ ca->ca_ipl = 3; /* we need interrupts for this board to work */
+
+ vx_reg = (struct vxreg *)ca->ca_vaddr;
+ board_addr = (unsigned int)ca->ca_vaddr;
+ if (!badvaddr(&vx_reg->ipc_cr, 1)){
+ if (ca->ca_vec & 0x03) {
+ printf("xvt: bad vector 0x%x\n", ca->ca_vec);
+ return (0);
+ }
+ return (1);
+ } else {
+ return (0);
+ }
+}
+
+void
+vxattach(parent, self, aux)
+struct device *parent;
+struct device *self;
+void *aux;
+{
+ struct vxsoftc *sc = (struct vxsoftc *)self;
+ struct confargs *ca = aux;
+ int i;
+
+ /* set up dual port memory and registers and init*/
+ sc->vx_reg = (struct vxreg *)ca->ca_vaddr;
+ sc->channel = (struct channel *)(ca->ca_vaddr + 0x0100);
+ sc->sc_vme2 = ca->ca_master;
+ sc->sc_ipl = ca->ca_ipl;
+ sc->sc_vec = ca->ca_vec;
+ sc->board_addr = (unsigned int)ca->ca_vaddr;
+
+ printf("\n");
+
+ if (create_channels(sc)) {
+ printf("%s: failed to create channel %d\n", sc->sc_dev.dv_xname,
+ sc->channel->channel_number);
+ return;
+ }
+ if (vx_init(sc)){
+ printf("%s: failed to initialize\n", sc->sc_dev.dv_xname);
+ return;
+ }
+
+ /* enable interrupts */
+ sc->sc_ih_c.ih_fn = vx_intr;
+ sc->sc_ih_c.ih_arg = sc;
+ sc->sc_ih_c.ih_ipl = ca->ca_ipl;
+ sc->sc_ih_c.ih_wantframe = 0;
+
+ vmeintr_establish(ca->ca_vec, &sc->sc_ih_c);
+ evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt);
+}
+
+int vxtdefaultrate = TTYDEF_SPEED;
+
+dtr_ctl(sc, port, on)
+ struct vxsoftc *sc;
+ int port;
+ int on;
+{
+ struct packet pkt;
+ bzero(&pkt, sizeof(struct packet));
+ pkt.command = CMD_IOCTL;
+ pkt.ioctl_cmd_l = IOCTL_TCXONC;
+ pkt.command_pipe_number = sc->channel_number;
+ pkt.status_pipe_number = sc->channel_number;
+ pkt.device_number = port;
+ if (on) {
+ pkt.ioctl_arg_l = 6; /* assert DTR */
+ } else {
+ pkt.ioctl_arg_l = 7; /* negate DTR */
+ }
+ bpp_send(sc, &pkt, NOWAIT);
+ return (pkt.error_l);
+}
+
+rts_ctl(sc, port, on)
+ struct vxsoftc *sc;
+ int port;
+ int on;
+{
+ struct packet pkt;
+ bzero(&pkt, sizeof(struct packet));
+ pkt.command = CMD_IOCTL;
+ pkt.ioctl_cmd_l = IOCTL_TCXONC;
+ pkt.command_pipe_number = sc->channel_number;
+ pkt.status_pipe_number = sc->channel_number;
+ pkt.device_number = port;
+ if (on) {
+ pkt.ioctl_arg_l = 4; /* assert RTS */
+ } else {
+ pkt.ioctl_arg_l = 5; /* negate RTS */
+ }
+ bpp_send(sc, &pkt, NOWAIT);
+ return (pkt.error_l);
+}
+
+flush_ctl(sc, port, which)
+ struct vxsoftc *sc;
+ int port;
+ int which;
+{
+ struct packet pkt;
+ bzero(&pkt, sizeof(struct packet));
+ pkt.command = CMD_IOCTL;
+ pkt.ioctl_cmd_l = IOCTL_TCFLSH;
+ pkt.command_pipe_number = sc->channel_number;
+ pkt.status_pipe_number = sc->channel_number;
+ pkt.device_number = port;
+ pkt.ioctl_arg_l = which; /* 0=input, 1=output, 2=both */
+ bpp_send(sc, &pkt, NOWAIT);
+ return (pkt.error_l);
+}
+
+int vx_mctl (dev, bits, how)
+dev_t dev;
+int bits;
+int how;
+{
+ int s, unit, port;
+ int vxbits;
+ struct vxsoftc *sc;
+ struct vx_info *vxt;
+ u_char msvr;
+
+ unit = VX_UNIT(dev);
+ port = VX_PORT(dev);
+ sc = (struct vxsoftc *) vx_cd.cd_devs[unit];
+ vxt = &sc->sc_info[port];
+
+ s = splvx();
+ switch (how) {
+ case DMSET:
+ if( bits & TIOCM_RTS) {
+ rts_ctl(sc, port, 1);
+ vxt->vx_linestatus |= TIOCM_RTS;
+ } else {
+ rts_ctl(sc, port, 0);
+
+ vxt->vx_linestatus &= ~TIOCM_RTS;
+ }
+ if( bits & TIOCM_DTR) {
+ dtr_ctl(sc, port, 1);
+ vxt->vx_linestatus |= TIOCM_DTR;
+ } else {
+ dtr_ctl(sc, port, 0);
+ vxt->vx_linestatus &= ~TIOCM_DTR;
+ }
+ break;
+ case DMBIC:
+ if ( bits & TIOCM_RTS) {
+ rts_ctl(sc, port, 0);
+ vxt->vx_linestatus &= ~TIOCM_RTS;
+ }
+ if ( bits & TIOCM_DTR) {
+ dtr_ctl(sc, port, 0);
+ vxt->vx_linestatus &= ~TIOCM_DTR;
+ }
+ break;
+
+ case DMBIS:
+ if ( bits & TIOCM_RTS) {
+ rts_ctl(sc, port, 1);
+ vxt->vx_linestatus |= TIOCM_RTS;
+ }
+ if ( bits & TIOCM_DTR) {
+ dtr_ctl(sc, port, 1);
+ vxt->vx_linestatus |= TIOCM_DTR;
+ }
+ break;
+
+ case DMGET:
+ bits = 0;
+ msvr = vxt->vx_linestatus;
+ if( msvr & TIOCM_DSR) {
+ bits |= TIOCM_DSR;
+ }
+ if( msvr & TIOCM_CD) {
+ bits |= TIOCM_CD;
+ }
+ if( msvr & TIOCM_CTS) {
+ bits |= TIOCM_CTS;
+ }
+ if( msvr & TIOCM_DTR) {
+ bits |= TIOCM_DTR;
+ }
+ if( msvr & TIOCM_RTS) {
+ bits |= TIOCM_RTS;
+ }
+ break;
+ }
+
+ splx(s);
+ bits = 0;
+ bits |= TIOCM_DTR;
+ bits |= TIOCM_RTS;
+ bits |= TIOCM_CTS;
+ bits |= TIOCM_CD;
+ bits |= TIOCM_DSR;
+ return (bits);
+}
+
+int vxopen (dev, flag, mode, p)
+dev_t dev;
+int flag;
+int mode;
+struct proc *p;
+{
+ int s, unit, port;
+ struct vx_info *vxt;
+ struct vxsoftc *sc;
+ struct tty *tp;
+ struct open_packet opkt;
+ u_short code;
+
+ unit = VX_UNIT(dev);
+ port = VX_PORT(dev);
+
+ if (unit >= vx_cd.cd_ndevs ||
+ (sc = (struct vxsoftc *) vx_cd.cd_devs[unit]) == NULL) {
+ return (ENODEV);
+ }
+
+ /*flush_ctl(sc, port, 2);*/
+
+ bzero(&opkt, sizeof(struct packet));
+ opkt.eye_catcher[0] = 0x33;
+ opkt.eye_catcher[1] = 0x33;
+ opkt.eye_catcher[2] = 0x33;
+ opkt.eye_catcher[3] = 0x33;
+ opkt.command_pipe_number = sc->channel_number;
+ opkt.status_pipe_number = sc->channel_number;
+ opkt.command = CMD_OPEN;
+ opkt.device_number = port;
+
+ bpp_send(sc, &opkt, WAIT_POLL);
+
+ if (opkt.error_l) {
+#ifdef DEBUG_VXT
+ printf("unit %d, port %d, ", unit, port);
+ printf("error = %d\n", opkt.error_l);
+#endif
+ return (ENODEV);
+ }
+
+ code = opkt.event_code;
+ s = splvx();
+
+ vxt = &sc->sc_info[port];
+ if (vxt->tty) {
+ tp = vxt->tty;
+ } else {
+ tp = vxt->tty = ttymalloc();
+ }
+
+ /* set line status */
+ tp->t_state |= TS_CARR_ON;
+ if (code & E_DCD) {
+ tp->t_state |= TS_CARR_ON;
+ vxt->vx_linestatus |= TIOCM_CD;
+ }
+ if (code & E_DSR) {
+ vxt->vx_linestatus |= TIOCM_DSR;
+ }
+ if (code & E_CTS) {
+ vxt->vx_linestatus |= TIOCM_CTS;
+ }
+
+ tp->t_oproc = vxstart;
+ tp->t_param = vx_param;
+ tp->t_dev = dev;
+
+ if ((tp->t_state & TS_ISOPEN) == 0) {
+ tp->t_state |= TS_WOPEN;
+ ttychars(tp);
+ if (tp->t_ispeed == 0) {
+ /*
+ * only when cleared do we reset to defaults.
+ */
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_lflag = TTYDEF_LFLAG;
+ tp->t_ispeed = tp->t_ospeed = vxtdefaultrate;
+ tp->t_cflag = TTYDEF_CFLAG;
+ }
+ /*
+ * do these all the time
+ */
+ if (vxt->vx_swflags & TIOCFLAG_CLOCAL)
+ tp->t_cflag |= CLOCAL;
+ if (vxt->vx_swflags & TIOCFLAG_CRTSCTS)
+ tp->t_cflag |= CRTSCTS;
+ if (vxt->vx_swflags & TIOCFLAG_MDMBUF)
+ tp->t_cflag |= MDMBUF;
+ vx_param(tp, &tp->t_termios);
+ ttsetwater(tp);
+
+ (void)vx_mctl(dev, TIOCM_DTR | TIOCM_RTS, DMSET);
+
+ tp->t_state |= TS_CARR_ON;
+ } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
+ splx(s);
+ return (EBUSY);
+ }
+
+ /*
+ * Reset the tty pointer, as there could have been a dialout
+ * use of the tty with a dialin open waiting.
+ */
+ tp->t_dev = dev;
+ sc->sc_info[port].open = 1;
+ read_wakeup(sc, port);
+ splx(s);
+ return ((*linesw[tp->t_line].l_open)(dev, tp));
+}
+
+int
+vx_param(tp, t)
+struct tty *tp;
+struct termios *t;
+{
+ int unit, port;
+ struct vxsoftc *sc;
+ int s;
+ dev_t dev;
+
+ dev = tp->t_dev;
+ unit = VX_UNIT(dev);
+ if (unit >= vx_cd.cd_ndevs ||
+ (sc = (struct vxsoftc *) vx_cd.cd_devs[unit]) == NULL) {
+ return (ENODEV);
+ }
+ port = VX_PORT(dev);
+ tp->t_ispeed = t->c_ispeed;
+ tp->t_ospeed = t->c_ospeed;
+ tp->t_cflag = t->c_cflag;
+ vx_ccparam(sc, t, port);
+ vx_unblock(tp);
+ return 0;
+}
+
+int
+vxclose (dev, flag, mode, p)
+dev_t dev;
+int flag;
+int mode;
+struct proc *p;
+{
+ int unit, port;
+ struct tty *tp;
+ struct vx_info *vxt;
+ struct vxsoftc *sc;
+ int s;
+ struct close_packet cpkt;
+ unit = VX_UNIT(dev);
+ if (unit >= vx_cd.cd_ndevs ||
+ (sc = (struct vxsoftc *) vx_cd.cd_devs[unit]) == NULL) {
+ return (ENODEV);
+ }
+ port = VX_PORT(dev);
+/* flush_ctl(sc, port, 2); flush both input and output */
+
+ vxt = &sc->sc_info[port];
+ tp = vxt->tty;
+ (*linesw[tp->t_line].l_close)(tp, flag);
+
+ if((tp->t_cflag & HUPCL) != 0) {
+ rts_ctl(sc, port, 0);
+ dtr_ctl(sc, port, 0);
+ }
+
+ s = splvx();
+
+ bzero(&cpkt, sizeof(struct packet));
+ cpkt.eye_catcher[0] = 0x55;
+ cpkt.eye_catcher[1] = 0x55;
+ cpkt.eye_catcher[2] = 0x55;
+ cpkt.eye_catcher[3] = 0x55;
+ cpkt.command_pipe_number = sc->channel_number;
+ cpkt.status_pipe_number = sc->channel_number;
+ cpkt.command = CMD_CLOSE;
+ cpkt.device_number = port;
+
+ bpp_send(sc, &cpkt, NOWAIT);
+ splx(s);
+ ttyclose(tp);
+ sc->sc_info[port].open = 0;
+ return (0);
+}
+
+void
+read_wakeup(sc, port)
+struct vxsoftc *sc;
+int port;
+{
+ struct rring *rp;
+ struct read_wakeup_packet rwp;
+ volatile struct vx_info *vxt;
+ vxt = &sc->sc_info[port];
+ /*
+ * If we already have a read_wakeup paket
+ * for this port, do nothing.
+ */
+ if (vxt->read_pending) {
+ return;
+ } else {
+ vxt->read_pending = 1;
+ }
+
+ bzero(&rwp, sizeof(struct packet));
+ rwp.eye_catcher[0] = 0x11;
+ rwp.eye_catcher[1] = 0x11;
+ rwp.eye_catcher[2] = 0x11;
+ rwp.eye_catcher[3] = 0x11;
+ rwp.command_pipe_number = sc->channel_number;
+ rwp.status_pipe_number = sc->channel_number;
+ rwp.command = CMD_READW;
+ rwp.device_number = port;
+
+ /*
+ * Do not wait. Characters will be transfered
+ * to (*linesw[tp->t_line].l_rint)(c,tp); by
+ * vx_intr() (IPC will notify via interrupt)
+ */
+ bpp_send(sc, &rwp, NOWAIT);
+}
+
+int
+vxread (dev, uio, flag)
+dev_t dev;
+struct uio *uio;
+int flag;
+{
+ int unit, port;
+ struct tty *tp;
+ volatile struct vx_info *vxt;
+ volatile struct vxsoftc *sc;
+
+ unit = VX_UNIT(dev);
+ if (unit >= vx_cd.cd_ndevs ||
+ (sc = (struct vxsoftc *) vx_cd.cd_devs[unit]) == NULL) {
+ return (ENODEV);
+ }
+ port = VX_PORT(dev);
+ vxt = &sc->sc_info[port];
+ tp = vxt->tty;
+ if (!tp) return ENXIO;
+ return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
+}
+
+int
+vxwrite (dev, uio, flag)
+dev_t dev;
+struct uio *uio;
+int flag;
+{
+ int unit, port;
+ struct tty *tp;
+ struct vx_info *vxt;
+ struct vxsoftc *sc;
+ struct wring *wp;
+ struct write_wakeup_packet wwp;
+ u_short get, put;
+ int i, cnt, s;
+
+ unit = VX_UNIT(dev);
+ if (unit >= vx_cd.cd_ndevs ||
+ (sc = (struct vxsoftc *) vx_cd.cd_devs[unit]) == NULL) {
+ return (ENODEV);
+ }
+
+ port = VX_PORT(dev);
+ vxt = &sc->sc_info[port];
+ tp = vxt->tty;
+ if (!tp) return ENXIO;
+
+ wp = sc->sc_info[port].wringp;
+ get = wp->get;
+ put = wp->put;
+
+ if ((put + 1) == get) {
+ bzero(&wwp, sizeof(struct packet));
+ wwp.eye_catcher[0] = 0x22;
+ wwp.eye_catcher[1] = 0x22;
+ wwp.eye_catcher[2] = 0x22;
+ wwp.eye_catcher[3] = 0x22;
+ wwp.command_pipe_number = sc->channel_number;
+ wwp.status_pipe_number = sc->channel_number;
+ wwp.command = CMD_WRITEW;
+ wwp.device_number = port;
+
+ bpp_send(sc, &wwp, WAIT_POLL);
+
+ if (wwp.error_l) {
+ return (ENXIO);
+ }
+ }
+ return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
+}
+
+int
+vxioctl (dev, cmd, data, flag, p)
+dev_t dev;
+int cmd;
+caddr_t data;
+int flag;
+struct proc *p;
+{
+ int error;
+ int unit, port;
+ struct tty *tp;
+ struct vx_info *vxt;
+ struct vxsoftc *sc;
+ unit = VX_UNIT(dev);
+ if (unit >= vx_cd.cd_ndevs ||
+ (sc = (struct vxsoftc *) vx_cd.cd_devs[unit]) == NULL) {
+ return (ENODEV);
+ }
+ port = VX_PORT(dev);
+ vxt = &sc->sc_info[port];
+ tp = vxt->tty;
+ if (!tp)
+ return ENXIO;
+
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return (error);
+
+ error = ttioctl(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return (error);
+
+ switch (cmd) {
+ case TIOCSBRK:
+ /* */
+ break;
+
+ case TIOCCBRK:
+ /* */
+ break;
+
+ case TIOCSDTR:
+ (void) vx_mctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIS);
+ break;
+
+ case TIOCCDTR:
+ (void) vx_mctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIC);
+ break;
+
+ case TIOCMSET:
+ (void) vx_mctl(dev, *(int *) data, DMSET);
+ break;
+
+ case TIOCMBIS:
+ (void) vx_mctl(dev, *(int *) data, DMBIS);
+ break;
+
+ case TIOCMBIC:
+ (void) vx_mctl(dev, *(int *) data, DMBIC);
+ break;
+
+ case TIOCMGET:
+ *(int *)data = vx_mctl(dev, 0, DMGET);
+ break;
+
+ case TIOCGFLAGS:
+ *(int *)data = vxt->vx_swflags;
+ break;
+
+ case TIOCSFLAGS:
+ error = suser(p->p_ucred, &p->p_acflag);
+ if (error != 0)
+ return(EPERM);
+
+ vxt->vx_swflags = *(int *)data;
+ vxt->vx_swflags &= /* only allow valid flags */
+ (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS);
+ break;
+
+ default:
+ return (ENOTTY);
+ }
+ return 0;
+}
+
+int
+vxstop(tp, flag)
+struct tty *tp;
+int flag;
+{
+ int s;
+
+ s = splvx();
+ if (tp->t_state & TS_BUSY) {
+ if ((tp->t_state & TS_TTSTOP) == 0)
+ tp->t_state |= TS_FLUSH;
+ }
+ splx(s);
+ return 0;
+}
+
+static u_char
+vxgetc(sc, port)
+struct vxsoftc *sc;
+int *port;
+{
+ return 0;
+}
+
+static void
+vxputc(sc, port, c)
+struct vxsoftc *sc;
+int port;
+u_char c;
+{
+ struct wring *wp;
+
+ wp = sc->sc_info[port].wringp;
+ wp->data[wp->put++ & (WRING_BUF_SIZE-1)] = c;
+ wp->put &= (WRING_BUF_SIZE-1);
+ return;
+}
+
+u_short vxtspeed(speed)
+int speed;
+{
+ switch (speed) {
+ case B0:
+ return VB0;
+ break;
+ case B50:
+ return VB50;
+ break;
+ case B75:
+ return VB75;
+ break;
+ case B110:
+ return VB110;
+ break;
+ case B134:
+ return VB134;
+ break;
+ case B150:
+ return VB150;
+ break;
+ case B200:
+ return VB200;
+ break;
+ case B300:
+ return VB300;
+ break;
+ case B600:
+ return VB600;
+ break;
+ case B1200:
+ return VB1200;
+ break;
+ case B1800:
+ return VB1800;
+ break;
+ case B2400:
+ return VB2400;
+ break;
+ case B4800:
+ return VB4800;
+ break;
+ case B9600:
+ return VB9600;
+ break;
+ case B19200:
+ return VB19200;
+ break;
+ case B38400:
+ return VB38400;
+ break;
+ default:
+ return VB9600;
+ break;
+ }
+}
+
+int
+vx_ccparam(sc, par, port)
+struct vxsoftc *sc;
+struct termios *par;
+int port;
+{
+ struct termio tio;
+ int imask=0, ints, s;
+ int cflag, iflag, oflag, lflag;
+ struct ioctl_a_packet pkt;
+ bzero(&pkt, sizeof(struct packet));
+
+ if (par->c_ospeed == 0) {
+ s = splvx();
+ /* dont kill the console */
+ if(sc->sc_info[port].vx_consio == 0) {
+ /* disconnect, drop RTS DTR stop reciever */
+ rts_ctl(sc, port, 0);
+ dtr_ctl(sc, port, 0);
+ }
+ splx(s);
+ return (0xff);
+ }
+
+ pkt.command = CMD_IOCTL;
+ pkt.ioctl_cmd_l = IOCTL_TCGETA;
+ pkt.command_pipe_number = sc->channel_number;
+ pkt.status_pipe_number = sc->channel_number;
+ pkt.device_number = port;
+ bpp_send(sc, &pkt, WAIT_POLL);
+
+ cflag = pkt.c_cflag;
+ cflag |= vxtspeed(par->c_ospeed);
+
+ switch (par->c_cflag & CSIZE) {
+ case CS5:
+ cflag |= VCS5;
+ imask = 0x1F;
+ break;
+ case CS6:
+ cflag |= VCS6;
+ imask = 0x3F;
+ break;
+ case CS7:
+ cflag |= VCS7;
+ imask = 0x7F;
+ break;
+ default:
+ cflag |= VCS8;
+ imask = 0xFF;
+ }
+
+ if (par->c_cflag & PARENB) cflag |= VPARENB; else cflag &= ~VPARENB;
+ if (par->c_cflag & PARODD) cflag |= VPARODD; else cflag &= ~VPARODD;
+ if (par->c_cflag & CREAD) cflag |= VCREAD; else cflag &= ~VCREAD;
+ if (par->c_cflag & CLOCAL) cflag |= VCLOCAL; else cflag &= ~VCLOCAL;
+ if (par->c_cflag & HUPCL) cflag |= VHUPCL; else cflag &= ~VHUPCL;
+ /*
+ if (par->c_iflag & BRKINT) iflag |= VBRKINT; else iflag &= ~VBRKINT;
+ if (par->c_iflag & ISTRIP) iflag |= VISTRIP; else iflag &= ~VISTRIP;
+ if (par->c_iflag & ICRNL) iflag |= VICRNL; else iflag &= ~VICRNL;
+ if (par->c_iflag & IXON) iflag |= VIXON; else iflag &= ~VIXON;
+ if (par->c_iflag & IXANY) iflag |= VIXANY; else iflag &= ~VIXANY;
+ if (par->c_oflag & OPOST) oflag |= VOPOST; else oflag &= ~VOPOST;
+ if (par->c_oflag & ONLCR) oflag |= VONLCR; else oflag &= ~VONLCR;
+ if (par->c_oflag & OXTABS) oflag |= VOXTABS; else oflag &= ~VOXTABS;
+ if (par->c_lflag & ECHO) lflag |= VECHO; else lflag &= ~VECHO;
+ if (par->c_lflag & ECHOE) lflag |= VECHOE; else lflag &= ~VECHOE;
+ if (par->c_lflag & ICANON) lflag |= VICANON; else lflag &= ~VICANON;
+ if (par->c_lflag & ISIG) lflag |= VISIG; else lflag &= ~VISIG;
+ */
+ pkt.command = CMD_IOCTL;
+ pkt.ioctl_cmd_l = IOCTL_TCSETA;
+ pkt.command_pipe_number = sc->channel_number;
+ pkt.status_pipe_number = sc->channel_number;
+ pkt.device_number = port;
+ pkt.c_cflag = cflag;
+/*
+ pkt.c_iflag = iflag;
+ pkt.c_oflag = oflag;
+ pkt.c_lflag = lflag;
+ */
+
+ bpp_send(sc, &pkt, WAIT_POLL);
+ return imask;
+}
+
+void
+vx_unblock(tp)
+struct tty *tp;
+{
+ tp->t_state &= ~TS_FLUSH;
+ if (tp->t_outq.c_cc != 0)
+ vxstart(tp);
+}
+
+void
+vxstart(tp)
+struct tty *tp;
+{
+ dev_t dev;
+ u_char cbuf;
+ struct vxsoftc *sc;
+ struct wring *wp;
+ int cc, port, unit, s, cnt, i;
+ u_short get, put;
+ char buffer[WRING_BUF_SIZE];
+ char *wrdp;
+
+ dev = tp->t_dev;
+ port = VX_PORT(dev);
+ unit = VX_UNIT(dev);
+ if (unit >= vx_cd.cd_ndevs ||
+ (sc = (struct vxsoftc *) vx_cd.cd_devs[unit]) == NULL) {
+ return;
+ }
+
+ if ((tp->t_state & TS_ISOPEN) == 0)
+ return;
+
+ s = splvx();
+ if ((tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP | TS_FLUSH)) == 0) {
+ tp->t_state |= TS_BUSY;
+ wp = sc->sc_info[port].wringp;
+ get = wp->get;
+ put = wp->put;
+ cc = tp->t_outq.c_cc;
+ while (cc > 0) {
+ cnt = min(WRING_BUF_SIZE, cc);
+ cnt = q_to_b(&tp->t_outq, buffer, cnt);
+ buffer[cnt] = 0;
+ for (i=0; i<cnt; i++) {
+ vxputc(sc, port, buffer[i]);
+ }
+ cc -= cnt;
+ }
+ tp->t_state &= ~TS_BUSY;
+ }
+ splx(s);
+ return;
+}
+
+void
+read_chars(sc, port)
+struct vxsoftc *sc;
+int port;
+{
+ /*
+ * This routine is called by vx_intr() when there are
+ * characters in the read ring. It will process one
+ * cooked line, put the chars in the line disipline ring,
+ * and then return. The characters may then
+ * be read by vxread.
+ */
+ struct vx_info *vxt;
+ struct rring *rp;
+ struct read_wakeup_packet rwp;
+ struct tty *tp;
+ u_short get, put;
+ int frame_count, i, pc = 0, open;
+ char c;
+
+ vxt = &sc->sc_info[port];
+ tp = vxt->tty;
+ rp = vxt->rringp;
+ open = vxt->open;
+ get = rp->get;
+ put = rp->put;
+#ifdef DEBUG_VXT
+ printf("read_chars() get=%d, put=%d ", get, put);
+ printf("open = %d ring at 0x%x\n", open, rp);
+#endif
+ while (get != put) {
+ frame_count = rp->data[rp->get++ & (RRING_BUF_SIZE - 1)];
+ rp->get &= (RRING_BUF_SIZE - 1);
+ for (i=0; i<frame_count; i++) {
+ c = rp->data[rp->get++ & (RRING_BUF_SIZE - 1)];
+ rp->get &= (RRING_BUF_SIZE - 1);
+ if (open)
+ (*linesw[tp->t_line].l_rint)(c,tp);
+ }
+ c = rp->data[rp->get++ & (RRING_BUF_SIZE - 1)];
+ rp->get &= (RRING_BUF_SIZE - 1);
+ if (!(c & DELIMITER)) {
+ vx_frame (sc, port);
+ break;
+ } else {
+ break;
+ }
+ get = rp->get;
+ put = rp->put;
+ }
+ vxt->read_pending = 0;
+ read_wakeup(sc, port);
+ return;
+}
+
+ccode(sc, port, c)
+struct vxsoftc *sc;
+int port;
+char c;
+{
+ struct vx_info *vxt;
+ struct tty *tp;
+ tp = vxt->tty;
+ vxt = &sc->sc_info[port];
+ tp = vxt->tty;
+ (*linesw[tp->t_line].l_rint)(c,tp);
+}
+
+int
+vx_intr(sc)
+struct vxsoftc *sc;
+{
+ struct envelope *envp, *next_envp;
+ struct envelope env;
+ struct packet *pktp, pkt;
+ int valid, i;
+ short cmd;
+ u_char port;
+ struct vme2reg *vme2 = (struct vme2reg *)sc->sc_vme2;
+
+ if (vme2->vme2_vbr & VME2_SYSFAIL){
+ /* do something... print_dump(sc); */
+ }
+ if (!cold) sc->sc_intrcnt.ev_count++;
+
+ while (env_isvalid(get_status_head(sc))) {
+ pktp = get_packet(sc, get_status_head(sc));
+ valid = env_isvalid(get_status_head(sc));
+ cmd = pktp->command;
+ port = pktp->device_number;
+ /* if we are waiting on this packet, strore the info so bpp_send
+ can process the packet */
+ if (sc->sc_bppwait_pktp == pktp)
+ memcpy2(&sc->sc_bppwait_pkt, pktp, sizeof(struct packet));
+
+ memcpy2(&pkt, pktp, sizeof(struct packet));
+ next_envp = get_next_envelope(get_status_head(sc));
+ envp = get_status_head(sc);
+ /* return envelope and packet to the free queues */
+ put_free_envelope(sc, envp);
+ put_free_packet(sc, pktp);
+ /* mark new status pipe head pointer */
+ set_status_head(sc, next_envp);
+ /* if it was valid, process packet */
+ switch (cmd) {
+ case CMD_READW:
+#ifdef DEBUG_VXT
+ printf("READW Packet\n");
+#endif
+ read_chars(sc, port);
+ return 1;
+ break;
+ case CMD_WRITEW:
+#ifdef DEBUG_VXT
+ printf("WRITEW Packet\n"); /* Still don't know XXXsmurph */
+#endif
+ return 1;
+ break;
+ case CMD_EVENT:
+#ifdef DEBUG_VXT
+ printf("EVENT Packet\n");
+#endif
+ vx_event(sc, &pkt);
+ return 1;
+ break;
+ case CMD_PROCCESED:
+#ifdef DEBUG_VXT
+ printf("CMD_PROCCESED Packet\n");
+#endif
+ return 1;
+ break;
+ default:
+#ifdef DEBUG_VXT
+ printf("Other packet 0x%x\n", cmd);
+#endif
+ return 1;
+ break;
+ }
+ }
+ return 1;
+}
+
+int
+vx_event(sc, evntp)
+struct vxsoftc *sc;
+struct packet *evntp;
+{
+ u_short code = evntp->event_code;
+ struct event_packet evnt;
+ struct vx_info *vxt;
+
+ vxt = &sc->sc_info[evntp->device_number];
+
+ if (code & E_INTR) {
+ ccode(sc, evntp->device_number, CINTR);
+ }
+ if (code & E_QUIT) {
+ ccode(sc, evntp->device_number, CQUIT);
+ }
+ if (code & E_HUP) {
+ rts_ctl(sc, evntp->device_number, 0);
+ dtr_ctl(sc, evntp->device_number, 0);
+ }
+ if (code & E_DCD) {
+ vxt->vx_linestatus |= TIOCM_CD;
+ }
+ if (code & E_DSR) {
+ vxt->vx_linestatus |= TIOCM_DSR;
+ }
+ if (code & E_CTS) {
+ vxt->vx_linestatus |= TIOCM_CTS;
+ }
+ if (code & E_LOST_DCD) {
+ vxt->vx_linestatus &= ~TIOCM_CD;
+ }
+ if (code & E_LOST_DSR) {
+ vxt->vx_linestatus &= ~TIOCM_DSR;
+ }
+ if (code & E_LOST_CTS) {
+ vxt->vx_linestatus &= ~TIOCM_CTS;
+ }
+ if (code & E_PR_FAULT) {
+ /* do something... */
+ }
+ if (code & E_PR_POUT) {
+ /* do something... */
+ }
+ if (code & E_PR_SELECT) {
+ /* do something... */
+ }
+ if (code & E_SWITCH) {
+ /* do something... */
+ }
+ if (code & E_BREAK) {
+ vx_break (sc, evntp->device_number);
+ }
+
+ /* send and event packet backe to the device */
+ bzero(&evnt, sizeof(struct event_packet));
+ evnt.command = CMD_EVENT;
+ evnt.device_number = evntp->device_number;
+ evnt.command_pipe_number = sc->channel_number;
+ /* return status on same channel */
+ evnt.status_pipe_number = sc->channel_number;
+ /* send packet to the firmware */
+ bpp_send(sc, &evnt, NOWAIT);
+ return 1;
+}
+
+void
+vx_overflow (sc, port, ptime, msg)
+struct vxsoftc *sc;
+int port;
+long *ptime;
+u_char *msg;
+{
+ log(LOG_WARNING, "%s port %d: overrun\n", sc->sc_dev.dv_xname, port);
+ return;
+}
+
+void
+vx_frame (sc, port)
+struct vxsoftc *sc;
+int port;
+{
+ log(LOG_WARNING, "%s port %d: frame error\n", sc->sc_dev.dv_xname, port);
+ return;
+}
+
+void
+vx_break (sc, port)
+struct vxsoftc *sc;
+int port;
+{
+#ifdef DEBUG_KERN
+ Debugger();
+#else
+ log(LOG_WARNING, "%s port %d: break detected\n", sc->sc_dev.dv_xname, port);
+#endif
+ return;
+}
+
+/*
+ * Initialization and Buffered Pipe Protocol (BPP) code
+ */
+
+/* special function for 16 bit data transfer */
+/* Not needed now that I figured out VME bus */
+/* mappings and address modifiers, but I don't */
+/* want to change them :) */
+void *
+memcpy2(void *dest, const void *src, size_t size)
+{
+ int i;
+ short *d, *s;
+ d = (short*) dest;
+ s = (short*) src;
+ for (i=0; i<(size/2); i++) {
+ *d = *s;
+ d++;
+ s++;
+ }
+}
+
+void
+wzero(void *addr, size_t size)
+{
+ int i;
+ short *d;
+ d = (short*) addr;
+ for (i=0; i<(size/2); i++) {
+ *d = 0;
+ d++;
+ }
+}
+
+int
+create_free_queue(sc)
+struct vxsoftc *sc;
+{
+ int i;
+ struct envelope *envp;
+ struct envelope env;
+ struct packet *pktp;
+ struct packet pkt;
+
+ envp = (struct envelope *)ENVELOPE_AREA;
+ sc->elist_head = envp;
+ for (i=0; i < NENVELOPES; i++) {
+ bzero(envp, sizeof(struct envelope));
+ if (i==(NENVELOPES - 1)) {
+ envp->link = NULL;
+ } else {
+ envp->link = (u_long)envp + sizeof(struct envelope);
+ }
+ envp->packet_ptr = NULL;
+ envp->valid_flag = 0;
+ envp++;
+ }
+ sc->elist_tail = --envp;
+
+ pktp = (struct packet *)PACKET_AREA;
+ sc->plist_head = pktp;
+ for (i=0; i < NPACKETS; i++) {
+ bzero(pktp, sizeof(struct packet));
+ if (i==(NPACKETS - 1)) {
+ pktp->link = NULL;
+ } else {
+ pktp->link = (u_long)pktp + sizeof(struct packet);
+ }
+ pktp++;
+ }
+ sc->plist_tail = --pktp;
+ return 0; /* no error */
+}
+
+void *
+get_free_envelope(sc)
+struct vxsoftc *sc;
+{
+ void *envp;
+
+ envp = sc->elist_head;
+ sc->elist_head = (struct envelope *)sc->elist_head->link;
+ bzero(envp, sizeof(struct envelope));
+ return envp;
+}
+
+void
+put_free_envelope(sc, ep)
+struct vxsoftc *sc;
+void * ep;
+{
+ struct envelope *envp = (struct envelope *)ep;
+ bzero(envp, sizeof(struct envelope));
+ sc->elist_tail->link = (ulong)envp;
+ envp->link = NULL;
+ sc->elist_tail = envp;
+}
+
+void*
+get_free_packet(sc)
+struct vxsoftc *sc;
+{
+ struct packet *pktp;
+
+ pktp = sc->plist_head;
+ sc->plist_head = (struct packet *)sc->plist_head->link;
+ bzero(pktp, sizeof(struct packet));
+ return pktp;
+}
+
+void
+put_free_packet(sc, pp)
+struct vxsoftc *sc;
+void *pp;
+{
+ struct packet *pktp = (struct packet *)pp;
+ /*bzero(pktp, sizeof(struct packet));*/
+ pktp->command = CMD_PROCCESED;
+ sc->plist_tail->link = (u_long)pktp;
+ pktp->link = NULL;
+ sc->plist_tail = pktp;
+}
+
+/*
+ * This is the nitty gritty. All the rest if this code
+ * was hell to come by. Getting this right from the
+ * Moto manual took *time*!
+ */
+int
+create_channels(sc)
+struct vxsoftc *sc;
+{
+ struct envelope *envp;
+ struct envelope env;
+ struct packet *pktp;
+ u_char valid;
+ u_short status;
+ u_short tas, csr;
+ struct vxreg *ipc_csr;
+
+ ipc_csr = sc->vx_reg;
+ /* wait for busy bit to clear */
+ while ((ipc_csr->ipc_cr & IPC_CR_BUSY));
+ create_free_queue(sc);
+ /* set up channel header. we only want one */
+ tas = ipc_csr->ipc_tas;
+ while (!(tas & IPC_TAS_VALID_STATUS)) {
+ envp = get_free_envelope(sc);
+ sc->channel->command_pipe_head_ptr_h = HI(envp);
+ sc->channel->command_pipe_head_ptr_l = LO(envp);
+ sc->channel->command_pipe_tail_ptr_h = sc->channel->command_pipe_head_ptr_h;
+ sc->channel->command_pipe_tail_ptr_l = sc->channel->command_pipe_head_ptr_l;
+ envp = get_free_envelope(sc);
+ sc->channel->status_pipe_head_ptr_h = HI(envp);
+ sc->channel->status_pipe_head_ptr_l = LO(envp);
+ sc->channel->status_pipe_tail_ptr_h = sc->channel->status_pipe_head_ptr_h;
+ sc->channel->status_pipe_tail_ptr_l = sc->channel->status_pipe_head_ptr_l;
+ sc->channel->interrupt_level = sc->sc_ipl;
+ sc->channel->interrupt_vec = sc->sc_vec;
+ sc->channel->channel_priority = 0;
+ sc->channel->channel_number = 0;
+ sc->channel->valid = 1;
+ sc->channel->address_modifier = 0x8D; /* A32/D16 supervisor data access */
+ sc->channel->datasize = 0; /* 32 bit data mode */
+
+ /* loop until TAS bit is zero */
+ while ((ipc_csr->ipc_tas & IPC_TAS_TAS));
+ ipc_csr->ipc_tas |= IPC_TAS_TAS;
+ /* load address of channel header */
+ ipc_csr->ipc_addrh = HI(sc->channel);
+ ipc_csr->ipc_addrl = LO(sc->channel);
+ /* load address modifier reg (supervisor data access) */
+ ipc_csr->ipc_amr = 0x8D;
+ /* load tas with create channel command */
+ ipc_csr->ipc_tas |= IPC_CSR_CREATE;
+ /* set vaild command bit */
+ ipc_csr->ipc_tas |= IPC_TAS_VALID_CMD;
+ /* notify IPC of the CSR command */
+ ipc_csr->ipc_cr |= IPC_CR_ATTEN;
+ /* loop until IPC sets vaild status bit */
+ delay(5000);
+ tas = ipc_csr->ipc_tas;
+ }
+
+ /* save the status */
+ status = ipc_csr->ipc_sr;
+ /* set COMMAND COMPLETE bit */
+ ipc_csr->ipc_tas |= IPC_TAS_COMPLETE;
+ /* notify IPC that we are through */
+ ipc_csr->ipc_cr |= IPC_CR_ATTEN;
+ /* check and see if the channel was created */
+ if (!status && sc->channel->valid) {
+ sc->channel_number = sc->channel->channel_number;
+ printf("%s: created channel %d\n", sc->sc_dev.dv_xname,
+ sc->channel->channel_number);
+ return 0;
+ } else {
+ switch (status) {
+ case 0x0000:
+ printf("%s: channel not valid\n",
+ sc->sc_dev.dv_xname);
+ break;
+ case 0xFFFF:
+ printf("%s: invalid CSR command\n",
+ sc->sc_dev.dv_xname);
+ break;
+ case 0xC000:
+ printf("%s: could not read channel structure\n",
+ sc->sc_dev.dv_xname);
+ break;
+ case 0x8000:
+ printf("%s: could not write channel structure\n",
+ sc->sc_dev.dv_xname);
+ break;
+ default:
+ printf("%s: unknown IPC CSR command error 0x%x\n",
+ sc->sc_dev.dv_xname, status);
+ break;
+ }
+ return status; /* error */
+ }
+}
+
+void
+print_dump(sc)
+struct vxsoftc *sc;
+{
+ char *dump_area, *end_dump, *dumpp;
+ char dump[209];
+ char dump2[209];
+ bzero(&dump, 209);
+
+ dump_area = (char *)0xff780030;
+ memcpy2(&dump, dump_area, 208);
+
+ printf("%s", dump);
+}
+
+void *
+get_next_envelope(thisenv)
+struct envelope *thisenv;
+{
+ return ((void *)thisenv->link);
+}
+
+int
+env_isvalid(thisenv)
+struct envelope *thisenv;
+{
+ return thisenv->valid_flag;
+}
+
+struct envelope *
+get_cmd_tail(sc)
+struct vxsoftc *sc;
+{
+ unsigned long retaddr;
+ retaddr = (unsigned long)sc->vx_reg;
+ retaddr += sc->channel->command_pipe_tail_ptr_l;
+ return ((struct envelope *)retaddr);
+}
+
+struct envelope *
+get_status_head(sc)
+struct vxsoftc *sc;
+{
+ unsigned long retaddr;
+ retaddr = (unsigned long)sc->vx_reg;
+ retaddr += sc->channel->status_pipe_head_ptr_l;
+ return ((struct envelope *)retaddr);
+}
+
+void
+set_status_head(sc, envp)
+struct vxsoftc *sc;
+void *envp;
+{
+ sc->channel->status_pipe_head_ptr_h = HI(envp);
+ sc->channel->status_pipe_head_ptr_l = LO(envp);
+ return;
+}
+
+struct packet *
+get_packet(sc, thisenv)
+struct vxsoftc *sc;
+struct envelope *thisenv;
+{
+ struct envelope env;
+ unsigned long baseaddr;
+
+ if (thisenv == NULL) return NULL;
+ baseaddr = (unsigned long)sc->vx_reg;
+ /*
+ * packet ptr returned on status pipe is only last two bytes
+ * so we must supply the full address based on the board address.
+ * This also works for all envelopes because every address is an
+ * offset to the board address
+ */
+ baseaddr |= thisenv->packet_ptr;
+ return ((void*)baseaddr);
+}
+
+/*
+ * Send a command via BPP
+ */
+int
+bpp_send(struct vxsoftc *sc, void *pkt, int wait_flag)
+{
+ struct envelope *envp;
+ struct init_packet init, *initp;
+ struct packet *wpktp, *pktp, *testpktp;
+ struct vme2reg *vme2 = (struct vme2reg *)sc->sc_vme2;
+ unsigned long newenv;
+ int i, s;
+
+
+ /* load up packet in dual port mem */
+ pktp = get_free_packet(sc);
+ memcpy2(pktp, pkt, sizeof(struct packet));
+
+ envp = get_cmd_tail(sc);
+ newenv = (unsigned long)get_free_envelope(sc); /* put a NULL env on the tail */
+ envp->link = newenv;
+ sc->channel->command_pipe_tail_ptr_h = HI(newenv);
+ sc->channel->command_pipe_tail_ptr_l = LO(newenv);
+ envp->packet_ptr = (u_long)pktp; /* add the command packet */
+ envp->valid_flag = 1; /* set valid command flag */
+
+ sc->vx_reg->ipc_cr |= IPC_CR_ATTEN;
+ if (wait_flag) { /* wait for a packet to return */
+ while (pktp->command != CMD_PROCCESED) {
+#ifdef DEBUG_VXT
+ printf("Polling for packet 0x%x in envelope 0x%x...\n", pktp, envp);
+#endif
+ vx_intr(sc);
+ delay(5000);
+ }
+ memcpy2(pkt, pktp, sizeof(struct packet));
+ return 0;
+ }
+ return 0; /* no error */
+}
+
+/*
+ * BPP commands
+ */
+int
+vx_init(sc)
+struct vxsoftc *sc;
+{
+ int i;
+ struct init_info *infp, inf;
+ struct wring *wringp;
+ struct rring *rringp;
+ struct termio def_termio;
+ struct init_packet init;
+ struct event_packet evnt;
+
+ bzero(&def_termio, sizeof(struct termio));
+ /* init wait queue */
+ bzero(&sc->sc_bppwait_pkt, sizeof(struct packet));
+ sc->sc_bppwait_pktp = NULL;
+ /* set up init_info array */
+ wringp = (struct wring *)WRING_AREA;
+ rringp = (struct rring *)RRING_AREA;
+ infp = (struct init_info *)INIT_INFO_AREA;
+ for (i=0; i<9; i++) {
+ bzero(&inf, sizeof(struct init_info));
+ infp->write_ring_ptr_h = HI(wringp);
+ infp->write_ring_ptr_l = LO(wringp);
+ sc->sc_info[i].wringp = wringp;
+ infp->read_ring_ptr_h = HI(rringp);
+ infp->read_ring_ptr_l = LO(rringp);
+ sc->sc_info[i].rringp = rringp;
+#ifdef DEBUG_VXT
+ printf("write at 0x%8x, read at 0x%8x\n", wringp, rringp);
+#endif
+ infp->write_ring_size = WRING_DATA_SIZE;
+ infp->read_ring_size = RRING_DATA_SIZE;
+ infp->def_termio.c_iflag = VBRKINT;
+ infp->def_termio.c_oflag = 0;
+ infp->def_termio.c_cflag = (VB9600 | VCS8);
+
+ infp->def_termio.c_lflag = VISIG; /* enable signal processing */
+ infp->def_termio.c_line = 1; /* raw line disipline, we want to control it! */
+ infp->def_termio.c_cc[0] = CINTR;
+ infp->def_termio.c_cc[1] = CQUIT;
+ infp->def_termio.c_cc[2] = CERASE;
+ infp->def_termio.c_cc[3] = CKILL;
+ infp->def_termio.c_cc[4] = 20;
+ infp->def_termio.c_cc[5] = 2;
+ infp->reserved1 = 0; /* Must be Zero */
+ infp->reserved2 = 0;
+ infp->reserved3 = 0;
+ infp->reserved4 = 0;
+ wringp++; rringp++; infp++;
+ }
+ /* set up init_packet */
+ bzero(&init, sizeof(struct init_packet));
+ init.eye_catcher[0] = 0x12;
+ init.eye_catcher[1] = 0x34;
+ init.eye_catcher[2] = 0x56;
+ init.eye_catcher[3] = 0x78;
+ init.command = CMD_INIT;
+ init.command_pipe_number = sc->channel_number;
+ /* return status on the same channel */
+ init.status_pipe_number = sc->channel_number;
+ init.interrupt_level = sc->sc_ipl;
+ init.interrupt_vec = sc->sc_vec;
+ init.init_info_ptr_h = HI(INIT_INFO_AREA);
+ init.init_info_ptr_l = LO(INIT_INFO_AREA);
+
+ /* send packet to the firmware and wait for completion */
+ bpp_send(sc, &init, WAIT_POLL);
+
+ /* check for error */
+ if (init.error_l !=0) {
+ return init.error_l;
+ } else {
+ /* send one event packet to each device; */
+ for (i=0; i<9; i++) {
+ bzero(&evnt, sizeof(struct event_packet));
+ evnt.command = CMD_EVENT;
+ evnt.device_number = i;
+ evnt.command_pipe_number = sc->channel_number;
+ /* return status on same channel */
+ evnt.status_pipe_number = sc->channel_number;
+ /* send packet to the firmware */
+ bpp_send(sc, &evnt, NOWAIT);
+ }
+ return 0;
+ }
+}
+
+
diff --git a/sys/arch/mvme88k/dev/vxreg.h b/sys/arch/mvme88k/dev/vxreg.h
new file mode 100644
index 00000000000..f328b9dcdd9
--- /dev/null
+++ b/sys/arch/mvme88k/dev/vxreg.h
@@ -0,0 +1,530 @@
+/* $OpenBSD: vxreg.h,v 1.1 1999/05/29 04:41:45 smurph Exp $ */
+
+/*
+ * Copyright (c) 1999 Steve Murphree, Jr. 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 Dale Rahn.
+ * 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.
+ */
+
+/* IPC - Intelligent Peripheral Controller */
+
+struct vxreg {
+/*0x0*/volatile u_short ipc_addrh; /* IPC addr reg, most significant */
+/*0x2*/volatile u_short ipc_addrl; /* IPC addr reg, least significant */
+/*0x4*/volatile u_char ipc_amr; /* IPC address modifier reg */
+/*0x5*/volatile u_char unused1;
+/*0x6*/volatile u_short ipc_cr; /* IPC control ceg */
+/*0x8*/volatile u_short ipc_sr; /* IPC status reg */
+/*0xA*/volatile u_char ipc_mdbp; /* IPC model data byte pointer */
+/*0xB*/volatile u_char reserved3;
+/*0xC*/volatile u_char ipc_avrp; /* IPC abort vector reg pointer */
+/*0xD*/volatile u_char unused2;
+/*0xE*/volatile u_short ipc_tas; /* IPC test and set reg */
+};
+
+#define NOWAIT 0
+#define WAIT 1
+#define WAIT_POLL 2
+
+#define IPC_CR_SYSFI 0x1000 /* inhibit sysfail */
+#define IPC_CR_ATTEN 0x2000 /* attention bit */
+#define IPC_CR_RESET 0x4000 /* reset bit */
+#define IPC_CR_BUSY 0x8000 /* busy bit */
+
+#define IPC_SR_BUSERROR 0x4000 /* bus error */
+#define IPC_SR_ERROR 0x8000 /* general error */
+#define IPC_SR_INVAL 0xFFFF /* invalid command */
+
+#define IPC_TAS_COMPLETE 0x1000
+#define IPC_TAS_VALID_STATUS 0x2000
+#define IPC_TAS_VALID_CMD 0x4000
+#define IPC_TAS_TAS 0x8000
+
+#define IPC_CSR_CREATE 0x0001
+#define IPC_CSR_DELETE 0x0002
+
+#define CSW_OFFSET 0x0010
+
+#define CMD_INIT 0x0000
+#define CMD_READW 0x0001
+#define CMD_WRITEW 0x0002
+#define CMD_OPEN 0x0003
+#define CMD_IOCTL 0x0004
+#define CMD_CLOSE 0x0005
+#define CMD_EVENT 0x0006
+#define CMD_PROCCESED 0x00FF
+
+#define IOCTL_LDOPEN 0x4400
+#define IOCTL_LDCLOSE 0x4401
+#define IOCTL_LDCHG 0x4402
+#define IOCTL_LDGETT 0x4408
+#define IOCTL_LDSETT 0x4409
+#define IOCTL_TCGETA 0x5401 /* get dev termio struct */
+#define IOCTL_TCSETA 0x5402 /* set dev termio struct */
+#define IOCTL_TCSETAW 0x5403 /* set dev termio struct - wait */
+#define IOCTL_TCSETAF 0x5404 /* set dev termio struct - wait - flush */
+#define IOCTL_TCSBRK 0x5405 /* transmit a break seq */
+#define IOCTL_TCXONC 0x5406 /* sus or res, xon or xoff, RTS or DTR */
+#define IOCTL_TCFLSH 0x5407 /* Flush */
+#define IOCTL_TCSETHW 0x5440 /* enable/disable HW handshake */
+#define IOCTL_TCGETHW 0x5441 /* get current HW handshake info */
+#define IOCTL_TCGETDL 0x5442 /* get daownloadable addr and mem size */
+#define IOCTL_TCDLOAD 0x5443 /* download code/data to mem */
+#define IOCTL_TCLINE 0x5444 /* copy line discipline */
+#define IOCTL_TCEXEC 0x5445 /* exec code in local mem */
+#define IOCTL_TCGETVR 0x5446 /* get version and revison of firmware */
+#define IOCTL_TCGETDF 0x5447 /* get default termio stuct */
+#define IOCTL_TCSETDF 0x5448 /* set default termio stuct */
+#define IOCTL_TCGETSYM 0x5449 /* get firmware symbol table */
+#define IOCTL_TCWHAT 0x544A /* get all SCSI IDs of FW files */
+#define IOCTL_TIOGETP 0x7408 /* get devs curr termio struct by sgttyb */
+#define IOCTL_TIOSETP 0x7409 /* set devs curr termio struct by sgttyb */
+
+#define IPC_EIO 5 /* I/O error */
+#define IPC_ENXIO 6 /* no such device or address */
+#define IPC_ENOMEM 12 /* not enough space */
+#define IPC_EEXIST 17 /* device or address exists */
+#define IPC_EINVAL 22 /* invalid caommand argument */
+
+/*
+ * Index into c_cc[VNCC];
+ */
+#define VVINTR 0 /* ISIG */
+#define VVQUIT 1 /* ISIG */
+#define VVERASE 2 /* ICANON */
+#define VVKILL 3 /* ICANON */
+#define VVEOF 4 /* ICANON */
+#define VVEOL 5 /* ICANON */
+#define VVSWTCH 6
+
+/*
+ * Input flags - software input processing
+ */
+#define VIGNBRK 0000001 /* ignore BREAK condition */
+#define VBRKINT 0000002 /* map BREAK to SIGINTR */
+#define VIGNPAR 0000004 /* ignore (discard) parity errors */
+#define VPARMRK 0000010 /* mark parity and framing errors */
+#define VINPCK 0000020 /* enable checking of parity errors */
+#define VISTRIP 0000040 /* strip 8th bit off chars */
+#define VINLCR 0000100 /* map NL into CR */
+#define VIGNCR 0000200 /* ignore CR */
+#define VICRNL 0000400 /* map CR to NL (ala CRMOD) */
+#define VIUCLC 0001000 /* translate upper to lower case */
+#define VIXON 0002000 /* enable output flow control */
+#define VIXANY 0004000 /* any char will restart after stop */
+#define VIXOFF 0010000 /* enable input flow control */
+
+/*
+ * Output flags - software output processing
+ */
+#define VOPOST 0000001 /* enable following output processing */
+#define VOLCUC 0000002 /* translate lower case to upper case */
+#define VONLCR 0000004 /* map NL to CR-NL (ala CRMOD) */
+#define VOCRNL 0000010 /* map CR to NL */
+#define VONOCR 0000020 /* No CR output at column 0 */
+#define VONLRET 0000040 /* NL performs the CR function */
+#define VOFILL 0000100
+#define VOFDEL 0000200
+#define VOXTABS 0014000 /* expand tabs to spaces */
+
+/*
+ * Control flags - hardware control of terminal
+ */
+
+#define VCBAUD 0000017 /* baud rate */
+#define VB0 0000000 /* hang up */
+#define VB50 0000001
+#define VB75 0000002
+#define VB110 0000003
+#define VB134 0000004
+#define VB150 0000005
+#define VB200 0000006
+#define VB300 0000007
+#define VB600 0000010
+#define VB1200 0000011
+#define VB1800 0000012
+#define VB2400 0000013
+#define VB4800 0000014
+#define VB9600 0000015
+#define VB19200 0000016
+#define VB38400 0000017
+#define VEXTA 0000016
+#define VEXTB 0000017
+#define VCSIZE 0000060 /* character size mask */
+#define VCS5 0000000 /* 5 bits (pseudo) */
+#define VCS6 0000020 /* 6 bits */
+#define VCS7 0000040 /* 7 bits */
+#define VCS8 0000060 /* 8 bits */
+#define VCSTOPB 0000100 /* send 2 stop bits */
+#define VCREAD 0000200 /* enable receiver */
+#define VPARENB 0000400 /* parity enable */
+#define VPARODD 0001000 /* odd parity, else even */
+#define VHUPCL 0002000 /* hang up on last close */
+#define VCLOCAL 0004000 /* ignore modem status lines */
+
+/*
+ * "Local" flags - dumping ground for other state
+ *
+ * Warning: some flags in this structure begin with
+ * the letter "I" and look like they belong in the
+ * input flag.
+ */
+
+#define VISIG 0000001 /* enable signals INTR, QUIT, [D]SUSP */
+#define VICANON 0000002 /* canonicalize input lines */
+#define VXCASE 0000004 /* canonical upper/lower case */
+#define VECHO 0000010 /* enable echoing */
+#define VECHOE 0000020 /* visually erase chars */
+#define VECHOK 0000040 /* echo NL after line kill */
+#define VECHONL 0000100 /* echo NL even if ECHO is off */
+#define VNOFLSH 0000200 /* don't flush after interrupt */
+
+
+#define VNCC 9 /* 18 bytes */
+struct termio {
+ volatile unsigned short c_iflag;
+ volatile unsigned short c_oflag;
+ volatile unsigned short c_cflag;
+ volatile unsigned short c_lflag;
+ volatile char c_line;
+ volatile unsigned char c_cc[VNCC];
+};
+
+struct sgttyb { /* 6 bytes */
+ volatile char sg_ispeed;
+ volatile char sg_ospeed;
+ volatile char sg_erase;
+ volatile char sg_kill;
+ volatile short sg_flags;
+};
+
+struct termcb { /* 6 bytes */
+ volatile char st_flgs;
+ volatile char st_termt;
+ volatile char st_crow;
+ volatile char st_ccol;
+ volatile char st_vrow;
+ volatile char st_lrow;
+};
+
+struct ctdesc {
+ unsigned short csw,
+ resv;
+ unsigned long magic,
+ lcnt,
+ fatal,
+ error,
+ faddr,
+ expdata,
+ readdata;
+};
+
+struct dl_info { /* 18 bytes */
+ volatile unsigned long host_addr;
+ volatile unsigned long ipc_addr;
+ volatile unsigned long count;
+ volatile unsigned long extra_long;
+ volatile unsigned short extra_short;
+};
+
+struct packet { /* 68 bytes */
+ volatile u_long link; /* was eyecatcher */
+ volatile u_char command_pipe_number;
+ volatile u_char status_pipe_number;
+ volatile char filler0[4];
+ volatile short command;
+ volatile char filler1[1];
+ volatile char command_dependent;
+ volatile char filler2[2];
+ volatile u_char device_number;
+ volatile char filler3[1];
+ volatile short ioctl_cmd_h;
+ volatile short ioctl_cmd_l;
+ volatile short ioctl_arg_h;
+ volatile short ioctl_arg_l;
+ volatile short ioctl_mode_h;
+ volatile short ioctl_mode_l;
+ volatile char filler4[6];
+ volatile short error_h;
+ volatile short error_l;
+ volatile short event_code;
+ volatile char filler5[6];
+ union {
+ struct termio tio;
+ struct termcb tcb;
+ struct sgttyb sgt;
+ struct dl_info dl;
+ long param;
+ } parameter_block;
+ short reserved; /* for alignment */
+} packet;
+
+struct ioctl_a_packet { /* 68 bytes */
+ volatile u_long link; /* was eyecatcher */
+ volatile u_char command_pipe_number;
+ volatile u_char status_pipe_number;
+ volatile char filler0[4];
+ volatile short command;
+ volatile char filler1[1];
+ volatile char command_dependent;
+ volatile char filler2[2];
+ volatile u_char device_number;
+ volatile char filler3[1];
+ volatile short ioctl_cmd_h;
+ volatile short ioctl_cmd_l;
+ volatile short ioctl_arg_h;
+ volatile short ioctl_arg_l;
+ volatile short ioctl_mode_h;
+ volatile short ioctl_mode_l;
+ volatile char filler4[6];
+ volatile short error_h;
+ volatile short error_l;
+ volatile short event_code;
+ volatile char filler5[6];
+ volatile unsigned short c_iflag;
+ volatile unsigned short c_oflag;
+ volatile unsigned short c_cflag;
+ volatile unsigned short c_lflag;
+ volatile char c_line;
+ volatile unsigned char c_cc[VNCC];
+ short reserved; /* for alignment */
+};
+
+struct envelope { /* 12 bytes */
+ volatile u_long link;
+ volatile u_long packet_ptr;
+ volatile char valid_flag;
+ volatile char reserved1;
+ volatile char reserved[2];
+};
+
+struct channel { /* 24 bytes */
+ volatile short command_pipe_head_ptr_h;
+ volatile short command_pipe_head_ptr_l;
+ volatile short command_pipe_tail_ptr_h;
+ volatile short command_pipe_tail_ptr_l;
+ volatile short status_pipe_head_ptr_h;
+ volatile short status_pipe_head_ptr_l;
+ volatile short status_pipe_tail_ptr_h;
+ volatile short status_pipe_tail_ptr_l;
+ volatile char interrupt_level;
+ volatile char interrupt_vec;
+ volatile char channel_priority;
+ volatile char address_modifier;
+ volatile char channel_number;
+ volatile char valid;
+ volatile char datasize;
+ volatile char reserved;
+};
+
+#define WRING_DATA_SIZE 4096 /* for a total struct size of 4104 (4K + 6 + 2 bytes) */
+#define WRING_BUF_SIZE WRING_DATA_SIZE
+struct wring {
+ volatile unsigned short reserved;
+ volatile unsigned short put;
+ volatile unsigned short get;
+ volatile char data[WRING_BUF_SIZE];
+ char res[2]; /* for alignment */
+};
+
+#define RRING_DATA_SIZE 2048 /* for a total struct size of 2054 (2K + 6 + 2 bytes) */
+#define RRING_BUF_SIZE RRING_DATA_SIZE
+struct rring {
+ volatile unsigned short reserved;
+ volatile unsigned short put;
+ volatile unsigned short get;
+ volatile char data[RRING_BUF_SIZE];
+ char res[2]; /* for alignment */
+};
+
+#define EOFRAME 0xA
+#define DELIMITER 0x1
+
+struct init_info { /* 88 bytes */
+ volatile u_short write_ring_ptr_h;
+ volatile u_short write_ring_ptr_l;
+ volatile u_short read_ring_ptr_h;
+ volatile u_short read_ring_ptr_l;
+ volatile unsigned short write_ring_size;
+ volatile unsigned short read_ring_size;
+ volatile struct termio def_termio;
+ volatile unsigned short reserved1;
+ volatile unsigned short reserved2;
+ volatile unsigned short reserved3;
+ volatile unsigned short reserved4;
+ volatile char init_data[56];
+};
+
+struct init_packet {
+ volatile char eye_catcher[4];
+ volatile unsigned char command_pipe_number;
+ volatile unsigned char status_pipe_number;
+ volatile char filler_0[4];
+ volatile short command;
+ volatile char filler_1[3];
+ volatile char interrupt_level;
+ volatile char filler_2[2];
+ volatile short init_info_ptr_h;
+ volatile short init_info_ptr_l;
+ volatile char filler_3[7];
+ volatile char interrupt_vec;
+ volatile char filler_4[6];
+ volatile short error_h;
+ volatile short error_l;
+};
+
+struct event_packet {
+ volatile char eye_catcher[4];
+ volatile unsigned char command_pipe_number;
+ volatile unsigned char status_pipe_number;
+ volatile char filler_0[4];
+ volatile short command;
+ volatile char filler_1[4];
+ volatile char device_number;
+ volatile char filler_2[19];
+ volatile short error_h;
+ volatile short error_l;
+#define E_INTR 0x0001
+#define E_QUIT 0x0002
+#define E_HUP 0x0004
+#define E_DCD 0x0008
+#define E_DSR 0x0010
+#define E_CTS 0x0020
+#define E_LOST_DCD 0x0040
+#define E_LOST_DSR 0x0080
+#define E_LOST_CTS 0x0100
+#define E_PR_FAULT 0x0200
+#define E_PR_POUT 0x0400
+#define E_PR_SELECT 0x0800
+#define E_SWITCH 0x4000
+#define E_BREAK 0x8000
+ volatile unsigned short event_code; /* returned from IPC */
+};
+
+struct open_packet {
+ volatile char eye_catcher[4];
+ volatile unsigned char command_pipe_number;
+ volatile unsigned char status_pipe_number;
+ volatile char filler_0[4];
+ volatile short command;
+ volatile char filler_1[4];
+ volatile char device_number;
+ volatile char filler_2[19];
+ volatile short error_h;
+ volatile short error_l;
+ volatile unsigned short event_code; /* returned from IPC */
+};
+
+struct close_packet {
+ volatile char eye_catcher[4];
+ volatile unsigned char command_pipe_number;
+ volatile unsigned char status_pipe_number;
+ volatile char filler_0[4];
+ volatile short command;
+ volatile char filler_1[4];
+ volatile char device_number;
+ volatile char filler_2[19];
+ volatile short error_h;
+ volatile short error_l;
+ volatile unsigned short event_code; /* returned from IPC */
+};
+
+struct read_wakeup_packet {
+ volatile char eye_catcher[4];
+ volatile unsigned char command_pipe_number;
+ volatile unsigned char status_pipe_number;
+ volatile char filler_0[4];
+ volatile short command;
+ volatile char filler_1[4];
+ volatile char device_number;
+ volatile char filler_2[19];
+ volatile short error_h;
+ volatile short error_l;
+};
+
+struct write_wakeup_packet {
+ volatile char eye_catcher[4];
+ volatile unsigned char command_pipe_number;
+ volatile unsigned char status_pipe_number;
+ volatile char filler_0[4];
+ volatile short command;
+ volatile char filler_1[4];
+ volatile char device_number;
+ volatile char filler_2[19];
+ volatile short error_h;
+ volatile short error_l;
+};
+
+/*
+ * All structures must reside in dual port user memory.
+ * ($FFxx0100 to $FFxxFFF0)
+ * All structures must be word aligned (see byte counts above)
+ *
+ * +--------------------------------+
+ * | IPC Control/Status Register | $FFxx0000
+ * | (16 bytes) |
+ * |--------------------------------|
+ * | Confidence Test Descriptor | $FFxx0010
+ * | (32 bytes) |
+ * |--------------------------------|
+ * | Dump Area | $FFxx0030
+ * | (208 bytes) |
+ * |--------------------------------|
+ * | | $FFxx0100
+ * | |
+ * : User Space :
+ * : :
+ * : (65,264 bytes) :
+ * | |
+ * | |
+ * |--------------------------------|
+ * | Interrupt Vector Registers | $FFxxFFF0
+ * | (16 bytes) |
+ * +--------------------------------+
+ */
+#define ALIGNIT(p) (((u_int)(p) + 7) & ~7)
+
+#define NENVELOPES 30
+#define NPACKETS NENVELOPES
+#define USER_AREA (sc->board_addr + 0x0100)
+#define CHANNEL_H (sc->board_addr + 0x0100)
+#define ENVELOPE_AREA (CHANNEL_H + sizeof(struct channel))
+#define ENVELOPE_AREA_SIZE (NENVELOPES * sizeof(struct envelope))
+#define PACKET_AREA (ENVELOPE_AREA + ENVELOPE_AREA_SIZE)
+#define PACKET_AREA_SIZE (NPACKETS * sizeof(struct packet))
+#define INIT_INFO_AREA (PACKET_AREA + PACKET_AREA_SIZE)
+#define INIT_INFO_AREA_SIZE (9 * sizeof(struct init_info))
+#define WRING_AREA ALIGNIT(INIT_INFO_AREA + INIT_INFO_AREA_SIZE)
+#define WRING_AREA_SIZE (9 * sizeof(struct wring))
+#define RRING_AREA (WRING_AREA + WRING_AREA_SIZE)
+#define RRING_AREA_SIZE (9 * sizeof(struct rring))
+#define USER_AREA_SIZE (RRING_AREA + RRING_AREA_SIZE - USER_AREA)
+
+#define LO(x) (u_short)((unsigned long)x & 0x0000FFFF)
+#define HI(x) (u_short)((unsigned long)x >> 16)
+
+
diff --git a/sys/arch/mvme88k/include/board.h b/sys/arch/mvme88k/include/board.h
index 9a49db4625b..a42a6968acb 100644
--- a/sys/arch/mvme88k/include/board.h
+++ b/sys/arch/mvme88k/include/board.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: board.h,v 1.4 1999/02/09 06:36:25 smurph Exp $ */
+/* $OpenBSD: board.h,v 1.5 1999/05/29 04:41:45 smurph Exp $ */
/*
* Copyright (c) 1996 Nivas Madhur
* All rights reserved.
@@ -62,66 +62,50 @@
# endif
#endif
-#define MAX_CPUS 1 /* no. of CPUs */
+#define MAX_CPUS 1 /* no. of CPUs */
#define MAX_CMMUS 2 /* 2 CMMUs - 1 data and 1 code */
-#define SYSV_BASE U(0x00000000) /* system virtual base */
+#define SYSV_BASE U(0x00000000) /* system virtual base */
-#define MAXU_ADDR U(0x40000000) /* size of user virtual space */
-#define MAXPHYSMEM U(0x10000000) /* max physical memory */
+#define MAXU_ADDR U(0x40000000) /* size of user virtual space */
+#define MAXPHYSMEM U(0x10000000) /* max physical memory */
-#define BUGROM_START U(0xFF800000) /* start of BUG PROM */
-#define BUGROM_SIZE U(0x003FFFFF) /* size of BUG PROM */
-#define SRAM_START U(0xFFE00000) /* start of sram used by bug */
-#define SRAM_SIZE U(0x0001FFFF) /* size of sram */
-#define OBIO_START U(0xFFF00000) /* start of local IO */
-#define OBIO_SIZE U(0x000EFFFF) /* size of obio space */
+#define BUGROM_START U(0xFF800000) /* start of BUG PROM */
+#define BUGROM_SIZE U(0x003FFFFF) /* size of BUG PROM */
+#define SRAM_START U(0xFFE00000) /* start of sram used by bug */
+#define SRAM_SIZE U(0x0001FFFF) /* size of sram */
+#define OBIO_START U(0xFFF00000) /* start of local IO */
+#define OBIO_SIZE U(0x000EFFFF) /* size of obio space */
#define INT_PRI_LEVEL U(0xFFF4203E) /* interrupt priority level */
#define INT_MASK_LEVEL U(0xFFF4203F) /* interrupt mask level */
#define LOCAL_IO_DEVS U(0xFFF00000) /* local IO devices */
-#define VMEA16 U(0xFFFF0000) /* VMEbus A16 */
-#define PCC2_ADDR U(0xFFF42000) /* PCCchip2 Regs */
-#define MEM_CTLR U(0xFFF43000) /* MEMC040 mem controller */
-#define SCC_ADDR U(0xFFF45000) /* Cirrus Chip */
-#define LANCE_ADDR U(0xFFF46000) /* 82596CA */
-#define SCSI_ADDR U(0xFFF47000) /* NCR 710 address */
-#define NCR710_SIZE U(0x00000040) /* NCR 710 size */
-#define MK48T08_ADDR U(0xFFFC0000) /* BBRAM, TOD */
+#define VMEA16 U(0xFFFF0000) /* VMEbus A16 */
+#define VMEA16_SIZE U(0x0000EFFF) /* VMEbus A16 size */
+#define VMEA32D16 U(0xFF000000) /* VMEbus A32/D16 */
+#define VMEA32D16_SIZE U(0x007FFFFF) /* VMEbus A32/D16 size */
-#define TOD_CAL_CTL U(0xFFFC1FF8) /* calendar control register */
-#define TOD_CAL_SEC U(0xFFFC1FF9) /* seconds */
-#define TOD_CAL_MIN U(0xFFFC1FFA) /* minutes */
-#define TOD_CAL_HOUR U(0xFFFC1FFB) /* hours */
-#define TOD_CAL_DOW U(0xFFFC1FFC) /* Day Of the Week */
-#define TOD_CAL_DAY U(0xFFFC1FFD) /* days */
-#define TOD_CAL_MON U(0xFFFC1FFE) /* months */
-#define TOD_CAL_YEAR U(0xFFFC1FFF) /* years */
+#define PCC2_ADDR U(0xFFF42000) /* PCCchip2 Regs */
+#define MEM_CTLR U(0xFFF43000) /* MEMC040 mem controller */
+#define SCC_ADDR U(0xFFF45000) /* Cirrus Chip */
+#define LANCE_ADDR U(0xFFF46000) /* 82596CA */
+#define SCSI_ADDR U(0xFFF47000) /* NCR 710 address */
+#define NCR710_SIZE U(0x00000040) /* NCR 710 size */
+#define MK48T08_ADDR U(0xFFFC0000) /* BBRAM, TOD */
-#define CMMU_I U(0xFFF77000) /* CMMU instruction */
-#define CMMU_D U(0xFFF7F000) /* CMMU data */
-#define CMMU_SIZE 0x1000
+#define TOD_CAL_CTL U(0xFFFC1FF8) /* calendar control register */
+#define TOD_CAL_SEC U(0xFFFC1FF9) /* seconds */
+#define TOD_CAL_MIN U(0xFFFC1FFA) /* minutes */
+#define TOD_CAL_HOUR U(0xFFFC1FFB) /* hours */
+#define TOD_CAL_DOW U(0xFFFC1FFC) /* Day Of the Week */
+#define TOD_CAL_DAY U(0xFFFC1FFD) /* days */
+#define TOD_CAL_MON U(0xFFFC1FFE) /* months */
+#define TOD_CAL_YEAR U(0xFFFC1FFF) /* years */
-#if 0
-/* interrupt vectors */
-
-#define PPBSY 0x50 /* printer port busy */
-#define PPPE 0x51 /* printer port PE */
-#define PPSEL 0x52 /* printer port select */
-#define PPFLT 0x53 /* printer port fault */
-#define PPACK 0x54 /* printer port ack */
-#define SCSIIRQ 0x55 /* SCSI IRQ */
-#define LANCERR 0x56 /* LANC ERR */
-#define LANCIRQ 0x57 /* LANC IRQ */
-#define TIMER2IRQ 0x58 /* Tick Timer 2 vec */
-#define TIMER1IRQ 0x59 /* Tick Timer 1 vec */
-#define GPIOIRQ 0x5A /* GPIO IRQ */
-#define SRXEXIRQ 0x5C /* Serial RX Exception IRQ */
-#define SRMIRQ 0x5D /* Serial Modem IRQ */
-#define STXIRQ 0x5E /* Serial TX IRQ */
-#define SRXIRQ 0x5F /* Serial RX IRQ */
-#endif /* 0 */
+#define CMMU_I U(0xFFF77000) /* CMMU instruction */
+#define CMMU_D U(0xFFF7F000) /* CMMU data */
+#define CMMU_SIZE 0x1000
#endif /* _MACHINE_BOARD_H */
diff --git a/sys/arch/mvme88k/include/exec.h b/sys/arch/mvme88k/include/exec.h
index e02b2e8166b..f599b77eb16 100644
--- a/sys/arch/mvme88k/include/exec.h
+++ b/sys/arch/mvme88k/include/exec.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: exec.h,v 1.6 1999/02/09 06:36:26 smurph Exp $ */
+/* $OpenBSD: exec.h,v 1.7 1999/05/29 04:41:45 smurph Exp $ */
#ifndef _MACHINE_EXEC_H_
#define _MACHINE_EXEC_H_
@@ -17,8 +17,14 @@ struct relocation_info_m88k {
};
#define relocation_info relocation_info_m88k
-#define _NLIST_DO_AOUT
+#define ELF_TARG_CLASS ELFCLASS32
+#define ELF_TARG_DATA ELFDATA2MSB
+#define ELF_TARG_MACH EM_88K
-#define _KERN_DO_AOUT
+#define _NLIST_DO_AOUT
+#define _NLIST_DO_ELF
+
+#define _KERN_DO_AOUT
+#define _KERN_DO_ELF
#endif _MACHINE_EXEC_H_
diff --git a/sys/arch/mvme88k/include/param.h b/sys/arch/mvme88k/include/param.h
index 34ecc00afe4..fced74b83d1 100644
--- a/sys/arch/mvme88k/include/param.h
+++ b/sys/arch/mvme88k/include/param.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: param.h,v 1.8 1999/02/09 06:36:27 smurph Exp $ */
+/* $OpenBSD: param.h,v 1.9 1999/05/29 04:41:45 smurph Exp $ */
/*
* Copyright (c) 1999 Steve Murphree, Jr.
* Copyright (c) 1988 University of Utah.
@@ -40,7 +40,7 @@
* from: Utah $Hdr: machparam.h 1.11 89/08/14$
*
* @(#)param.h 7.8 (Berkeley) 6/28/91
- * $Id: param.h,v 1.8 1999/02/09 06:36:27 smurph Exp $
+ * $Id: param.h,v 1.9 1999/05/29 04:41:45 smurph Exp $
*/
#ifndef _MACHINE_PARAM_H_
#define _MACHINE_PARAM_H_
@@ -96,7 +96,7 @@
#define SINCR 1 /* increment of stack/NBPG */
#define USPACE ctob(UPAGES)
-#define UPAGES 3 /* pages of u-area */
+#define UPAGES 4 /* pages of u-area */
#define UADDR 0xEEE00000 /* address of u */
#define UVPN (UADDR>>PGSHIFT)/* virtual page number of u */
#define KERNELSTACK (UADDR+UPAGES*NBPG) /* top of kernel stack */
diff --git a/sys/arch/mvme88k/include/pmap.h b/sys/arch/mvme88k/include/pmap.h
index 839727e5d8d..625b3efa533 100644
--- a/sys/arch/mvme88k/include/pmap.h
+++ b/sys/arch/mvme88k/include/pmap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.h,v 1.5 1999/02/09 06:36:27 smurph Exp $ */
+/* $OpenBSD: pmap.h,v 1.6 1999/05/29 04:41:45 smurph Exp $ */
/*
* Mach Operating System
* Copyright (c) 1991 Carnegie Mellon University
@@ -95,6 +95,12 @@ void pmap_activate(pmap_t my_pmap, pcb_t);
void pmap_deactivate(pmap_t pmap, pcb_t);
int pmap_check_transaction(pmap_t pmap, vm_offset_t va, vm_prot_t type);
+vm_offset_t pmap_map(
+ vm_offset_t virt,
+ vm_offset_t start,
+ vm_offset_t end,
+ vm_prot_t prot);
+
vm_offset_t pmap_map_batc(
vm_offset_t virt,
vm_offset_t start,
diff --git a/sys/arch/mvme88k/include/proc.h b/sys/arch/mvme88k/include/proc.h
index b283c4a72ff..31acf460704 100644
--- a/sys/arch/mvme88k/include/proc.h
+++ b/sys/arch/mvme88k/include/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.4 1999/02/09 06:36:27 smurph Exp $ */
+/* $OpenBSD: proc.h,v 1.5 1999/05/29 04:41:45 smurph Exp $ */
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@@ -43,7 +43,7 @@
* @(#)proc.h 8.1 (Berkeley) 6/11/93
*
* from: Header: proc.h,v 1.6 92/11/26 02:04:41 torek Exp (LBL)
- * $Id: proc.h,v 1.4 1999/02/09 06:36:27 smurph Exp $
+ * $Id: proc.h,v 1.5 1999/05/29 04:41:45 smurph Exp $
*/
#include <machine/pcb.h>
@@ -56,4 +56,6 @@ struct mdproc {
struct trapframe *md_tf; /* trap/syscall registers */
struct fpstate *md_fpstate; /* fpu state, if any; always resident */
int md_upte[UPAGES]; /* ptes for mapping u page */
+ int md_ss_addr; /* single step address for ptrace */
+ int md_ss_instr; /* single step instruction for ptrace */
};
diff --git a/sys/arch/mvme88k/include/prom.h b/sys/arch/mvme88k/include/prom.h
index 015c65a3c54..2f1650c85be 100644
--- a/sys/arch/mvme88k/include/prom.h
+++ b/sys/arch/mvme88k/include/prom.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: prom.h,v 1.3 1999/02/09 06:36:27 smurph Exp $ */
+/* $OpenBSD: prom.h,v 1.4 1999/05/29 04:41:45 smurph Exp $ */
/*
* Copyright (c) 1998 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -98,19 +98,21 @@ struct mvmeprom_brdid {
u_short devtype;
u_short devnum;
u_long bug;
-
- /*
- * XXX: I have seen no documentation for these!
- *
- * The following (appears to) exist only on the MVME162 and
- * upwards. We should figure out what the other fields are.
- */
- u_char xx1[16];
- u_char xx2[4];
- u_char longname[12];
- u_char xx3[16];
- u_char speed[4];
- u_char xx4[12];
+ u_char version[4];
+ u_char serial[12]; /* SBC serial number */
+ u_char id[16]; /* SBC id */
+ u_char pwa[16]; /* printed wiring assembly number */
+ u_char speed[4]; /* cpu speed */
+ u_char etheraddr[6]; /* mac address, all zero if no ether */
+ u_char fill[2];
+ u_char scsiid[2]; /* local SCSI id */
+ u_char sysid[8]; /* system id - nothing on mvme187 */
+ u_char brd1_pwb[8]; /* memory board 1 pwb */
+ u_char brd1_serial[8]; /* memory board 1 serial */
+ u_char brd2_pwb[8]; /* memory board 2 pwb */
+ u_char brd2_serial[8]; /* memory board 2 serial */
+ u_char reserved[153];
+ u_char cksum[1];
};
struct mvmeprom_time {
diff --git a/sys/arch/mvme88k/mvme88k/autoconf.c b/sys/arch/mvme88k/mvme88k/autoconf.c
index 3a04a63dcfa..df5a0ba3e52 100644
--- a/sys/arch/mvme88k/mvme88k/autoconf.c
+++ b/sys/arch/mvme88k/mvme88k/autoconf.c
@@ -29,7 +29,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: autoconf.c,v 1.4 1998/12/15 05:11:01 smurph Exp $
+ * $Id: autoconf.c,v 1.5 1999/05/29 04:41:45 smurph Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
@@ -74,7 +74,7 @@ void
configure()
{
bootdv = NULL; /* set by device drivers (if found) */
-/* rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16);*/
+ /*rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16);*/
if (config_rootfound("mainbus", "mainbus") == 0)
panic("no mainbus found");
@@ -124,8 +124,7 @@ swapconf()
{
register struct swdevt *swp;
register int nblks;
-
- for (swp = swdevt; swp->sw_dev != NODEV; swp++)
+ for (swp = swdevt; swp->sw_dev != NODEV; swp++){
if (bdevsw[major(swp->sw_dev)].d_psize) {
nblks =
(*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
@@ -133,6 +132,7 @@ swapconf()
(swp->sw_nblks == 0 || swp->sw_nblks > nblks))
swp->sw_nblks = nblks;
}
+ }
dumpconf();
}
diff --git a/sys/arch/mvme88k/mvme88k/conf.c b/sys/arch/mvme88k/mvme88k/conf.c
index 0fc1eb1fd62..f91962bbd7c 100644
--- a/sys/arch/mvme88k/mvme88k/conf.c
+++ b/sys/arch/mvme88k/mvme88k/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.10 1999/02/09 06:36:28 smurph Exp $ */
+/* $OpenBSD: conf.c,v 1.11 1999/05/29 04:41:46 smurph Exp $ */
/*-
* Copyright (c) 1991 The Regents of the University of California.
@@ -107,21 +107,19 @@ cdev_decl(ctty);
cdev_decl(mm);
cdev_decl(sw);
-#if 1 /*notyet*/
#include "sram.h"
cdev_decl(sram);
#include "nvram.h"
cdev_decl(nvram);
-#endif
-#if notyet
#include "vmel.h"
cdev_decl(vmel);
#include "vmes.h"
cdev_decl(vmes);
+#if notyet
#include "flash.h"
cdev_decl(flash);
#endif /* notyet */
@@ -146,6 +144,9 @@ cdev_decl(cl);
#include "bugtty.h"
cdev_decl(bugtty);
+#include "vx.h"
+cdev_decl(vx);
+
/* open, close, write, ioctl */
#define cdev_lp_init(c,n) { \
dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
@@ -192,6 +193,12 @@ cdev_decl(tun);
#define NLKM 0
#endif
+#ifdef IPFILTER
+#define NIPF 1
+#else
+#define NIPF 0
+#endif
+
cdev_decl(lkm);
struct cdevsw cdevsw[] =
@@ -203,18 +210,10 @@ struct cdevsw cdevsw[] =
cdev_tty_init(NPTY,pts), /* 4: pseudo-tty slave */
cdev_ptc_init(NPTY,ptc), /* 5: pseudo-tty master */
cdev_log_init(1,log), /* 6: /dev/klog */
-#if 1
cdev_mdev_init(NSRAM,sram), /* 7: /dev/sramX */
-#else
- cdev_notdef(), /* 7: */
-#endif /* notyet */
cdev_disk_init(NSD,sd), /* 8: SCSI disk */
cdev_disk_init(NCD,cd), /* 9: SCSI CD-ROM */
-#if 1
cdev_mdev_init(NNVRAM,nvram), /* 10: /dev/nvramX */
-#else
- cdev_notdef(), /* 10: */
-#endif /* notyet */
#if notyet
cdev_mdev_init(NFLASH,flash), /* 11: /dev/flashX */
@@ -225,7 +224,7 @@ struct cdevsw cdevsw[] =
#endif /* notyet */
cdev_tty_init(NCL,cl), /* 13: CL-CD1400 serial (tty0[0-3]) */
cdev_tty_init(NBUGTTY,bugtty), /* 14: BUGtty (ttyB) */
- cdev_notdef(), /* 15 */
+ cdev_tty_init(NVX,vx), /* 15: MVME332XT serial/lpt ttyv[0-7][a-i] */
cdev_notdef(), /* 16 */
cdev_notdef(), /* 17: concatenated disk */
cdev_disk_init(NRD,rd), /* 18: ramdisk disk */
@@ -245,25 +244,20 @@ struct cdevsw cdevsw[] =
#if notyet
cdev_lp_init(NLP,lp), /* 28: lp */
cdev_lp_init(NLPTWO,lptwo), /* 29: lptwo */
-#else
+#else
cdev_notdef(), /* 28: lp */
cdev_notdef(), /* 29: lptwo */
#endif /* notyet */
cdev_notdef(), /* 30 */
-#if notyet
cdev_mdev_init(NVMEL,vmel), /* 31: /dev/vmelX */
cdev_mdev_init(NVMES,vmes), /* 32: /dev/vmesX */
-#else /* notyet */
- cdev_notdef(), /* 31: /dev/vmelX */
- cdev_notdef(), /* 32: /dev/vmesX */
-#endif /* notyet */
cdev_lkm_dummy(), /* 33 */
cdev_lkm_dummy(), /* 34 */
cdev_lkm_dummy(), /* 35 */
cdev_lkm_dummy(), /* 36 */
cdev_lkm_dummy(), /* 37 */
cdev_lkm_dummy(), /* 38 */
- cdev_notdef(), /* 39 */
+ cdev_gen_ipf(NIPF,ipl), /* 39: IP filter */
cdev_notdef(), /* 40 */
cdev_notdef(), /* 41 */
cdev_notdef(), /* 42 */
diff --git a/sys/arch/mvme88k/mvme88k/eh.S b/sys/arch/mvme88k/mvme88k/eh.S
index 00da4a56d3d..3ba6fc8046e 100644
--- a/sys/arch/mvme88k/mvme88k/eh.S
+++ b/sys/arch/mvme88k/mvme88k/eh.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: eh.S,v 1.6 1999/02/09 06:36:28 smurph Exp $ */
+/* $OpenBSD: eh.S,v 1.7 1999/05/29 04:41:46 smurph Exp $ */
/*
* Mach Operating System
* Copyright (c) 1993-1991 Carnegie Mellon University
@@ -239,6 +239,8 @@
#define FLAG_FROM_KERNEL 8 /* this should be in asm.h */
+#define INTSTACK 0 /* To make interupts use their own stack */
+
text
align 8
@@ -1664,7 +1666,7 @@ LABEL(setup_phase_one)
* If it's not the interrupt exception, enable interrupts and
* take care of any data access exceptions......
*
-#if notyet
+#if INTSTACK
* If interrupt exception, switch to interrupt stack if not
* already there. Else, switch to kernel stack.
#endif
@@ -1673,7 +1675,7 @@ LABEL(setup_phase_one)
ld r2, r31, REG_OFF(EF_EPSR)
bb1 PSR_SUPERVISOR_MODE_BIT, r2, 1f /* If in kernel mode */
-#if notyet
+#if INTSTACK
ld r3, r31, REG_OFF(EF_VECTOR)
cmp r3, r3, 1 /* is interrupt ? */
bb0 eq, r3, 2f
@@ -1687,13 +1689,13 @@ LABEL(setup_phase_one)
addu r31, r31, USIZE /* point at proper end */
br 3f
1:
-#if notyet
+#if INTSTACK
ld r3, r31, REG_OFF(EF_VECTOR)
cmp r3, r3, 1 /* is interrupt ? */
bb0 eq, r3, 3f /* no, we will stay on kern stack */
or.u r31, r0, hi16(_intstack_end) /* swith to int stack */
or r31, r31, lo16(_intstack_end)
-#endif /* notyet */
+#endif /* INTSTACK */
/* This label is here for debugging */
exception_handler_has_ksp: global exception_handler_has_ksp
3: /*
diff --git a/sys/arch/mvme88k/mvme88k/locore.S b/sys/arch/mvme88k/mvme88k/locore.S
index e5e00519946..498331426a1 100644
--- a/sys/arch/mvme88k/mvme88k/locore.S
+++ b/sys/arch/mvme88k/mvme88k/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.7 1999/02/09 06:36:28 smurph Exp $ */
+/* $OpenBSD: locore.S,v 1.8 1999/05/29 04:41:46 smurph Exp $ */
/*
* Copyright (c) 1998 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -213,8 +213,11 @@ LABEL(_start_text) /* This is the *real* start upon poweron or reset */
set r11, r11, 1<PSR_SHADOW_FREEZE_BIT>
set r11, r11, 1<PSR_FPU_DISABLE_BIT>
#endif
+#define PSR_MXM_DISABLE_BIT 2
+
set r11, r0, 1<PSR_SUPERVISOR_MODE_BIT>
set r11, r11, 1<PSR_INTERRUPT_DISABLE_BIT>
+ set r11, r11, 1<PSR_MXM_DISABLE_BIT> /* a cheat! for now... */
stcr r11, PSR
FLUSH_PIPELINE
@@ -313,7 +316,7 @@ _msgsw:
global _intstack
global _intstack_end
_intstack:
- space (4 * NBPG) /* 16K */
+ space (4 * NBPG) /* 16K, just to be safe*/
_intstack_end:
/*
diff --git a/sys/arch/mvme88k/mvme88k/machdep.c b/sys/arch/mvme88k/mvme88k/machdep.c
index a5ced81862b..71c87315fcb 100644
--- a/sys/arch/mvme88k/mvme88k/machdep.c
+++ b/sys/arch/mvme88k/mvme88k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.14 1999/05/24 23:09:05 jason Exp $ */
+/* $OpenBSD: machdep.c,v 1.15 1999/05/29 04:41:46 smurph Exp $ */
/*
* Copyright (c) 1998 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -128,6 +128,9 @@ volatile u_char *pcc2intr_ipl;
volatile vm_offset_t bugromva;
volatile vm_offset_t sramva;
volatile vm_offset_t obiova;
+volatile vm_offset_t extiova;
+volatile vm_offset_t vmea16va;
+volatile vm_offset_t vmea32d16va;
int physmem; /* available physical memory, in pages */
@@ -143,7 +146,7 @@ int BugWorks = 0;
*/
int safepri = 0;
-#if 0 /*XXX_FUTURE*/
+#if 1 /*XXX_FUTURE*/
/*
* iomap stuff is for managing chunks of virtual address space that
* can be allocated to IO devices.
@@ -197,7 +200,7 @@ char *esym;
int boothowto; /* read in kern/bootstrap */
int cputyp;
-int cpuspeed = 33; /* 25 MHZ XXX should be read from NVRAM */
+int cpuspeed = 25; /* 25 MHZ XXX should be read from NVRAM */
#ifndef roundup
#define roundup(value, stride) (((unsigned)(value) + (stride) - 1) & ~((stride)-1))
@@ -220,8 +223,9 @@ int no_symbols = 1;
struct proc *lastproc;
pcb_t curpcb;
-
extern struct user *proc0paddr;
+extern void *etherbuf;
+extern int etherlen;
/* XXX this is to fake out the console routines, while booting. */
#include "bugtty.h"
@@ -348,11 +352,11 @@ identifycpu()
{
cpuspeed = getcpuspeed();
sprintf(cpu_model, "Motorola MVME%x %dMhz", cputyp, cpuspeed);
- printf("\nModel: %s\n", cpu_model);
+ printf("\nModel: %s\n", cpu_model);
}
/* The following two functions assume UPAGES == 3 */
-#if UPAGES != 3
+#if UPAGES != 4
#error "UPAGES changed?"
#endif
@@ -377,12 +381,12 @@ void
load_u_area(struct proc *p)
{
pte_template_t *t;
-
+
int i;
for (i=0; i<UPAGES; i++) {
t = kvtopte(UADDR + (i * NBPG));
t->bits = p->p_md.md_upte[i];
-}
+ }
for (i=0; i<UPAGES; i++) {
cmmu_flush_tlb(1, UADDR + (i * NBPG), NBPG);
}
@@ -477,7 +481,23 @@ cpu_startup()
printf("obiova %x: OBIO not free\n", obiova);
panic("bad OBIO");
}
+
+#if 0
+ /*
+ * Grab the EXTIO space that we hardwired in pmap_bootstrap
+ */
+
+ extiova = IOMAP_MAP_START;
+
+ vm_map_find(kernel_map, vm_object_allocate(IOMAP_SIZE), 0,
+ (vm_offset_t *)&extiova, IOMAP_SIZE, TRUE);
+ if (extiova != IOMAP_MAP_START) {
+ printf("extiova %x: EXTIO not free\n", extiova);
+ panic("bad EXTIO");
+ }
+#endif
+
/*
* Now allocate buffers proper. They are different than the above
* in that they usually occupy more virtual memory than physical.
@@ -535,7 +555,7 @@ cpu_startup()
panic("cpu_startup: unable to create phys_map");
}
-#if 0 /*XXX_FUTURE*/
+#if 1 /*XXX_FUTURE*/
iomap_map = vm_map_create(kernel_pmap, IOMAP_MAP_START,
IOMAP_MAP_START + IOMAP_SIZE, TRUE);
if (iomap_map == NULL) {
@@ -666,7 +686,7 @@ allocsys(v)
valloc(swbuf, struct buf, nswbuf);
valloc(buf, struct buf, nbuf);
-#if 0 /*XXX_FUTURE*/
+#if 1 /*XXX_FUTURE*/
/*
* Arbitrarily limit the number of devices mapping
* the IO space at a given time to NIOPMAP (= 32, default).
@@ -1760,11 +1780,13 @@ db_splx(int s)
}
#endif /* DDB */
+
/*
* Called from locore.S during boot,
* this is the first C code that's run.
*/
+
void
m187_bootstrap(void)
{
@@ -1787,21 +1809,6 @@ m187_bootstrap(void)
vm_set_page_size();
-#if 0
- esym = kflags.esym;
- boothowto = kflags.bflags;
- bootdev = kflags.bdev;
-#endif /* 0 */
-
-#if 0
- end_loaded = kflags.end_load;
- if (esym != NULL) {
- end = (char *)((int)(kflags.symtab));
- } else {
- first_addr = (vm_offset_t)&end;
- }
-#endif
-
first_addr = m88k_round_page(first_addr);
if (!no_symbols) boothowto |= RB_KDB;
diff --git a/sys/arch/mvme88k/mvme88k/pmap.c b/sys/arch/mvme88k/mvme88k/pmap.c
index bac606c48a9..768392fdea9 100644
--- a/sys/arch/mvme88k/mvme88k/pmap.c
+++ b/sys/arch/mvme88k/mvme88k/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.6 1999/02/09 06:36:30 smurph Exp $ */
+/* $OpenBSD: pmap.c,v 1.7 1999/05/29 04:41:46 smurph Exp $ */
/*
* Copyright (c) 1996 Nivas Madhur
* All rights reserved.
@@ -257,7 +257,7 @@ static pv_entry_t pv_head_table; /* array of entries, one per page */
#define UNLOCK_PVH(index)
#define ETHERPAGES 16
-void *etherbuf;
+void *etherbuf=NULL;
int etherlen;
/*
@@ -1125,119 +1125,132 @@ pmap_bootstrap(vm_offset_t load_start, /* IN */
* the translation tree. I don't think we need to map it CACHE_INH
* here...
*/
- if (kmapva != vaddr) {
+ if (kmapva != vaddr) {
#ifdef DEBUG
- if ((pmap_con_dbg & (CD_BOOT | CD_FULL)) == (CD_BOOT | CD_FULL)) {
- printf("(pmap_bootstrap) correcting vaddr\n");
- }
+ if ((pmap_con_dbg & (CD_BOOT | CD_FULL)) == (CD_BOOT | CD_FULL)) {
+ printf("(pmap_bootstrap) correcting vaddr\n");
+ }
#endif
- while (vaddr < (*virt_start - kernel_pmap_size))
- vaddr = M88K_ROUND_PAGE(vaddr + 1);
- }
+ while (vaddr < (*virt_start - kernel_pmap_size))
+ vaddr = M88K_ROUND_PAGE(vaddr + 1);
+ }
- vaddr = PMAPER(
- vaddr,
- (vm_offset_t)kmap,
- *phys_start,
- (VM_PROT_WRITE|VM_PROT_READ)|(CACHE_GLOBAL << 16));
+ vaddr = PMAPER(vaddr,(vm_offset_t)kmap,*phys_start,
+ (VM_PROT_WRITE|VM_PROT_READ)|(CACHE_GLOBAL << 16));
+
+ if (vaddr != *virt_start) {
+ #ifdef DEBUG
+ if ((pmap_con_dbg & (CD_BOOT | CD_FULL)) == (CD_BOOT | CD_FULL)) {
+ printf("1:vaddr %x *virt_start %x *phys_start %x\n", vaddr,
+ *virt_start, *phys_start);
+ }
+ #endif
+ *virt_start = vaddr;
+ *phys_start = round_page(*phys_start);
+ }
- etherlen = ETHERPAGES * NBPG;
/*
- * Get ethernet buffer - need etherlen bytes physically contiguous.
+ * Get ethernet buffer - need etherlen bytes physically contiguous.
* 1 to 1 mapped as well???. There is actually a bug in the macros
* used by the 1x7 ethernet driver. Remove this when that is fixed.
* XXX -nivas
*/
-
- if (vaddr != *virt_start) {
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_BOOT | CD_FULL)) == (CD_BOOT | CD_FULL)) {
- printf("1:vaddr %x *virt_start %x *phys_start %x\n", vaddr,
- *virt_start, *phys_start);
- }
-#endif
- *virt_start = vaddr;
- *phys_start = round_page(*phys_start);
- }
-
+ etherlen = (ETHERPAGES * NBPG);
*phys_start = vaddr;
-
+
etherbuf = (void *)vaddr;
-
- vaddr = PMAPER(
- vaddr,
- *phys_start,
- *phys_start + etherlen,
- (VM_PROT_WRITE|VM_PROT_READ)|(CACHE_INH << 16));
-
+
+ vaddr = PMAPER(vaddr,*phys_start,*phys_start + etherlen,
+ (VM_PROT_WRITE|VM_PROT_READ)|(CACHE_INH << 16));
*virt_start += etherlen;
- *phys_start += etherlen;
-
+ *phys_start += etherlen;
+
if (vaddr != *virt_start) {
#ifdef DEBUG
- if ((pmap_con_dbg & (CD_BOOT | CD_FULL)) == (CD_BOOT | CD_FULL)) {
- printf("2:vaddr %x *virt_start %x *phys_start %x\n", vaddr,
- *virt_start, *phys_start);
- }
+ if ((pmap_con_dbg & (CD_BOOT | CD_FULL)) == (CD_BOOT | CD_FULL)) {
+ printf("2:vaddr %x *virt_start %x *phys_start %x\n", vaddr,
+ *virt_start, *phys_start);
+ }
#endif
- *virt_start = vaddr;
- *phys_start = round_page(*phys_start);
+ *virt_start = vaddr;
+ *phys_start = round_page(*phys_start);
}
- *virt_start = round_page(*virt_start);
- *virt_end = VM_MAX_KERNEL_ADDRESS;
- /*
- * Map a few more pages for phys routines and debugger.
- */
+ *virt_start = round_page(*virt_start);
+ *virt_end = VM_MAX_KERNEL_ADDRESS;
- phys_map_vaddr1 = round_page(*virt_start);
- phys_map_vaddr2 = phys_map_vaddr1 + PAGE_SIZE;
+ /*
+ * Map a few more pages for phys routines and debugger.
+ */
- /*
- * To make 1:1 mapping of virt:phys, throw away a few phys pages.
- * XXX what is this? nivas
- */
+ phys_map_vaddr1 = round_page(*virt_start);
+ phys_map_vaddr2 = phys_map_vaddr1 + PAGE_SIZE;
+ /*
+ * To make 1:1 mapping of virt:phys, throw away a few phys pages.
+ * XXX what is this? nivas
+ */
- *phys_start += 2 * PAGE_SIZE;
- *virt_start += 2 * PAGE_SIZE;
-
- /*
- * Map all IO space 1-to-1. Ideally, I would like to not do this
- * but have va for the given IO address dynamically allocated. But
- * on the 88200, 2 of the BATCs are hardwired to do map the IO space
- * 1-to-1; I decided to map the rest of the IO space 1-to-1.
- * And bug ROM & the SRAM need to be mapped 1-to-1 if we ever want to
- * execute bug system calls after the MMU has been turned on.
- * OBIO should be mapped cache inhibited.
- */
+ *phys_start += 2 * PAGE_SIZE;
+ *virt_start += 2 * PAGE_SIZE;
+
+ /*
+ * Map all IO space 1-to-1. Ideally, I would like to not do this
+ * but have va for the given IO address dynamically allocated. But
+ * on the 88200, 2 of the BATCs are hardwired to do map the IO space
+ * 1-to-1; I decided to map the rest of the IO space 1-to-1.
+ * And bug ROM & the SRAM need to be mapped 1-to-1 if we ever want to
+ * execute bug system calls after the MMU has been turned on.
+ * OBIO should be mapped cache inhibited.
+ */
- PMAPER(
+ PMAPER(
BUGROM_START,
BUGROM_START,
BUGROM_START + BUGROM_SIZE,
VM_PROT_WRITE|VM_PROT_READ|(CACHE_INH << 16));
- PMAPER(
+ PMAPER(
SRAM_START,
SRAM_START,
SRAM_START + SRAM_SIZE,
VM_PROT_WRITE|VM_PROT_READ|(CACHE_GLOBAL << 16));
- PMAPER(
+ PMAPER(
OBIO_START,
OBIO_START,
OBIO_START + OBIO_SIZE,
VM_PROT_WRITE|VM_PROT_READ|(CACHE_INH << 16));
+#if 0
+ PMAPER(
+ VMEA16,
+ VMEA16,
+ VMEA16 + VMEA16_SIZE,
+ VM_PROT_WRITE|VM_PROT_READ|(CACHE_INH << 16));
+
+ PMAPER(
+ VMEA32D16,
+ VMEA32D16,
+ VMEA32D16 + VMEA32D16_SIZE,
+ VM_PROT_WRITE|VM_PROT_READ|(CACHE_INH << 16));
+
+ PMAPER(
+ IOMAP_MAP_START,
+ IOMAP_MAP_START,
+ IOMAP_MAP_START + IOMAP_SIZE,
+ VM_PROT_WRITE|VM_PROT_READ|(CACHE_INH << 16));
+#endif /* 0 */
+
/*
* Allocate all the submaps we need. Note that SYSMAP just allocates
* kernel virtual address with no physical backing memory. The idea
* is physical memory will be mapped at this va before using that va.
* This means that if different physcal pages are going to be mapped
- * at different times, we better do a tlb flush before using it - * else we will be referencing the wrong page.
+ * at different times, we better do a tlb flush before using it -
+ * else we will be referencing the wrong page.
*/
#define SYSMAP(c, p, v, n) \
diff --git a/sys/arch/mvme88k/mvme88k/process_machdep.c b/sys/arch/mvme88k/mvme88k/process_machdep.c
index d58e2725390..f8e66540bf8 100644
--- a/sys/arch/mvme88k/mvme88k/process_machdep.c
+++ b/sys/arch/mvme88k/mvme88k/process_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: process_machdep.c,v 1.5 1999/02/09 06:36:30 smurph Exp $ */
+/* $OpenBSD: process_machdep.c,v 1.6 1999/05/29 04:41:47 smurph Exp $ */
/*
* Copyright (c) 1993 The Regents of the University of California.
@@ -74,16 +74,14 @@
#include <machine/frame.h>
#endif
#include <sys/ptrace.h>
+/* NOTE: struct reg == struct trapframe */
int
process_read_regs(p, regs)
struct proc *p;
struct reg *regs;
{
-#if 0
- /* NOTE: struct reg == struct trapframe */
bcopy(p->p_md.md_tf, (caddr_t)regs, sizeof(struct reg));
-#endif
return (0);
}
@@ -92,11 +90,7 @@ process_write_regs(p, regs)
struct proc *p;
struct reg *regs;
{
-#if 0
- int psr = p->p_md.md_tf->tf_epsr & ~PSR_ICC;
bcopy((caddr_t)regs, p->p_md.md_tf, sizeof(struct reg));
- p->p_md.md_tf->tf_epsr = psr | (regs->r_epsr & PSR_ICC);
-#endif
return (0);
}
@@ -104,10 +98,8 @@ int
process_sstep(p, sstep)
struct proc *p;
{
-#if 0
if (sstep)
- return EINVAL;
-#endif
+ cpu_singlestep(p);
return (0);
}
@@ -116,10 +108,8 @@ process_set_pc(p, addr)
struct proc *p;
caddr_t addr;
{
-#if 0
- p->p_md.md_tf->tf_pc = (u_int)addr;
- p->p_md.md_tf->tf_npc = (u_int)addr + 4;
-#endif
+ p->p_md.md_tf->sxip = (u_int)addr;
+ p->p_md.md_tf->snip = (u_int)addr + 4;
return (0);
}
diff --git a/sys/arch/mvme88k/mvme88k/trap.c b/sys/arch/mvme88k/mvme88k/trap.c
index 53eab7da4b8..57b276fd5dc 100644
--- a/sys/arch/mvme88k/mvme88k/trap.c
+++ b/sys/arch/mvme88k/mvme88k/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.6 1999/02/09 06:36:30 smurph Exp $ */
+/* $OpenBSD: trap.c,v 1.7 1999/05/29 04:41:47 smurph Exp $ */
/*
* Copyright (c) 1998 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -57,12 +57,17 @@
#include <machine/m88100.h> /* DMT_VALID, etc. */
#include <machine/trap.h>
#include <machine/psl.h> /* FIP_E, etc. */
+#include <machine/pcb.h> /* FIP_E, etc. */
#include <sys/systm.h>
#if (DDB)
#include <machine/db_machdep.h>
+#else
+#define PC_REGS(regs) ((regs->sxip & 2) ? regs->sxip & ~3 : \
+ (regs->snip & 2 ? regs->snip & ~3 : regs->sfip & ~3))
#endif /* DDB */
+#define BREAKPOINT (0xF000D1F8U) /* Single Step Breakpoint */
#define TRAPTRACE
#if defined(TRAPTRACE)
@@ -191,6 +196,7 @@ trap(unsigned type, struct m88100_saved_state *frame)
union sigval sv;
int result;
int sig = 0;
+ unsigned pc = PC_REGS(frame); /* get program counter (sxip) */
extern vm_map_t kernel_map;
extern int fubail(), subail();
@@ -392,11 +398,12 @@ trap(unsigned type, struct m88100_saved_state *frame)
case T_DATAFLT+T_USER:
user_fault:
- if (type == T_INSTFLT+T_USER)
+ if (type == T_INSTFLT+T_USER){
fault_addr = frame->sxip & XIP_ADDR;
- else
+ }else{
fault_addr = frame->dma0;
-
+ }
+
if (frame->dmt0 & (DMT_WRITE|DMT_LOCKBAR)) {
ftype = VM_PROT_READ|VM_PROT_WRITE;
fault_code = VM_PROT_WRITE;
@@ -502,9 +509,61 @@ trap(unsigned type, struct m88100_saved_state *frame)
* is executed. When this breakpoint is hit, we get the
* T_STEPBPT trap.
*/
+#if 0
+ frame->sfip = frame->snip; /* set up next FIP */
+ frame->snip = frame->sxip; /* set up next NIP */
+ break;
+#endif
+ {
+ register unsigned va;
+ unsigned instr;
+ struct uio uio;
+ struct iovec iov;
+
+ /* compute address of break instruction */
+ va = pc;
+
+ /* read break instruction */
+ instr = fuiword((caddr_t)pc);
+#if 1
+ printf("trap: %s (%d) breakpoint %x at %x: (adr %x ins %x)\n",
+ p->p_comm, p->p_pid, instr, pc,
+ p->p_md.md_ss_addr, p->p_md.md_ss_instr); /* XXX */
+#endif
+ /* check and see if we got here by accident */
+/*
+ if (p->p_md.md_ss_addr != pc || instr != BREAKPOINT) {
+ sig = SIGTRAP;
+ fault_type = TRAP_TRACE;
+ break;
+ }
+*/
+ /* restore original instruction and clear BP */
+ /*sig = suiword((caddr_t)pc, p->p_md.md_ss_instr);*/
+ instr = p->p_md.md_ss_instr;
+ if (instr == 0){
+ printf("Warning: can't restore instruction at %x: %x\n",
+ p->p_md.md_ss_addr, p->p_md.md_ss_instr);
+ } else {
+ iov.iov_base = (caddr_t)&instr;
+ iov.iov_len = sizeof(int);
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = (off_t)pc;
+ uio.uio_resid = sizeof(int);
+ uio.uio_segflg = UIO_SYSSPACE;
+ uio.uio_rw = UIO_WRITE;
+ uio.uio_procp = curproc;
+ }
+
frame->sfip = frame->snip; /* set up next FIP */
frame->snip = frame->sxip; /* set up next NIP */
+ frame->snip |= 2; /* set valid bit */
+ p->p_md.md_ss_addr = 0;
+ sig = SIGTRAP;
+ fault_type = TRAP_BRKPT;
break;
+ }
case T_USERBPT+T_USER:
/*
@@ -786,3 +845,206 @@ init_sir()
sir_routines[1] = softclock;
next_sir = 2;
}
+
+
+/************************************\
+* User Single Step Debugging Support *
+\************************************/
+
+/*
+ * Read bytes from address space for debugger.
+ */
+void
+ss_read_bytes(addr, size, data)
+ unsigned addr;
+ register int size;
+ register char *data;
+{
+ register char *src;
+
+ src = (char *)addr;
+
+ while(--size >= 0) {
+ *data++ = *src++;
+ }
+}
+
+unsigned
+ss_get_value(unsigned addr, int size, int is_signed)
+{
+ char data[sizeof(unsigned)];
+ unsigned value, extend;
+ int i;
+
+ ss_read_bytes(addr, size, data);
+
+ value = 0;
+ extend = (~(db_expr_t)0) << (size * 8 - 1);
+ for (i = 0; i < size; i++)
+ value = (value << 8) + (data[i] & 0xFF);
+
+ if (size < sizeof(unsigned) && is_signed && (value & extend))
+ value |= extend;
+ return (value);
+}
+
+
+/*
+ * ss_branch_taken(instruction, program counter, func, func_data)
+ *
+ * instruction will be a control flow instruction location at address pc.
+ * Branch taken is supposed to return the address to which the instruction
+ * would jump if the branch is taken. Func can be used to get the current
+ * register values when invoked with a register number and func_data as
+ * arguments.
+ *
+ * If the instruction is not a control flow instruction, panic.
+ */
+unsigned
+ss_branch_taken(
+ unsigned inst,
+ unsigned pc,
+ unsigned (*func)(unsigned int, struct trapframe *),
+ struct trapframe *func_data) /* 'opaque' */
+{
+
+ /* check if br/bsr */
+ if ((inst & 0xf0000000U) == 0xc0000000U)
+ {
+ /* signed 26 bit pc relative displacement, shift left two bits */
+ inst = (inst & 0x03ffffffU)<<2;
+ /* check if sign extension is needed */
+ if (inst & 0x08000000U)
+ inst |= 0xf0000000U;
+ return pc + inst;
+ }
+
+ /* check if bb0/bb1/bcnd case */
+ switch ((inst & 0xf8000000U))
+ {
+ case 0xd0000000U: /* bb0 */
+ case 0xd8000000U: /* bb1 */
+ case 0xe8000000U: /* bcnd */
+ /* signed 16 bit pc relative displacement, shift left two bits */
+ inst = (inst & 0x0000ffffU)<<2;
+ /* check if sign extension is needed */
+ if (inst & 0x00020000U)
+ inst |= 0xfffc0000U;
+ return pc + inst;
+ }
+
+ /* check jmp/jsr case */
+ /* check bits 5-31, skipping 10 & 11 */
+ if ((inst & 0xfffff3e0U) == 0xf400c000U)
+ return (*func)(inst & 0x1f, func_data); /* the register value */
+
+ return 0; /* keeps compiler happy */
+}
+
+/*
+ * ss_getreg_val - handed a register number and an exception frame.
+ * Returns the value of the register in the specified
+ * frame. Only makes sense for general registers.
+ */
+unsigned
+ss_getreg_val(unsigned regno, struct trapframe *tf)
+{
+ if (regno == 0)
+ return 0;
+ else if (regno < 31)
+ return tf->r[regno];
+ else {
+ panic("bad register number to ss_getreg_val.");
+ return 0;/*to make compiler happy */
+ }
+}
+
+unsigned
+ss_get_next_addr(struct trapframe *regs)
+{
+ unsigned inst;
+ unsigned pc = PC_REGS(regs);
+ unsigned addr = 0;
+
+ inst = ss_get_value(pc, sizeof(int), FALSE);
+ addr = ss_branch_taken(inst, pc, ss_getreg_val, regs);
+ if (addr) return(addr);
+ return(pc + 4);
+}
+
+int
+cpu_singlestep(p)
+ register struct proc *p;
+{
+ register unsigned va;
+ struct trapframe *sstf = p->p_md.md_tf;
+ int i;
+
+ int bpinstr = BREAKPOINT;
+ int curinstr;
+ struct uio uio;
+ struct iovec iov;
+
+ /*
+ * Fetch what's at the current location.
+ */
+ iov.iov_base = (caddr_t)&curinstr;
+ iov.iov_len = sizeof(int);
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = (off_t)sstf->sxip;
+ uio.uio_resid = sizeof(int);
+ uio.uio_segflg = UIO_SYSSPACE;
+ uio.uio_rw = UIO_READ;
+ uio.uio_procp = curproc;
+ procfs_domem(curproc, p, NULL, &uio);
+
+ /* compute next address after current location */
+ if(curinstr != 0) {
+ va = ss_get_next_addr(sstf);
+ printf("SS %s (%d): next breakpoint set at %x\n",
+ p->p_comm, p->p_pid, va);
+ }
+ else {
+ va = PC_REGS(sstf) + 4;
+ }
+ if (p->p_md.md_ss_addr) {
+ printf("SS %s (%d): breakpoint already set at %x (va %x)\n",
+ p->p_comm, p->p_pid, p->p_md.md_ss_addr, va); /* XXX */
+ return (EFAULT);
+ }
+
+ p->p_md.md_ss_addr = va;
+
+ /*
+ * Fetch what's at the current location.
+ */
+ iov.iov_base = (caddr_t)&p->p_md.md_ss_instr;
+ iov.iov_len = sizeof(int);
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = (off_t)va;
+ uio.uio_resid = sizeof(int);
+ uio.uio_segflg = UIO_SYSSPACE;
+ uio.uio_rw = UIO_READ;
+ uio.uio_procp = curproc;
+ procfs_domem(curproc, p, NULL, &uio);
+
+ /*
+ * Store breakpoint instruction at the "next" location now.
+ */
+ iov.iov_base = (caddr_t)&bpinstr;
+ iov.iov_len = sizeof(int);
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = (off_t)va;
+ uio.uio_resid = sizeof(int);
+ uio.uio_segflg = UIO_SYSSPACE;
+ uio.uio_rw = UIO_WRITE;
+ uio.uio_procp = curproc;
+ i = procfs_domem(curproc, p, NULL, &uio);
+
+ if (i < 0) return (EFAULT);
+ return (0);
+}
+
diff --git a/sys/arch/mvme88k/mvme88k/vm_machdep.c b/sys/arch/mvme88k/mvme88k/vm_machdep.c
index 0c482250d07..d9f5f05d898 100644
--- a/sys/arch/mvme88k/mvme88k/vm_machdep.c
+++ b/sys/arch/mvme88k/mvme88k/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.7 1999/02/09 06:36:30 smurph Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.8 1999/05/29 04:41:47 smurph Exp $ */
/*
* Copyright (c) 1998 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -42,7 +42,7 @@
* from: Utah $Hdr: vm_machdep.c 1.21 91/04/06$
* from: @(#)vm_machdep.c 7.10 (Berkeley) 5/7/91
* vm_machdep.c,v 1.3 1993/07/07 07:09:32 cgd Exp
- * $Id: vm_machdep.c,v 1.7 1999/02/09 06:36:30 smurph Exp $
+ * $Id: vm_machdep.c,v 1.8 1999/05/29 04:41:47 smurph Exp $
*/
#include <sys/param.h>
@@ -61,10 +61,8 @@
#include <machine/cpu.h>
#include <machine/pte.h>
-#ifdef XXX_FUTURE
extern struct map *iomap;
-#endif
-extern struct map extiomap;
+extern vm_map_t iomap_map;
/*
* Finish a fork operation, with process p2 nearly set up.
@@ -304,35 +302,48 @@ iomap_mapin(vm_offset_t pa, vm_size_t len, boolean_t canwait)
if (len == 0)
return NULL;
- off = (u_long)pa & PGOFSET;
+ ppa = pa;
+ off = (u_long)ppa & PGOFSET;
len = round_page(off + len);
s = splimp();
for (;;) {
- iova = rmalloc(&extiomap, len);
+ iova = rmalloc(iomap, len);
if (iova != 0)
break;
if (canwait) {
- (void)tsleep(&extiomap, PRIBIO+1, "iomapin", 0);
+ (void)tsleep(iomap, PRIBIO+1, "iomapin", 0);
continue;
}
splx(s);
return NULL;
}
splx(s);
+
+ cmmu_flush_tlb(1, iova, len);
- tva = iova;
- pa = trunc_page(pa);
+ ppa = trunc_page(ppa);
- while (len) {
- pmap_enter(kernel_pmap, tva, pa,
- VM_PROT_READ|VM_PROT_WRITE, 1);
+#ifndef NEW_MAPPING
+ tva = iova;
+#else
+ tva = ppa;
+#endif
+
+ while (len>0) {
+ pmap_enter(vm_map_pmap(iomap_map), tva, ppa,
+ VM_PROT_WRITE|VM_PROT_READ|(CACHE_INH << 16), 1);
len -= PAGE_SIZE;
tva += PAGE_SIZE;
ppa += PAGE_SIZE;
}
+#ifndef NEW_MAPPING
return (iova + off);
+#else
+ return (pa + off);
+#endif
+
}
/*
@@ -348,11 +359,11 @@ iomap_mapout(vm_offset_t kva, vm_size_t len)
kva = trunc_page(kva);
len = round_page(off + len);
- pmap_remove(kernel_pmap, kva, kva + len);
+ pmap_remove(vm_map_pmap(iomap_map), kva, kva + len);
s = splimp();
- rmfree(&extiomap, len, kva);
- wakeup(&extiomap);
+ rmfree(iomap, len, kva);
+ wakeup(iomap);
splx(s);
return 1;
}
@@ -420,10 +431,18 @@ int
badvaddr(vm_offset_t va, int size)
{
register int x;
-
- if (badaddr(va, size)) {
- return -1;
+ int i;
+ int ret = 0;
+
+ for (i=0; i<5; i++){
+ ret = badaddr(va, size);
+ if (ret)
+ delay(500);
+ else
+ break;
}
+ if (ret)
+ return -1;
switch (size) {
case 1:
diff --git a/sys/arch/mvme88k/stand/bootsd/Makefile b/sys/arch/mvme88k/stand/bootsd/Makefile
index a44e8916872..63dfa97be93 100644
--- a/sys/arch/mvme88k/stand/bootsd/Makefile
+++ b/sys/arch/mvme88k/stand/bootsd/Makefile
@@ -1,5 +1,5 @@
# from: @(#)Makefile 8.1 (Berkeley) 6/10/93
-# $OpenBSD: Makefile,v 1.4 1998/12/15 06:32:33 smurph Exp $
+# $OpenBSD: Makefile,v 1.5 1999/05/29 04:41:47 smurph Exp $
RELOC=0xCF0000
@@ -18,7 +18,7 @@ CLEANFILES+=bootsd
SRCS= boot.c conf.c version.c
-LIBS= ${LIBSA} ${LIBBUG} ${LIBZ} -lgcc -lc -lgcc
+LIBS= ${LIBSA} ${LIBBUG} ${LIBZ} ${LIBGCC}
OBJS= ${SRCS:N*.h:R:S/$/.o/g}
@@ -27,10 +27,10 @@ ALL= ${BOOTS}
all: ${ALL}
-bootsd: ${OBJS} ${BUGCRT} ${LIBS}
+bootsd: ${OBJS} ${SDCRT} ${LIBS}
${LD} ${LDFLAGS} -o $@ \
${SDCRT} ${OBJS} ${LIBS}
-#${SRTOBJ}
+
install:
install -c -m 555 -g bin -o bin ${BOOTS} ${DESTDIR}${MDEC_DIR}
diff --git a/sys/arch/mvme88k/stand/bootst/Makefile b/sys/arch/mvme88k/stand/bootst/Makefile
index e704666e79e..8d765cc1766 100644
--- a/sys/arch/mvme88k/stand/bootst/Makefile
+++ b/sys/arch/mvme88k/stand/bootst/Makefile
@@ -1,5 +1,5 @@
# from: @(#)Makefile 8.1 (Berkeley) 6/10/93
-# $OpenBSD: Makefile,v 1.4 1998/12/15 06:09:51 smurph Exp $
+# $OpenBSD: Makefile,v 1.5 1999/05/29 04:41:47 smurph Exp $
RELOC=0xAF0000
SIZE?= size
@@ -9,6 +9,7 @@ DEFS= -DSTANDALONE -DCOMPAT_NOLABEL
INCPATH=-I${.CURDIR} -I${.CURDIR}/../libsa -I${.CURDIR}/../libbug \
-I${.CURDIR}/../../include -I${S} -I${S}/lib/libsa
CFLAGS= -O2 ${INCPATH} ${DEFS} ${COPTS}
+LDFLAGS=-s -N -T ${RELOC}
CLEANFILES+=stboot bootst bootst.bug
.include "${S}/arch/mvme88k/stand/wrtvid/Makefile.inc"
@@ -19,7 +20,7 @@ CLEANFILES+=stboot bootst bootst.bug
SRCS= boot.c conf.c dev_tape.c rawfs.c version.c
-LIBS= ${LIBSA} ${LIBBUG} ${LIBZ} libgcc.a
+LIBS= ${LIBSA} ${LIBBUG} ${LIBZ}
OBJS= ${SRCS:N*.h:R:S/$/.o/g}
@@ -29,7 +30,7 @@ ALL= ${BOOTS}
all: ${ALL}
bootst.bug: ${OBJS} ${BUGCRT} ${LIBS}
- ${LD} -s -N -T ${RELOC} ${BUGCRT} ${OBJS} ${LIBS} -o $@
+ ${LD} ${LDFLAGS} ${BUGCRT} ${OBJS} ${LIBS} -o $@
@${SIZE} bootst.bug
bootst stboot: bootst.bug ${WRTVID}
diff --git a/sys/arch/mvme88k/stand/bootxx/Makefile b/sys/arch/mvme88k/stand/bootxx/Makefile
index d9e3b8891a1..1e04e3eaf25 100644
--- a/sys/arch/mvme88k/stand/bootxx/Makefile
+++ b/sys/arch/mvme88k/stand/bootxx/Makefile
@@ -1,5 +1,5 @@
# from: @(#)Makefile 8.1 (Berkeley) 6/10/93
-# $OpenBSD: Makefile,v 1.3 1998/12/15 06:32:34 smurph Exp $
+# $OpenBSD: Makefile,v 1.4 1999/05/29 04:41:48 smurph Exp $
RELOC=0xAF0000
@@ -17,7 +17,7 @@ CLEANFILES+=bootxx
SRCS= bootxx.c conf.c version.c
-LIBS= ${LIBSA} ${LIBBUG} ${LIBZ} -lgcc -lc -lgcc
+LIBS= ${LIBSA} ${LIBBUG} ${LIBZ} ${LIBGCC}
OBJS= ${SRCS:N*.h:R:S/$/.o/g}
diff --git a/sys/arch/mvme88k/stand/netboot/Makefile b/sys/arch/mvme88k/stand/netboot/Makefile
index ee920ad3152..10c150fe1e0 100644
--- a/sys/arch/mvme88k/stand/netboot/Makefile
+++ b/sys/arch/mvme88k/stand/netboot/Makefile
@@ -1,5 +1,5 @@
-# $OpenBSD: Makefile,v 1.5 1998/12/15 06:32:35 smurph Exp $
+# $OpenBSD: Makefile,v 1.6 1999/05/29 04:41:48 smurph Exp $
RELOC=0xAF0000
SIZE?= size
@@ -21,7 +21,7 @@ CLEANFILES+=netboot netboot.bin
SRCS= boot.c conf.c version.c devopen.c dev_net.c
SRCS+= if_ie.c if_le.c
OBJS= ${SRCS:S/.c/.o/g}
-LIBS= ${LIBSA} ${LIBBUG} ${LIBZ} -lgcc -lc -lgcc
+LIBS= ${LIBSA} ${LIBBUG} ${LIBZ} ${LIBGCC}
LDFLAGS+= -s -N -T ${RELOC}
#LDFLAGS+= -nostdlib -s -N -Ttext ${RELOC}
diff --git a/sys/arch/mvme88k/stand/netboot/config.h b/sys/arch/mvme88k/stand/netboot/config.h
index b79bd88e9ad..895f749d0f9 100644
--- a/sys/arch/mvme88k/stand/netboot/config.h
+++ b/sys/arch/mvme88k/stand/netboot/config.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.h,v 1.1 1998/08/22 08:37:56 smurph Exp $ */
+/* $OpenBSD: config.h,v 1.2 1999/05/29 04:41:48 smurph Exp $ */
/*
* Copyright (c) 1995 Theo de Raadt
@@ -45,6 +45,8 @@
#define CPU_172 0x172
#define CPU_177 0x177
#define CPU_187 0x187
+#define CPU_188 0x188
+#define CPU_197 0x197
struct brdid {
u_long eye_catcher;