Several fixes. This version actually works!

This commit is contained in:
gwr 1997-12-08 19:22:52 +00:00
parent 1a340a5921
commit ec9abe23be
1 changed files with 132 additions and 33 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ie_sebuf.c,v 1.3 1997/10/25 18:04:21 gwr Exp $ */
/* $NetBSD: if_ie_sebuf.c,v 1.4 1997/12/08 19:22:52 gwr Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -73,6 +73,14 @@ static void ie_sebuf_reset __P((struct ie_softc *));
static void ie_sebuf_attend __P((struct ie_softc *));
static void ie_sebuf_run __P((struct ie_softc *));
/*
* zero/copy functions: OBIO can use the normal functions, but VME
* must do only byte or half-word (16 bit) accesses...
*/
static void wcopy __P((const void *vb1, void *vb2, u_int l));
static void wzero __P((void *vb, u_int l));
/*
* New-style autoconfig attachment
*/
@ -117,8 +125,19 @@ ie_sebuf_attach(parent, self, args)
sc->reset_586 = ie_sebuf_reset;
sc->chan_attn = ie_sebuf_attend;
sc->run_586 = ie_sebuf_run;
sc->sc_bcopy = bcopy;
sc->sc_bzero = bzero;
sc->sc_bcopy = wcopy;
sc->sc_bzero = wzero;
/* Control regs mapped by parent. */
sc->sc_reg = aa->regs;
regs = (struct ie_regs *) sc->sc_reg;
/*
* On this hardware, the i82586 address zero
* maps to the start of the board, which we
* happen to know is 128K below (XXX).
*/
sc->sc_iobase = aa->buf - 0x20000;
/*
* There is 128K of memory for the i82586 on
@ -130,18 +149,19 @@ ie_sebuf_attach(parent, self, args)
panic("ie_sebuf: bad size");
sc->sc_msize = SE_IEBUFSIZE;
sc->sc_maddr = aa->buf;
sc->sc_reg = aa->regs;
regs = (volatile struct ie_regs *) sc->sc_reg;
/*
* On this hardware, the i82586 address is just
* masked to 17 bits, so sc_iobase == sc_maddr
*/
sc->sc_iobase = sc->sc_maddr;
/* Clear the memory. */
(sc->sc_bzero)(sc->sc_maddr, sc->sc_msize);
/*
* XXX: Unfortunately, the common driver code
* is not ready to deal with more than 64K of
* memory, so skip the first 64K. Too bad.
* Note: device needs the SCP at the end.
*/
sc->sc_msize -= 0x10000;
sc->sc_maddr += 0x10000;
/*
* Set the System Configuration Pointer (SCP).
* Its location is system-dependent because the
@ -150,8 +170,8 @@ ie_sebuf_attach(parent, self, args)
* masked down to 17 bits, so the SCP is found
* at the end of the RAM on the VME board.
*/
off = IE_SCP_ADDR & (SE_IEBUFSIZE-1);
sc->scp = (volatile void *) (sc->sc_iobase + off);
off = IE_SCP_ADDR & 0xFFFF;
sc->scp = (volatile void *) (sc->sc_maddr + off);
/*
* The rest of ram is used for buffers, etc.
@ -159,33 +179,20 @@ ie_sebuf_attach(parent, self, args)
sc->buf_area = sc->sc_maddr;
sc->buf_area_sz = off;
/* Set the ethernet address. */
idprom_etheraddr(sc->sc_addr);
/* Install interrupt handler. */
regs->ie_ivec = aa->ca.ca_intvec;
isr_add_vectored(ie_intr, (void *)sc,
aa->ca.ca_intpri, aa->ca.ca_intvec);
/* Set the ethernet address. */
idprom_etheraddr(sc->sc_addr);
/* Do machine-independent parts of attach. */
ie_attach(sc);
}
/*
* MULTIBUS/VME support
*/
void
ie_sebuf_reset(sc)
struct ie_softc *sc;
{
volatile struct ie_regs *regs = (struct ie_regs *) sc->sc_reg;
regs->ie_csr = IE_CSR_RESET;
delay(10);
regs->ie_csr = 0;
}
/* Whack the "channel attetion" line. */
void
ie_sebuf_attend(sc)
struct ie_softc *sc;
@ -196,11 +203,103 @@ ie_sebuf_attend(sc)
regs->ie_csr &= ~IE_CSR_ATTEN; /* down. */
}
/*
* This is called during driver attach.
* Reset and initialize.
*/
void
ie_sebuf_run(sc)
ie_sebuf_reset(sc)
struct ie_softc *sc;
{
volatile struct ie_regs *regs = (struct ie_regs *) sc->sc_reg;
regs->ie_csr |= IE_CSR_IENAB;
regs->ie_csr = IE_CSR_RESET;
delay(20);
regs->ie_csr = (IE_CSR_NOLOOP | IE_CSR_IENAB);
}
/*
* This is called at the end of ieinit().
* optional.
*/
void
ie_sebuf_run(sc)
struct ie_softc *sc;
{
/* do it all in reset */
}
/*
* wcopy/wzero - like bcopy/bzero but largest access is 16-bits,
* and also does byte swaps...
* XXX - Would be nice to have asm versions in some library...
*/
static void
wzero(vb, l)
void *vb;
u_int l;
{
u_char *b = vb;
u_char *be = b + l;
u_short *sp;
if (l == 0)
return;
/* front, */
if ((u_long)b & 1)
*b++ = 0;
/* back, */
if (b != be && ((u_long)be & 1) != 0) {
be--;
*be = 0;
}
/* and middle. */
sp = (u_short *)b;
while (sp != (u_short *)be)
*sp++ = 0;
}
static void
wcopy(vb1, vb2, l)
const void *vb1;
void *vb2;
u_int l;
{
const u_char *b1e, *b1 = vb1;
u_char *b2 = vb2;
u_short *sp;
int bstore = 0;
if (l == 0)
return;
/* front, */
if ((u_long)b1 & 1) {
*b2++ = *b1++;
l--;
}
/* middle, */
sp = (u_short *)b1;
b1e = b1 + l;
if (l & 1)
b1e--;
bstore = (u_long)b2 & 1;
while (sp < (u_short *)b1e) {
if (bstore) {
b2[1] = *sp & 0xff;
b2[0] = *sp >> 8;
} else
*((short *)b2) = *sp;
sp++;
b2 += 2;
}
/* and back. */
if (l & 1)
*b2 = *b1e;
}