summaryrefslogtreecommitdiff
path: root/sys/arch/mvme68k/stand/sboot
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/mvme68k/stand/sboot')
-rw-r--r--sys/arch/mvme68k/stand/sboot/Makefile19
-rw-r--r--sys/arch/mvme68k/stand/sboot/clock.c117
-rw-r--r--sys/arch/mvme68k/stand/sboot/clockreg.h69
-rw-r--r--sys/arch/mvme68k/stand/sboot/console.c139
-rw-r--r--sys/arch/mvme68k/stand/sboot/etherfun.c213
-rw-r--r--sys/arch/mvme68k/stand/sboot/etherfun.h124
-rw-r--r--sys/arch/mvme68k/stand/sboot/if_lereg.h176
-rw-r--r--sys/arch/mvme68k/stand/sboot/le_poll.c320
-rw-r--r--sys/arch/mvme68k/stand/sboot/libc_sa.c348
-rw-r--r--sys/arch/mvme68k/stand/sboot/oc_cksum.s187
-rw-r--r--sys/arch/mvme68k/stand/sboot/sboot.c150
-rw-r--r--sys/arch/mvme68k/stand/sboot/sboot.h96
-rw-r--r--sys/arch/mvme68k/stand/sboot/start.s47
13 files changed, 2005 insertions, 0 deletions
diff --git a/sys/arch/mvme68k/stand/sboot/Makefile b/sys/arch/mvme68k/stand/sboot/Makefile
new file mode 100644
index 00000000000..fb80ad4e86f
--- /dev/null
+++ b/sys/arch/mvme68k/stand/sboot/Makefile
@@ -0,0 +1,19 @@
+# $NetBSD: Makefile,v 1.1.1.1 1995/07/25 23:12:28 chuck Exp $
+
+#
+# sboot needs GNU ld because it can generate S-Records
+#
+
+COMPILE.s= $(AS) $(ASFLAGS) -o $*.o
+GNU_LD=/usr/local/bin/ld
+LDFLAGS=-oformat srec -x -N -Ttext 0x4000 -e start
+NOMAN=
+PROG= sboot
+SRCS= start.s clock.c console.c etherfun.c le_poll.c libc_sa.c \
+ oc_cksum.s sboot.c
+
+${PROG}: ${OBJS}
+ ${GNU_LD} ${LDFLAGS} -o ${.TARGET} ${OBJS}
+
+.include <bsd.prog.mk>
+
diff --git a/sys/arch/mvme68k/stand/sboot/clock.c b/sys/arch/mvme68k/stand/sboot/clock.c
new file mode 100644
index 00000000000..f6e344b7b9d
--- /dev/null
+++ b/sys/arch/mvme68k/stand/sboot/clock.c
@@ -0,0 +1,117 @@
+/* $NetBSD: clock.c,v 1.1.1.1 1995/07/25 23:12:28 chuck Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1994 Gordon W. Ross
+ * Copyright (c) 1993 Adam Glass
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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, 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.
+ *
+ * @(#)clock.c 8.1 (Berkeley) 6/11/93
+ */
+
+/*
+ * Clock driver.
+ */
+
+#include "sboot.h"
+#include "clockreg.h"
+static struct clockreg *clockreg = (struct clockreg *) CLOCK_ADDR;
+
+/*
+ * BCD to decimal and decimal to BCD.
+ */
+#define FROMBCD(x) (((x) >> 4) * 10 + ((x) & 0xf))
+#define TOBCD(x) (((x) / 10 * 16) + ((x) % 10))
+
+#define SECDAY (24 * 60 * 60)
+#define SECYR (SECDAY * 365)
+#define LEAPYEAR(y) (((y) & 3) == 0)
+
+/*
+ * This code is defunct after 2068.
+ * Will Unix still be here then??
+ */
+const short dayyr[12] =
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+
+static u_long chiptotime(sec, min, hour, day, mon, year)
+ register int sec, min, hour, day, mon, year;
+{
+ register int days, yr;
+
+ sec = FROMBCD(sec);
+ min = FROMBCD(min);
+ hour = FROMBCD(hour);
+ day = FROMBCD(day);
+ mon = FROMBCD(mon);
+ year = FROMBCD(year) + YEAR0;
+ if (year < 70) year = 70;
+
+ /* simple sanity checks */
+ if (year < 70 || mon < 1 || mon > 12 || day < 1 || day > 31)
+ return (0);
+ days = 0;
+ for (yr = 70; yr < year; yr++)
+ days += LEAPYEAR(yr) ? 366 : 365;
+ days += dayyr[mon - 1] + day - 1;
+ if (LEAPYEAR(yr) && mon > 2)
+ days++;
+ /* now have days since Jan 1, 1970; the rest is easy... */
+ return (days * SECDAY + hour * 3600 + min * 60 + sec);
+}
+
+/*
+ * Set up the system's time, given a `reasonable' time value.
+ */
+u_long time()
+{
+ register struct clockreg *cl = clockreg;
+ int sec, min, hour, day, mon, year;
+
+ cl->cl_csr |= CLK_READ; /* enable read (stop time) */
+ sec = cl->cl_sec;
+ min = cl->cl_min;
+ hour = cl->cl_hour;
+ day = cl->cl_mday;
+ mon = cl->cl_month;
+ year = cl->cl_year;
+ cl->cl_csr &= ~CLK_READ; /* time wears on */
+ return(chiptotime(sec, min, hour, day, mon, year));
+}
diff --git a/sys/arch/mvme68k/stand/sboot/clockreg.h b/sys/arch/mvme68k/stand/sboot/clockreg.h
new file mode 100644
index 00000000000..dbbf313f3d1
--- /dev/null
+++ b/sys/arch/mvme68k/stand/sboot/clockreg.h
@@ -0,0 +1,69 @@
+/* $NetBSD: clockreg.h,v 1.1.1.1 1995/07/25 23:12:29 chuck Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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, 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.
+ *
+ * @(#)clockreg.h 8.1 (Berkeley) 6/11/93
+ */
+
+/*
+ * Mostek MK48T02 clock.
+ */
+struct clockreg {
+ volatile u_char cl_csr; /* control register */
+ volatile u_char cl_sec; /* seconds (0..59; BCD) */
+ volatile u_char cl_min; /* minutes (0..59; BCD) */
+ volatile u_char cl_hour; /* hour (0..23; BCD) */
+ volatile u_char cl_wday; /* weekday (1..7) */
+ volatile u_char cl_mday; /* day in month (1..31; BCD) */
+ volatile u_char cl_month; /* month (1..12; BCD) */
+ volatile u_char cl_year; /* year (0..99; BCD) */
+};
+
+/* bits in cl_csr */
+#define CLK_WRITE 0x80 /* want to write */
+#define CLK_READ 0x40 /* want to read (freeze clock) */
+
+/*
+ * Sun chose the year `68' as their base count, so that
+ * cl_year==0 means 1968.
+ */
+#define YEAR0 68
diff --git a/sys/arch/mvme68k/stand/sboot/console.c b/sys/arch/mvme68k/stand/sboot/console.c
new file mode 100644
index 00000000000..19f01dcada8
--- /dev/null
+++ b/sys/arch/mvme68k/stand/sboot/console.c
@@ -0,0 +1,139 @@
+/*
+ *
+ * Copyright (c) 1995 Charles D. Cranor and Seth Widoff
+ * 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 D. Cranor
+ * and Seth Widoff.
+ * 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.
+ */
+/*
+ * console i/o
+ */
+
+#include "sboot.h"
+
+/*
+ * hardware
+ */
+
+struct zs_hw {
+ volatile u_char ctl;
+ volatile u_char data;
+};
+
+struct zs_hw *zs = (struct zs_hw *)CONS_ZS_ADDR;
+
+/*
+ * consinit: init console
+ */
+
+consinit()
+
+{
+ register int mark = time();
+ register int rr1;
+ while (1) {
+ if (time() > mark + 5) break;
+ zs->ctl = 1; rr1 = zs->ctl;
+ zs->ctl = 0;
+ if ((rr1 & 0x1) == 1 && (zs->ctl & 0x4) == 4) break; /* zs_drain! */
+ }
+ zs->ctl = 9; zs->ctl = 0x00; /* clear interrupt */
+ zs->ctl = 4; zs->ctl = 0x44; /* 16x clk, 1 stop bit */
+ zs->ctl = 5; zs->ctl = 0xea; /* DTR on, 8 bit xmit, xmit on, RTS on */
+ zs->ctl = 3; zs->ctl = 0xc1; /* 8 bit recv, auto cd_cts, recv on */
+ zs->ctl = 1; zs->ctl = 0x00; /* no intrs */
+ zs->ctl = 2; zs->ctl = 0x00; /* no vector */
+ zs->ctl = 10; zs->ctl = 0x00; /* */
+ zs->ctl = 11; zs->ctl = 0x50; /* clocking options */
+ zs->ctl = 12; zs->ctl = 0x0e; /* 9600 baud, part 1 */
+ zs->ctl = 13; zs->ctl = 0x00; /* 9600 baud, part 2 */
+ zs->ctl = 14; zs->ctl = 0x03; /* more clocking options */
+ zs->ctl = 15; zs->ctl = 0x00; /* clear intrs */
+}
+
+/*
+ * putchar: put char to console
+ */
+
+void putchar(char c)
+{
+ if (c == '\n') putchar('\r'); /* avoid the need for \r\n in printf */
+ zs->ctl = 0;
+ while ((zs->ctl & 0x04) == 0) {
+ zs->ctl = 0;
+ }
+ zs->ctl = 8;
+ zs->ctl = c;
+}
+
+/*
+ * cngetc: get 1 char from console
+ */
+
+char cngetc ()
+{
+ zs->ctl = 0;
+ while ((zs->ctl & 0x1) == 0) {
+ zs->ctl = 0;
+ }
+ zs->ctl = 8;
+ return zs->ctl;
+}
+
+/*
+ * puts: put string to console
+ */
+
+void puts ( char * str )
+{
+ while ( *str != '\0' ) {
+ putchar(*str);
+ str++;
+ }
+}
+
+/*
+ * ngets: get string from console
+ */
+
+void ngets ( char * str, int size )
+{
+ int i = 0;
+ while ( (i < size - 1) && (str[i] = cngetc()) != '\r') {
+ if ( str[i] == '\b' || str[i] == 0x7F ) {
+ if ( i == 0) continue;
+ i--;
+ puts("\b \b");
+ continue;
+ }
+ putchar(str[i]);
+ i++;
+ }
+ puts("\n");
+ str[i] = '\0';
+}
+
diff --git a/sys/arch/mvme68k/stand/sboot/etherfun.c b/sys/arch/mvme68k/stand/sboot/etherfun.c
new file mode 100644
index 00000000000..7c107b00e8a
--- /dev/null
+++ b/sys/arch/mvme68k/stand/sboot/etherfun.c
@@ -0,0 +1,213 @@
+/*
+ *
+ * Copyright (c) 1995 Charles D. Cranor and Seth Widoff
+ * 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 D. Cranor
+ * and Seth Widoff.
+ * 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.
+ */
+/* etherfun.c */
+
+#include "sboot.h"
+#include "etherfun.h"
+
+/* Construct and send a rev arp packet */
+void
+do_rev_arp ()
+{
+ int i;
+
+ for ( i = 0; i < 6; i++ ) {
+ eh->ether_dhost[i] = 0xff;
+ }
+ bcopy(myea, eh->ether_shost, 6);
+ eh->ether_type = ETYPE_RARP;
+
+ rarp->ar_hrd = 1; /* hardware type is 1 */
+ rarp->ar_pro = PTYPE_IP;
+ rarp->ar_hln = 6; /* length of hardware address is 6 bytes */
+ rarp->ar_pln = 4; /* length of ip address is 4 byte */
+ rarp->ar_op = OPCODE_RARP;
+ bcopy(myea, rarp->arp_sha, sizeof(myea));
+ bcopy(myea, rarp->arp_tha, sizeof(myea));
+ for ( i = 0; i < 4; i++ ) {
+ rarp->arp_spa[i] = rarp->arp_tpa[i] = 0x00;
+ }
+
+ le_put(buf, 76);
+}
+
+/* Recieve and disassemble the rev_arp reply */
+
+int
+get_rev_arp ()
+{
+ le_get(buf, sizeof(buf), 6);
+ if ( eh->ether_type == ETYPE_RARP && rarp->ar_op == OPCODE_REPLY ) {
+ bcopy(rarp->arp_tpa, myip, sizeof(rarp->arp_tpa));
+ bcopy(rarp->arp_spa, servip, sizeof(rarp->arp_spa));
+ bcopy(rarp->arp_sha, servea, sizeof(rarp->arp_sha));
+ return 1;
+ }
+ return 0;
+}
+
+/* Try to get a reply to a rev arp request */
+
+int
+rev_arp ()
+{
+ int tries = 0;
+ while ( tries < 5 ) {
+ do_rev_arp();
+ if ( get_rev_arp() ) {
+ return 1;
+ }
+ tries++;
+ }
+ return 0;
+}
+
+/* Send a tftp read request or acknowledgement
+ mesgtype 0 is a read request, 1 is an aknowledgement */
+
+void
+do_send_tftp ( int mesgtype )
+{
+ u_long res, iptmp, lcv;
+ char *tot;
+
+ if ( mesgtype == 0 ) {
+ tot = tftp_r + (sizeof(MSG)-1);
+ myport = (u_short)time();
+ if (myport < 1000) myport += 1000;
+ servport = FTP_PORT; /* to start */
+ } else {
+ tot = (char *)tftp_a + 4;
+ }
+
+ bcopy (servea, eh->ether_dhost, sizeof(servea));
+ bcopy (myea, eh->ether_shost, sizeof(myea));
+ eh->ether_type = ETYPE_IP;
+
+ iph->ip_v = IP_VERSION;
+ iph->ip_hl = IP_HLEN;
+ iph->ip_tos = 0; /* type of service is 0 */
+ iph->ip_id = 0; /* id field is 0 */
+ iph->ip_off = IP_DF;
+ iph->ip_ttl = 3; /* time to live is 3 seconds/hops */
+ iph->ip_p = IPP_UDP;
+ bcopy(myip, iph->ip_src, sizeof(myip));
+ bcopy(servip, iph->ip_dst, sizeof(servip));
+ iph->ip_sum = 0;
+ iph->ip_len = tot - (char *)iph;
+ res = oc_cksum(iph, sizeof(struct ip), 0);
+ iph->ip_sum = 0xffff & ~res;
+ udph->uh_sport = myport;
+ udph->uh_dport = servport;
+ udph->uh_sum = 0;
+
+ if ( mesgtype ) {
+ tftp_a->op_code = FTPOP_ACKN;
+ tftp_a->block = (u_short)(mesgtype);
+ } else {
+ bcopy (myip, &iptmp, sizeof(iptmp));
+ bcopy(MSG, tftp_r, (sizeof(MSG)-1));
+ for (lcv = 9; lcv >= 2; lcv--) {
+ tftp_r[lcv] = "0123456789ABCDEF"[iptmp & 0xF];
+
+ iptmp = iptmp >> 4;
+ }
+ }
+
+ udph->uh_ulen = tot - (char *)udph;
+
+ le_put( buf, tot - buf);
+}
+
+/* Attempt to tftp a file and read it into memory */
+
+int
+do_get_file ()
+{
+ int fail = 0, oldlen;
+ char *loadat = (char *)LOAD_ADDR;
+ last_ack = 0;
+
+ do_send_tftp( READ );
+ while (1) {
+ if ( le_get(buf, sizeof(buf), 5) == 0) { /* timeout occured */
+ if ( last_ack ) {
+ do_send_tftp( last_ack );
+ } else {
+ do_send_tftp( READ );
+ }
+ fail++;
+ if ( fail > 5 ) {
+ printf("\n");
+ return 1;
+ }
+ } else {
+ printf("%x \r", tftp->info.block*512);
+ if ((eh->ether_type != ETYPE_IP) || (iph->ip_p != IPP_UDP)) {
+ fail++;
+ continue;
+ }
+ if (servport == FTP_PORT) servport = udph->uh_sport;
+ if (tftp->info.op_code == FTPOP_ERR) {
+ printf("TFTP: Download error %d: %s\n",
+ tftp->info.block, tftp->data);
+ return 1;
+ }
+ if (tftp->info.block != last_ack + 1) { /* we recieved the wrong block */
+ if (tftp->info.block < last_ack +1) {
+ do_send_tftp(tftp->info.block); /* ackn whatever we recieved */
+ } else {
+ do_send_tftp( last_ack ); /* ackn the last confirmed block */
+ }
+ fail++;
+ } else { /* we got the right block */
+ fail = 0;
+ last_ack++;
+ oldlen = udph->uh_ulen;
+ do_send_tftp( last_ack );
+ /*printf("bcopy %x %x %d\n", &tftp->data, loadat, oldlen - 12);*/
+ bcopy(&tftp->data, loadat, oldlen - 12);
+ loadat += oldlen - 12;
+ if (oldlen < (8 + 4 + 512)) {
+ printf("\n");
+ return 0;
+ }
+ }
+ }
+ }
+ printf("\n");
+ return 0;
+}
+
+
+
+
diff --git a/sys/arch/mvme68k/stand/sboot/etherfun.h b/sys/arch/mvme68k/stand/sboot/etherfun.h
new file mode 100644
index 00000000000..2b6a14d69a5
--- /dev/null
+++ b/sys/arch/mvme68k/stand/sboot/etherfun.h
@@ -0,0 +1,124 @@
+/*
+ *
+ * Copyright (c) 1995 Charles D. Cranor and Seth Widoff
+ * 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 D. Cranor
+ * and Seth Widoff.
+ * 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.
+ */
+/* etherfun.h */
+
+/* constants */
+/* ether header */
+#define ETYPE_RARP 0x8035 /* ethertype is RARP */
+#define ETYPE_IP 0x800 /* ethertype is IP */
+
+/* rev arp */
+#define PTYPE_IP 0x800 /* Protocol type is IP */
+#define OPCODE_RARP 3 /* Optype is REVARP request */
+#define OPCODE_REPLY 4 /* Optype is REVARP reply */
+
+/* ip header */
+#define IPP_UDP 17 /* IP Protocol is UDP */
+#define IP_VERSION 4 /* IP version number */
+#define IP_HLEN 5 /* IP header length is a fixed 50 bytes */
+#define N 1536
+
+/* tftp header */
+#define FTPOP_ACKN 4 /* Opcode is acknowledge */
+#define FTPOP_ERR 5 /* Opcode is Error */
+#define FTP_PORT 69 /* Standard TFTP port number */
+#define MSG "\0\1xxxxxxxx.147\0octet\0" /* implicit NULL */
+
+/* data structures */
+
+struct ether_header {
+ u_char ether_dhost[6];
+ u_char ether_shost[6];
+ u_short ether_type;
+};
+
+struct ether_arp {
+ u_short ar_hrd; /* format of hardware address */
+ u_short ar_pro; /* format of protocol address */
+ u_char ar_hln; /* length of hardware address */
+ u_char ar_pln; /* length of protocol address */
+ u_short ar_op;
+ u_char arp_sha[6]; /* sender hardware address */
+ u_char arp_spa[4]; /* sender protocol address */
+ u_char arp_tha[6]; /* target hardware address */
+ u_char arp_tpa[4]; /* target protocol address */
+};
+
+struct ip {
+ u_char ip_v:4, /* version */
+ ip_hl:4; /* header length */
+ u_char ip_tos; /* type of service */
+ short ip_len; /* total length */
+ u_short ip_id; /* identification */
+ short ip_off; /* fragment offset field */
+#define IP_DF 0x4000 /* dont fragment flag */
+#define IP_MF 0x2000 /* more fragments flag */
+#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
+ u_char ip_ttl; /* time to live */
+ u_char ip_p; /* protocol */
+ u_short ip_sum; /* checksum */
+ u_char ip_src[4];
+ u_char ip_dst[4]; /* source and dest address */
+};
+
+struct udp {
+ u_short uh_sport;
+ u_short uh_dport;
+ short uh_ulen;
+ u_short uh_sum;
+};
+
+struct tftph {
+ u_short op_code;
+ u_short block;
+};
+
+struct tftphr {
+ struct tftph info;
+ char data[1];
+};
+
+/* globals */
+int last_ack;
+char buf[N];
+struct ether_header *eh = (struct ether_header *)buf;
+struct ether_arp *rarp =
+ (struct ether_arp *)(buf + sizeof(struct ether_header));
+struct ip *iph = (struct ip *)(buf + sizeof(struct ether_header));
+struct udp *udph = (struct udp *)(buf + sizeof(struct ether_header) +
+ sizeof(struct ip));
+char *tftp_r = buf + sizeof(struct ether_header) + sizeof(struct ip) +
+ sizeof(struct udp);
+struct tftph *tftp_a = (struct tftph *)(buf + sizeof(struct ether_header) +
+ sizeof(struct ip) + sizeof(struct udp));
+struct tftphr *tftp = (struct tftphr *)(buf + sizeof(struct ether_header) +
+ sizeof(struct ip) + sizeof(struct udp));
diff --git a/sys/arch/mvme68k/stand/sboot/if_lereg.h b/sys/arch/mvme68k/stand/sboot/if_lereg.h
new file mode 100644
index 00000000000..bae9a85fbd5
--- /dev/null
+++ b/sys/arch/mvme68k/stand/sboot/if_lereg.h
@@ -0,0 +1,176 @@
+/* $NetBSD: if_lereg.h,v 1.1.1.1 1995/07/25 23:12:31 chuck 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 LEMTU 1518
+#define LEMINSIZE 60 /* should be 64 if mode DTCR is set */
+#define LERBUF 8
+#define LERBUFLOG2 3
+#define LE_RLEN (LERBUFLOG2 << 13)
+#define LETBUF 1
+#define LETBUFLOG2 0
+#define LE_TLEN (LETBUFLOG2 << 13)
+
+/* Local Area Network Controller for Ethernet (LANCE) registers */
+struct lereg1 {
+ volatile u_short ler1_rdp; /* register data port */
+ volatile u_short ler1_rap; /* register address port */
+};
+
+/* register addresses */
+#define LE_CSR0 0 /* Control and status register */
+#define LE_CSR1 1 /* low address of init block */
+#define LE_CSR2 2 /* high address of init block */
+#define LE_CSR3 3 /* 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 0x4 /* byte swap */
+#define LE_C3_ACON 0x2 /* ALE control, eh? */
+#define LE_C3_BCON 0x1 /* byte control */
+/*
+ * Current size is 13,758 bytes with 8 x 1518 receive buffers and
+ * 1 x 1518 transmit buffer.
+ */
+struct lereg2 {
+ /* initialization block */
+ volatile u_short ler2_mode; /* mode */
+ volatile u_char ler2_padr[6]; /* physical address */
+#ifdef new_code
+ volatile u_short ler2_ladrf[4]; /* logical address filter */
+#else
+ volatile u_long ler2_ladrf0; /* logical address filter */
+ volatile u_long ler2_ladrf1; /* logical address filter */
+#endif
+ volatile u_short ler2_rdra; /* receive descriptor addr */
+ volatile u_short ler2_rlen; /* rda high and ring size */
+ volatile u_short ler2_tdra; /* transmit descriptor addr */
+ volatile u_short ler2_tlen; /* tda high and ring size */
+ /* receive message descriptors. bits/hadr are byte order dependent. */
+ struct lermd {
+ volatile u_short rmd0; /* low address of packet */
+ volatile u_char rmd1_bits; /* descriptor bits */
+ volatile u_char rmd1_hadr; /* high address of packet */
+ volatile short rmd2; /* buffer byte count */
+ volatile u_short rmd3; /* message byte count */
+ } ler2_rmd[LERBUF];
+ /* transmit message descriptors */
+ struct letmd {
+ volatile u_short tmd0; /* low address of packet */
+ volatile u_char tmd1_bits; /* descriptor bits */
+ volatile u_char tmd1_hadr; /* high address of packet */
+ volatile short tmd2; /* buffer byte count */
+ volatile u_short tmd3; /* transmit error bits */
+ } ler2_tmd[LETBUF];
+ volatile char ler2_rbuf[LERBUF][LEMTU];
+ volatile char ler2_tbuf[LETBUF][LEMTU];
+};
+
+/* 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"
+
+
+#define LE_ADDR_LOW_MASK (0xffff)
+
diff --git a/sys/arch/mvme68k/stand/sboot/le_poll.c b/sys/arch/mvme68k/stand/sboot/le_poll.c
new file mode 100644
index 00000000000..a958b746a36
--- /dev/null
+++ b/sys/arch/mvme68k/stand/sboot/le_poll.c
@@ -0,0 +1,320 @@
+/* $NetBSD: le_poll.c,v 1.1.1.1 1995/07/25 23:12:31 chuck Exp $ */
+
+/*
+ * Copyright (c) 1993 Adam Glass
+ * 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 Adam Glass.
+ * 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 Adam Glass ``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.
+ */
+
+#include "sboot.h"
+#include "if_lereg.h"
+
+struct {
+ struct lereg1 *sc_r1; /* LANCE registers */
+ struct lereg2 *sc_r2; /* RAM */
+ int next_rmd;
+ int next_tmd;
+} le_softc;
+
+void le_error(str, ler1)
+ char *str;
+ struct lereg1 *ler1;
+{
+ /* ler1->ler1_rap = LE_CSRO done in caller */
+ if (ler1->ler1_rdp & LE_C0_BABL) {
+ printf("le0: been babbling, found by '%s'\n", str);
+ callrom();
+ }
+ if (ler1->ler1_rdp & LE_C0_CERR) {
+ ler1->ler1_rdp = LE_C0_CERR;
+ }
+ if (ler1->ler1_rdp & LE_C0_MISS) {
+ ler1->ler1_rdp = LE_C0_MISS;
+ }
+ if (ler1->ler1_rdp & LE_C0_MERR) {
+ printf("le0: memory error in '%s'\n", str);
+ callrom();
+ }
+
+}
+
+void le_reset(myea)
+ u_char *myea;
+{
+ struct lereg1 *ler1 = le_softc.sc_r1;
+ struct lereg2 *ler2 = le_softc.sc_r2;
+ unsigned int a;
+ int timo = 100000, stat, i;
+
+ ler1->ler1_rap = LE_CSR0;
+ ler1->ler1_rdp = LE_C0_STOP; /* do nothing until we are finished */
+
+ bzero(ler2, sizeof(*ler2));
+
+ ler2->ler2_mode = LE_MODE_NORMAL;
+ ler2->ler2_padr[0] = myea[1];
+ ler2->ler2_padr[1] = myea[0];
+ ler2->ler2_padr[2] = myea[3];
+ ler2->ler2_padr[3] = myea[2];
+ ler2->ler2_padr[4] = myea[5];
+ ler2->ler2_padr[5] = myea[4];
+
+
+ ler2->ler2_ladrf0 = 0;
+ ler2->ler2_ladrf1 = 0;
+
+ a = (u_int)ler2->ler2_rmd;
+ ler2->ler2_rlen = LE_RLEN | (a >> 16);
+ ler2->ler2_rdra = a & LE_ADDR_LOW_MASK;
+
+ a = (u_int)ler2->ler2_tmd;
+ ler2->ler2_tlen = LE_TLEN | (a >> 16);
+ ler2->ler2_tdra = a & LE_ADDR_LOW_MASK;
+
+ ler1->ler1_rap = LE_CSR1;
+ a = (u_int)ler2;
+ ler1->ler1_rdp = a & LE_ADDR_LOW_MASK;
+ ler1->ler1_rap = LE_CSR2;
+ ler1->ler1_rdp = a >> 16;
+
+ for (i = 0; i < LERBUF; i++) {
+ a = (u_int)&ler2->ler2_rbuf[i];
+ ler2->ler2_rmd[i].rmd0 = a & LE_ADDR_LOW_MASK;
+ ler2->ler2_rmd[i].rmd1_bits = LE_R1_OWN;
+ ler2->ler2_rmd[i].rmd1_hadr = a >> 16;
+ ler2->ler2_rmd[i].rmd2 = -LEMTU;
+ ler2->ler2_rmd[i].rmd3 = 0;
+ }
+ for (i = 0; i < LETBUF; i++) {
+ a = (u_int)&ler2->ler2_tbuf[i];
+ ler2->ler2_tmd[i].tmd0 = a & LE_ADDR_LOW_MASK;
+ ler2->ler2_tmd[i].tmd1_bits = 0;
+ ler2->ler2_tmd[i].tmd1_hadr = a >> 16;
+ ler2->ler2_tmd[i].tmd2 = 0;
+ ler2->ler2_tmd[i].tmd3 = 0;
+ }
+
+ ler1->ler1_rap = LE_CSR3;
+ ler1->ler1_rdp = LE_C3_BSWP;
+
+ ler1->ler1_rap = LE_CSR0;
+ ler1->ler1_rdp = LE_C0_INIT;
+ do {
+ if (--timo == 0) {
+ printf("le0: init timeout, stat = 0x%x\n", stat);
+ break;
+ }
+ stat = ler1->ler1_rdp;
+ } while ((stat & LE_C0_IDON) == 0);
+
+ ler1->ler1_rdp = LE_C0_IDON;
+ le_softc.next_rmd = 0;
+ le_softc.next_tmd = 0;
+ ler1->ler1_rap = LE_CSR0;
+ ler1->ler1_rdp = LE_C0_STRT;
+}
+
+int le_poll(pkt, len)
+ void *pkt;
+ int len;
+{
+ struct lereg1 *ler1 = le_softc.sc_r1;
+ struct lereg2 *ler2 = le_softc.sc_r2;
+ unsigned int a;
+ int length;
+ struct lermd *rmd;
+
+ ler1->ler1_rap = LE_CSR0;
+ if ((ler1->ler1_rdp & LE_C0_RINT) != 0)
+ ler1->ler1_rdp = LE_C0_RINT;
+ rmd = &ler2->ler2_rmd[le_softc.next_rmd];
+ if (rmd->rmd1_bits & LE_R1_OWN) {
+ return(0);
+ }
+ if (ler1->ler1_rdp & LE_C0_ERR)
+ le_error("le_poll", ler1);
+ if (rmd->rmd1_bits & LE_R1_ERR) {
+ printf("le0_poll: rmd status 0x%x\n", rmd->rmd1_bits);
+ length = 0;
+ goto cleanup;
+ }
+ if ((rmd->rmd1_bits & (LE_R1_STP|LE_R1_ENP)) != (LE_R1_STP|LE_R1_ENP)) {
+ printf("le_poll: chained packet\n");
+ callrom();
+ }
+
+ length = rmd->rmd3;
+ if (length >= LEMTU) {
+ length = 0;
+ printf("csr0 when bad things happen: %x\n", ler1->ler1_rdp);
+ callrom();
+ goto cleanup;
+ }
+ if (!length) goto cleanup;
+ length -= 4;
+ if (length > 0)
+ bcopy((char *)&ler2->ler2_rbuf[le_softc.next_rmd], pkt, length);
+
+ cleanup:
+ a = (u_int)&ler2->ler2_rbuf[le_softc.next_rmd];
+ rmd->rmd0 = a & LE_ADDR_LOW_MASK;
+ rmd->rmd1_hadr = a >> 16;
+ rmd->rmd2 = -LEMTU;
+ le_softc.next_rmd =
+ (le_softc.next_rmd == (LERBUF - 1)) ? 0 : (le_softc.next_rmd + 1);
+ rmd->rmd1_bits = LE_R1_OWN;
+ return length;
+}
+
+int le_put(pkt, len)
+ u_char *pkt;
+ size_t len;
+{
+ struct lereg1 *ler1 = le_softc.sc_r1;
+ struct lereg2 *ler2 = le_softc.sc_r2;
+ struct letmd *tmd;
+ int timo = 100000, stat, i;
+ unsigned int a;
+
+ ler1->ler1_rap = LE_CSR0;
+ if (ler1->ler1_rdp & LE_C0_ERR)
+ le_error("le_put(way before xmit)", ler1);
+ tmd = &ler2->ler2_tmd[le_softc.next_tmd];
+ while(tmd->tmd1_bits & LE_T1_OWN) {
+ printf("le0: output buffer busy\n");
+ }
+ bcopy(pkt, (char *)ler2->ler2_tbuf[le_softc.next_tmd], len);
+ if (len < 64)
+ tmd->tmd2 = -64;
+ else
+ tmd->tmd2 = -len;
+ tmd->tmd3 = 0;
+ if (ler1->ler1_rdp & LE_C0_ERR)
+ le_error("le_put(before xmit)", ler1);
+ tmd->tmd1_bits = LE_T1_STP | LE_T1_ENP | LE_T1_OWN;
+ a = (u_int)&ler2->ler2_tbuf[le_softc.next_tmd];
+ tmd->tmd0 = a & LE_ADDR_LOW_MASK;
+ tmd->tmd1_hadr = a >> 16;
+ ler1->ler1_rdp = LE_C0_TDMD;
+ if (ler1->ler1_rdp & LE_C0_ERR)
+ le_error("le_put(after xmit)", ler1);
+ do {
+ if (--timo == 0) {
+ printf("le0: transmit timeout, stat = 0x%x\n",
+ stat);
+ if (ler1->ler1_rdp & LE_C0_ERR)
+ le_error("le_put(timeout)", ler1);
+ break;
+ }
+ stat = ler1->ler1_rdp;
+ } while ((stat & LE_C0_TINT) == 0);
+ ler1->ler1_rdp = LE_C0_TINT;
+ if (ler1->ler1_rdp & LE_C0_ERR) {
+ if ((ler1->ler1_rdp & (LE_C0_BABL|LE_C0_CERR|LE_C0_MISS|LE_C0_MERR)) !=
+ LE_C0_CERR)
+ printf("le_put: xmit error, buf %d\n", le_softc.next_tmd);
+ le_error("le_put(xmit error)", ler1);
+ }
+ le_softc.next_tmd = 0;
+/* (le_softc.next_tmd == (LETBUF - 1)) ? 0 : le_softc.next_tmd + 1;*/
+ if (tmd->tmd1_bits & LE_T1_ERR) {
+ printf("le0: transmit error, error = 0x%x\n",
+ tmd->tmd3);
+ return -1;
+ }
+ return len;
+}
+
+int le_get(pkt, len, timeout)
+ u_char *pkt;
+ size_t len;
+ u_long timeout;
+{
+ int cc;
+ int now, then;
+ int stopat = time() + timeout;
+ then = 0;
+
+ cc = 0;
+ while ((now = time()) < stopat && !cc) {
+ cc = le_poll(pkt, len);
+ if (then != now) {
+#ifdef LE_DEBUG
+ printf("%d \r", stopat - now);
+#endif
+ then = now;
+ }
+ if (cc && (pkt[0] != myea[0] || pkt[1] != myea[1] ||
+ pkt[2] != myea[2] || pkt[3] != myea[3] ||
+ pkt[4] != myea[4] || pkt[5] != myea[5])) {
+ cc = 0; /* ignore broadcast / multicast */
+#ifdef LE_DEBUG
+ printf("reject (%d sec left)\n", stopat - now);
+#endif
+ }
+ }
+#ifdef LE_DEBUG
+ printf("\n");
+#endif
+ return cc;
+}
+
+void le_init()
+{
+ caddr_t addr;
+ int *ea = (int *) LANCE_ADDR;
+ u_long *eram = (u_long *) ERAM_ADDR;
+ u_long e = *ea;
+ if (( e & 0x2fffff00 ) == 0x2fffff00) {
+ printf("ERROR: ethernet address not set! Use LSAD.\n");
+ callrom();
+ }
+ myea[0] = 0x08;
+ myea[1] = 0x00;
+ myea[2] = 0x3e;
+ e = e >> 8;
+ myea[5] = e & 0xff;
+ e = e >> 8;
+ myea[4] = e & 0xff;
+ e = e >> 8;
+ myea[3] = e;
+ printf("le0: ethernet address: %x:%x:%x:%x:%x:%x\n",
+ myea[0], myea[1], myea[2], myea[3], myea[4], myea[5]);
+ bzero(&le_softc, sizeof(le_softc));
+ le_softc.sc_r1 = (struct lereg1 *) LANCE_REG_ADDR;
+ le_softc.sc_r2 = (struct lereg2 *)(*eram - (1024*1024));
+ le_reset(myea);
+}
+
+void le_end()
+{
+ struct lereg1 *ler1 = le_softc.sc_r1;
+
+ ler1->ler1_rap = LE_CSR0;
+ ler1->ler1_rdp = LE_C0_STOP;
+}
diff --git a/sys/arch/mvme68k/stand/sboot/libc_sa.c b/sys/arch/mvme68k/stand/sboot/libc_sa.c
new file mode 100644
index 00000000000..5a178ad2930
--- /dev/null
+++ b/sys/arch/mvme68k/stand/sboot/libc_sa.c
@@ -0,0 +1,348 @@
+/* $NetBSD: libc_sa.c,v 1.1.1.1 1995/07/25 23:12:33 chuck Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "sboot.h"
+
+/*
+ * sizeof(word) MUST BE A POWER OF TWO
+ * SO THAT wmask BELOW IS ALL ONES
+ */
+typedef int word; /* "word" used for optimal copy speed */
+
+#define wsize sizeof(word)
+#define wmask (wsize - 1)
+
+/*
+ * Copy a block of memory, handling overlap.
+ * This is the routine that actually implements
+ * (the portable versions of) bcopy, memcpy, and memmove.
+ */
+void
+bcopy(src0, dst0, length)
+ void *dst0;
+ const void *src0;
+ register size_t length;
+{
+ register char *dst = dst0;
+ register const char *src = src0;
+ register size_t t;
+
+ if (length == 0 || dst == src) /* nothing to do */
+ goto done;
+
+ /*
+ * Macros: loop-t-times; and loop-t-times, t>0
+ */
+#define TLOOP(s) if (t) TLOOP1(s)
+#define TLOOP1(s) do { s; } while (--t)
+
+ if ((unsigned long)dst < (unsigned long)src) {
+ /*
+ * Copy forward.
+ */
+ t = (long)src; /* only need low bits */
+ if ((t | (long)dst) & wmask) {
+ /*
+ * Try to align operands. This cannot be done
+ * unless the low bits match.
+ */
+ if ((t ^ (long)dst) & wmask || length < wsize)
+ t = length;
+ else
+ t = wsize - (t & wmask);
+ length -= t;
+ TLOOP1(*dst++ = *src++);
+ }
+ /*
+ * Copy whole words, then mop up any trailing bytes.
+ */
+ t = length / wsize;
+ TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
+ t = length & wmask;
+ TLOOP(*dst++ = *src++);
+ } else {
+ /*
+ * Copy backwards. Otherwise essentially the same.
+ * Alignment works as before, except that it takes
+ * (t&wmask) bytes to align, not wsize-(t&wmask).
+ */
+ src += length;
+ dst += length;
+ t = (long)src;
+ if ((t | (long)dst) & wmask) {
+ if ((t ^ (long)dst) & wmask || length <= wsize)
+ t = length;
+ else
+ t &= wmask;
+ length -= t;
+ TLOOP1(*--dst = *--src);
+ }
+ t = length / wsize;
+ TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
+ t = length & wmask;
+ TLOOP(*--dst = *--src);
+ }
+done:
+ return;
+}
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+void *
+bzero(dst, n)
+ void *dst;
+ register size_t n;
+{
+
+ if (n != 0) {
+ register char *d = dst;
+
+ do
+ *d++ = 0;
+ while (--n != 0);
+ }
+ return (dst);
+}
+/* $NetBSD: libc_sa.c,v 1.1.1.1 1995/07/25 23:12:33 chuck Exp $ */
+
+/*-
+ * Copyright (c) 1991 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.
+ *
+ * @(#)printf.c 5.6 (Berkeley) 5/25/91
+ */
+
+/*
+ * Scaled down version of printf(3).
+ *
+ * One additional format:
+ *
+ * The format %b is supported to decode error registers.
+ * Its usage is:
+ *
+ * printf("reg=%b\n", regval, "<base><arg>*");
+ *
+ * where <base> is the output base expressed as a control character, e.g.
+ * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
+ * the first of which gives the bit number to be inspected (origin 1), and
+ * the next characters (up to a control character, i.e. a character <= 32),
+ * give the name of the register. Thus:
+ *
+ * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
+ *
+ * would produce output:
+ *
+ * reg=3<BITTWO,BITONE>
+ */
+
+/*
+ * Note that stdarg.h and the ANSI style va_start macro is used for both
+ * ANSI and traditional C compilers.
+ */
+#define _KERNEL
+#include <machine/stdarg.h>
+#undef _KERNEL
+
+static void
+kprintn(ul, base)
+ unsigned long ul;
+ int base;
+{
+ /* hold a long in base 8 */
+ char *p, buf[(sizeof(long) * 8 / 3) + 1];
+
+ p = buf;
+ do {
+ *p++ = "0123456789abcdef"[ul % base];
+ } while (ul /= base);
+ do {
+ putchar(*--p);
+ } while (p > buf);
+}
+
+void
+#if __STDC__
+printf(const char *fmt, ...)
+#else
+printf(fmt /* , va_alist */)
+ char *fmt;
+#endif
+{
+ register char *p;
+ register int ch, n;
+ unsigned long ul;
+ int lflag, set;
+ va_list ap;
+
+ va_start(ap, fmt);
+ for (;;) {
+ while ((ch = *fmt++) != '%') {
+ if (ch == '\0')
+ return;
+ putchar(ch);
+ }
+ lflag = 0;
+reswitch: switch (ch = *fmt++) {
+ case 'l':
+ lflag = 1;
+ goto reswitch;
+ case 'b':
+ ul = va_arg(ap, int);
+ p = va_arg(ap, char *);
+ kprintn(ul, *p++);
+
+ if (!ul)
+ break;
+
+ for (set = 0; n = *p++;) {
+ if (ul & (1 << (n - 1))) {
+ putchar(set ? ',' : '<');
+ for (; (n = *p) > ' '; ++p)
+ putchar(n);
+ set = 1;
+ } else
+ for (; *p > ' '; ++p);
+ }
+ if (set)
+ putchar('>');
+ break;
+ case 'c':
+ ch = va_arg(ap, int);
+ putchar(ch & 0x7f);
+ break;
+ case 's':
+ p = va_arg(ap, char *);
+ while (ch = *p++)
+ putchar(ch);
+ break;
+ case 'd':
+ ul = lflag ?
+ va_arg(ap, long) : va_arg(ap, int);
+ if ((long)ul < 0) {
+ putchar('-');
+ ul = -(long)ul;
+ }
+ kprintn(ul, 10);
+ break;
+ case 'o':
+ ul = lflag ?
+ va_arg(ap, u_long) : va_arg(ap, u_int);
+ kprintn(ul, 8);
+ break;
+ case 'u':
+ ul = lflag ?
+ va_arg(ap, u_long) : va_arg(ap, u_int);
+ kprintn(ul, 10);
+ break;
+ case 'x':
+ ul = lflag ?
+ va_arg(ap, u_long) : va_arg(ap, u_int);
+ kprintn(ul, 16);
+ break;
+ default:
+ putchar('%');
+ if (lflag)
+ putchar('l');
+ putchar(ch);
+ }
+ }
+ va_end(ap);
+}
+
diff --git a/sys/arch/mvme68k/stand/sboot/oc_cksum.s b/sys/arch/mvme68k/stand/sboot/oc_cksum.s
new file mode 100644
index 00000000000..3718a0c4868
--- /dev/null
+++ b/sys/arch/mvme68k/stand/sboot/oc_cksum.s
@@ -0,0 +1,187 @@
+| $NetBSD: oc_cksum.s,v 1.1.1.1 1995/07/25 23:12:31 chuck Exp $
+
+| Copyright (c) 1988 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.
+|
+| @(#)oc_cksum.s 7.2 (Berkeley) 11/3/90
+|
+|
+| oc_cksum: ones complement 16 bit checksum for MC68020.
+|
+| oc_cksum (buffer, count, strtval)
+|
+| Do a 16 bit one's complement sum of 'count' bytes from 'buffer'.
+| 'strtval' is the starting value of the sum (usually zero).
+|
+| It simplifies life in in_cksum if strtval can be >= 2^16.
+| This routine will work as long as strtval is < 2^31.
+|
+| Performance
+| -----------
+| This routine is intended for MC 68020s but should also work
+| for 68030s. It (deliberately) doesn't worry about the alignment
+| of the buffer so will only work on a 68010 if the buffer is
+| aligned on an even address. (Also, a routine written to use
+| 68010 "loop mode" would almost certainly be faster than this
+| code on a 68010).
+|
+| We don't worry about alignment because this routine is frequently
+| called with small counts: 20 bytes for IP header checksums and 40
+| bytes for TCP ack checksums. For these small counts, testing for
+| bad alignment adds ~10% to the per-call cost. Since, by the nature
+| of the kernel's allocator, the data we're called with is almost
+| always longword aligned, there is no benefit to this added cost
+| and we're better off letting the loop take a big performance hit
+| in the rare cases where we're handed an unaligned buffer.
+|
+| Loop unrolling constants of 2, 4, 8, 16, 32 and 64 times were
+| tested on random data on four different types of processors (see
+| list below -- 64 was the largest unrolling because anything more
+| overflows the 68020 Icache). On all the processors, the
+| throughput asymptote was located between 8 and 16 (closer to 8).
+| However, 16 was substantially better than 8 for small counts.
+| (It's clear why this happens for a count of 40: unroll-8 pays a
+| loop branch cost and unroll-16 doesn't. But the tests also showed
+| that 16 was better than 8 for a count of 20. It's not obvious to
+| me why.) So, since 16 was good for both large and small counts,
+| the loop below is unrolled 16 times.
+|
+| The processors tested and their average time to checksum 1024 bytes
+| of random data were:
+| Sun 3/50 (15MHz) 190 us/KB
+| Sun 3/180 (16.6MHz) 175 us/KB
+| Sun 3/60 (20MHz) 134 us/KB
+| Sun 3/280 (25MHz) 95 us/KB
+|
+| The cost of calling this routine was typically 10% of the per-
+| kilobyte cost. E.g., checksumming zero bytes on a 3/60 cost 9us
+| and each additional byte cost 125ns. With the high fixed cost,
+| it would clearly be a gain to "inline" this routine -- the
+| subroutine call adds 400% overhead to an IP header checksum.
+| However, in absolute terms, inlining would only gain 10us per
+| packet -- a 1% effect for a 1ms ethernet packet. This is not
+| enough gain to be worth the effort.
+
+#include <m68k/asm.h>
+
+ .text
+
+ .text; .even; .globl _oc_cksum; _oc_cksum:
+ movl sp@(4),a0 | get buffer ptr
+ movl sp@(8),d1 | get byte count
+ movl sp@(12),d0 | get starting value
+ movl d2,sp@- | free a reg
+
+ | test for possible 1, 2 or 3 bytes of excess at end
+ | of buffer. The usual case is no excess (the usual
+ | case is header checksums) so we give that the faster
+ | 'not taken' leg of the compare. (We do the excess
+ | first because we're about the trash the low order
+ | bits of the count in d1.)
+
+ btst #0,d1
+ jne L5 | if one or three bytes excess
+ btst #1,d1
+ jne L7 | if two bytes excess
+L1:
+ movl d1,d2
+ lsrl #6,d1 | make cnt into # of 64 byte chunks
+ andl #0x3c,d2 | then find fractions of a chunk
+ negl d2
+ andb #0xf,cc | clear X
+ jmp pc@(L3-.-2:b,d2)
+L2:
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+ movl a0@+,d2
+ addxl d2,d0
+L3:
+ dbra d1,L2 | (NB- dbra doesn't affect X)
+
+ movl d0,d1 | fold 32 bit sum to 16 bits
+ swap d1 | (NB- swap doesn't affect X)
+ addxw d1,d0
+ jcc L4
+ addw #1,d0
+L4:
+ andl #0xffff,d0
+ movl sp@+,d2
+ rts
+
+L5: | deal with 1 or 3 excess bytes at the end of the buffer.
+ btst #1,d1
+ jeq L6 | if 1 excess
+
+ | 3 bytes excess
+ clrl d2
+ movw a0@(-3,d1:l),d2 | add in last full word then drop
+ addl d2,d0 | through to pick up last byte
+
+L6: | 1 byte excess
+ clrl d2
+ movb a0@(-1,d1:l),d2
+ lsll #8,d2
+ addl d2,d0
+ jra L1
+
+L7: | 2 bytes excess
+ clrl d2
+ movw a0@(-2,d1:l),d2
+ addl d2,d0
+ jra L1
diff --git a/sys/arch/mvme68k/stand/sboot/sboot.c b/sys/arch/mvme68k/stand/sboot/sboot.c
new file mode 100644
index 00000000000..3a8d1bf8a34
--- /dev/null
+++ b/sys/arch/mvme68k/stand/sboot/sboot.c
@@ -0,0 +1,150 @@
+/*
+ *
+ * Copyright (c) 1995 Charles D. Cranor and Seth Widoff
+ * 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 D. Cranor
+ * and Seth Widoff.
+ * 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.
+ */
+/*
+ * main driver, plus machdep stuff
+ */
+
+#include "sboot.h"
+
+void sboot()
+
+{
+ char * mesg;
+ char buf[128];
+ buf[0] = '0';
+ consinit();
+ printf("\nsboot: serial line bootstrap program (&end = %x)\n\n", &end);
+ if (reboot) { /* global flag from AAstart.s */
+ reboot = 0;
+ printf("[rebooting...]\n");
+ do_cmd("b");
+ }
+ while (1) {
+ printf(">>> ");
+ ngets(buf, sizeof(buf));
+ do_cmd(buf);
+ }
+ /* not reached */
+}
+
+/*
+ * exit to rom
+ */
+
+void callrom ()
+{
+ asm("trap #15; .word 0x0063");
+}
+
+/*
+ * do_cmd: do a command
+ */
+
+void do_cmd(buf)
+
+char *buf;
+
+{
+ switch (*buf) {
+ case '\0':
+ return;
+ case 'a':
+ if ( rev_arp() ) {
+ printf ("My ip address is: %d.%d.%d.%d\n", myip[0],
+ myip[1], myip[2], myip[3]);
+ printf ("Server ip address is: %d.%d.%d.%d\n", servip[0],
+ servip[1], servip[2], servip[3]);
+ } else {
+ printf ("Failed.\n");
+ }
+ return;
+ case 'e':
+ printf("exiting to ROM\n");
+ callrom();
+ return;
+ case 'f':
+ if (do_get_file() == 1) {
+ printf("Download Failed\n");
+ } else {
+ printf("Download was a success!\n");
+ }
+ return;
+ case 'b':
+ le_init();
+ if ( rev_arp() ) {
+ printf ("My ip address is: %d.%d.%d.%d\n", myip[0],
+ myip[1], myip[2], myip[3]);
+ printf ("Server ip address is: %d.%d.%d.%d\n", servip[0],
+ servip[1], servip[2], servip[3]);
+ } else {
+ printf ("REVARP: Failed.\n");
+ return;
+ }
+ if (do_get_file() == 1) {
+ printf("Download Failed\n");
+ return;
+ } else {
+ printf("Download was a success!\n");
+ }
+ go(buf);
+ return;
+ case 'h':
+ case '?':
+ printf("valid commands\n");
+ printf("a - send a RARP\n");
+ printf("b - boot the system\n");
+ printf("e - exit to ROM\n");
+ printf("f - ftp the boot file\n");
+ printf("g - execute the boot file\n");
+ printf("h - help\n");
+ printf("i - init LANCE enet chip\n");
+ return;
+ case 'i':
+ le_init();
+ return;
+ case 'g':
+ go(buf);
+ return;
+ default:
+ printf("sboot: %s: Unknown command\n", buf);
+ }
+}
+
+go(buf)
+char *buf;
+
+{
+ void (*entry)() = (void (*)) LOAD_ADDR ;
+ printf("Start @ 0x%x ... \n", entry);
+ (*entry)(buf);
+}
+
diff --git a/sys/arch/mvme68k/stand/sboot/sboot.h b/sys/arch/mvme68k/stand/sboot/sboot.h
new file mode 100644
index 00000000000..01085b17b90
--- /dev/null
+++ b/sys/arch/mvme68k/stand/sboot/sboot.h
@@ -0,0 +1,96 @@
+/*
+ *
+ * Copyright (c) 1995 Charles D. Cranor and Seth Widoff
+ * 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 D. Cranor
+ * and Seth Widoff.
+ * 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.
+ */
+
+/*
+ * sboot.h: stuff for MVME147's serial line boot
+ */
+
+typedef unsigned short u_short;
+typedef unsigned long u_long;
+typedef unsigned char u_char;
+typedef unsigned int u_int;
+typedef u_long size_t;
+typedef char *caddr_t;
+extern caddr_t end;
+
+#define NULL ((char *)0)
+
+void bcopy(const void *, void *, size_t); /* libc_sa */
+void *memset(void *, int, size_t); /* libc_sa */
+void printf(const char *, ...); /* libc_sa */
+
+/* console */
+void puts(char *);
+void putchar(char);
+char cngetc();
+void ngets(char *, int);
+
+/* sboot */
+void callrom();
+void do_cmd(char *);
+
+/* le */
+#define LANCE_ADDR 0xfffe0778
+#define ERAM_ADDR 0xfffe0774
+#define LANCE_REG_ADDR 0xfffe1800
+void le_end(void);
+void le_init(void);
+int le_get(u_char *, size_t, u_long);
+int le_put(u_char *, size_t);
+
+/* etherfun */
+#define READ 0
+#define ACKN 1
+void do_rev_arp();
+int get_rev_arp();
+int rev_arp();
+void do_send_tftp( int );
+int do_get_file();
+void tftp_file(char *, u_long);
+
+/* clock */
+u_long time(void);
+
+/* checksum */
+u_long oc_cksum (void *, u_long, u_long);
+
+#define CONS_ZS_ADDR (0xfffe3002)
+#define CLOCK_ADDR (0xfffe07f8)
+#define LOAD_ADDR 0x8000
+
+unsigned char myea[6]; /* my ether addr */
+unsigned char myip[4];
+unsigned char servip[4];
+unsigned char servea[6];
+u_short myport;
+u_short servport;
+unsigned char reboot;
diff --git a/sys/arch/mvme68k/stand/sboot/start.s b/sys/arch/mvme68k/stand/sboot/start.s
new file mode 100644
index 00000000000..d878f94ea23
--- /dev/null
+++ b/sys/arch/mvme68k/stand/sboot/start.s
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright (c) 1995 Charles D. Cranor
+ * 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 D. Cranor.
+ * 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.
+ */
+/*
+ * start: at address 0x4000, load at 0xa000 (so put stack at 0x9ff0)
+ * note this file is named "AAstart" so that it gets linked FIRST
+ */
+
+.text
+.globl start
+start:
+ movb #0,_reboot
+ jra Ldoit
+restart:
+ movb #1,_reboot | fall through
+
+Ldoit:
+ movl #0x00006ff0,sp
+ jsr _sboot
+