Module Name:    src
Committed By:   tsutsui
Date:           Fri Oct 12 20:15:53 UTC 2012

Modified Files:
        src/sys/arch/x68k/stand: Makefile
        src/sys/arch/x68k/stand/boot: conf.c
        src/sys/arch/x68k/stand/libsa: Makefile Makefile.inc devopen.c
            libx68k.h
Added Files:
        src/sys/arch/x68k/stand/boot: dp8390.c dp8390.h if_ne.c ne.c ne.h
        src/sys/arch/x68k/stand/libsa: clock.c
        src/sys/arch/x68k/stand/netboot: Makefile boot.c conf.c version

Log Message:
First cut at x68k network bootloader via NE2000 on Neptune-X and Nereid.
Written by isaki@ back in 2003 based on x86's NE2000 netboot, and
misc debug and improvements by tsutsui@ and Y.Sugahara.

Tested on XM6i (emulating Nereid Ethernet) and X68030 + Neptune-X by me,
also on X68030 + Nereid and X68000 PRO-II + Xellent30 + Nereid by isaki@.

Note:
- X680x0 IPLROM doesn't support bootstrap from Neptune-X or Nereid,
  so this network bootloader needs to be loaded from floppy or harddisk.
- Currently netboot support is not merged into the secondary Multi-boot
  (/usr/mdec/boot) due to size restriction.
- Primary loaders assumes that the secondary bootloader name is /boot,
  so /usr/mdec/netboot needs to be installed as /boot into the target
  bootstrap device.


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/x68k/stand/Makefile
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/x68k/stand/boot/conf.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/x68k/stand/boot/dp8390.c \
    src/sys/arch/x68k/stand/boot/dp8390.h \
    src/sys/arch/x68k/stand/boot/if_ne.c src/sys/arch/x68k/stand/boot/ne.c \
    src/sys/arch/x68k/stand/boot/ne.h
cvs rdiff -u -r1.28 -r1.29 src/sys/arch/x68k/stand/libsa/Makefile
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/x68k/stand/libsa/Makefile.inc
cvs rdiff -u -r0 -r1.1 src/sys/arch/x68k/stand/libsa/clock.c
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/x68k/stand/libsa/devopen.c \
    src/sys/arch/x68k/stand/libsa/libx68k.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/x68k/stand/netboot/Makefile \
    src/sys/arch/x68k/stand/netboot/boot.c \
    src/sys/arch/x68k/stand/netboot/conf.c \
    src/sys/arch/x68k/stand/netboot/version

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x68k/stand/Makefile
diff -u src/sys/arch/x68k/stand/Makefile:1.12 src/sys/arch/x68k/stand/Makefile:1.13
--- src/sys/arch/x68k/stand/Makefile:1.12	Fri Oct 12 17:06:48 2012
+++ src/sys/arch/x68k/stand/Makefile	Fri Oct 12 20:15:52 2012
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.12 2012/10/12 17:06:48 tsutsui Exp $
+#	$NetBSD: Makefile,v 1.13 2012/10/12 20:15:52 tsutsui Exp $
 
 # host tools
 SUBDIR= newdisk installboot
@@ -9,7 +9,7 @@ SUBDIR+= libdos libiocs libsa .WAIT
 # standalone bootloaders
 SUBDIR+= mboot
 SUBDIR+= boot_ufs boot_ustar xxboot
-SUBDIR+= boot
+SUBDIR+= boot netboot
 
 # Human68k utility
 SUBDIR+= aout2hux .WAIT loadbsd

Index: src/sys/arch/x68k/stand/boot/conf.c
diff -u src/sys/arch/x68k/stand/boot/conf.c:1.9 src/sys/arch/x68k/stand/boot/conf.c:1.10
--- src/sys/arch/x68k/stand/boot/conf.c:1.9	Tue Mar 20 12:38:33 2012
+++ src/sys/arch/x68k/stand/boot/conf.c	Fri Oct 12 20:15:52 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: conf.c,v 1.9 2012/03/20 12:38:33 minoura Exp $	*/
+/*	$NetBSD: conf.c,v 1.10 2012/10/12 20:15:52 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 2001 Minoura Makoto
@@ -45,10 +45,10 @@ struct devsw devsw[] = {
 int ndevs = sizeof(devsw) / sizeof(devsw[0]);
 
 const struct devspec devspec[] = {
-	{ "sd", 0, 7 },
-	{ "cd", 1, 7 },
-	{ "fd", 2, 3 },
-	{ 0, 0, 0 }
+	{ "sd", 0, 7, 0 },
+	{ "cd", 1, 7, 0 },
+	{ "fd", 2, 3, 0 },
+	{ NULL, 0, 0, 0 }
 };
 
 struct fs_ops file_system[] = {

Index: src/sys/arch/x68k/stand/libsa/Makefile
diff -u src/sys/arch/x68k/stand/libsa/Makefile:1.28 src/sys/arch/x68k/stand/libsa/Makefile:1.29
--- src/sys/arch/x68k/stand/libsa/Makefile:1.28	Sun Dec 25 06:09:09 2011
+++ src/sys/arch/x68k/stand/libsa/Makefile	Fri Oct 12 20:15:52 2012
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.28 2011/12/25 06:09:09 tsutsui Exp $
+#	$NetBSD: Makefile,v 1.29 2012/10/12 20:15:52 tsutsui Exp $
 
 S=		${.CURDIR}/../../../..
 
@@ -11,6 +11,7 @@ CPPFLAGS+=	-DHEAP_VARIABLE
 CPPFLAGS+=	-DHAVE_CHANGEDISK_HOOK
 CPPFLAGS+=	-DUSTAR_SECT_PER_CYL=16
 CPPFLAGS+=	-DLIBSA_ENABLE_LS_OP
+CPPFLAGS+=	-DSUPPORT_BOOTP -DSUPPORT_DHCP
 #CPPFLAGS+=	-DDEBUG
 
 .PATH:	${LIBSADIR} ${LIBKERNDIR} ${LIBZDIR} ${LIBZDIST}

Index: src/sys/arch/x68k/stand/libsa/Makefile.inc
diff -u src/sys/arch/x68k/stand/libsa/Makefile.inc:1.1 src/sys/arch/x68k/stand/libsa/Makefile.inc:1.2
--- src/sys/arch/x68k/stand/libsa/Makefile.inc:1.1	Tue Apr 12 14:07:35 2011
+++ src/sys/arch/x68k/stand/libsa/Makefile.inc	Fri Oct 12 20:15:52 2012
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.inc,v 1.1 2011/04/12 14:07:35 tsutsui Exp $
+#	$NetBSD: Makefile.inc,v 1.2 2012/10/12 20:15:52 tsutsui Exp $
 
 # MD libsa files
 
@@ -8,4 +8,6 @@
 SRCS+=		consio.c devopen.c parseutils.c sdcd.c fd.c fdsub.S chdsk.c
 SRCS+=		putimage.S
 
-#SRCS+=		dev_net.c
+# network support
+SRCS+=		clock.c
+SRCS+=		dev_net.c

Index: src/sys/arch/x68k/stand/libsa/devopen.c
diff -u src/sys/arch/x68k/stand/libsa/devopen.c:1.5 src/sys/arch/x68k/stand/libsa/devopen.c:1.6
--- src/sys/arch/x68k/stand/libsa/devopen.c:1.5	Mon Apr 11 14:00:02 2011
+++ src/sys/arch/x68k/stand/libsa/devopen.c	Fri Oct 12 20:15:52 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: devopen.c,v 1.5 2011/04/11 14:00:02 tsutsui Exp $	*/
+/*	$NetBSD: devopen.c,v 1.6 2012/10/12 20:15:52 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 2001 Minoura Makoto
@@ -60,14 +60,19 @@ devparse(const char *fname, int *dev, in
 	s += strlen(devspec[i].ds_name);
 	*dev = devspec[i].ds_dev;
 
-	*unit = *s++ - '0';
-	if (*unit < 0 || *unit > devspec[i].ds_maxunit)
-		/* bad unit */
-		return ENODEV;
-	*part = *s++ - 'a';
-	if (*part < 0 || *part > MAXPARTITIONS)
-		/* bad partition */
-		return ENODEV;
+	if (devspec[i].ds_net) {
+		*unit = 0;
+		*part = 0;
+	} else {
+		*unit = *s++ - '0';
+		if (*unit < 0 || *unit > devspec[i].ds_maxunit)
+			/* bad unit */
+			return ENODEV;
+		*part = *s++ - 'a';
+		if (*part < 0 || *part > MAXPARTITIONS)
+			/* bad partition */
+			return ENODEV;
+	}
 
 	if (*s++ != ':')
 		return ENODEV;
Index: src/sys/arch/x68k/stand/libsa/libx68k.h
diff -u src/sys/arch/x68k/stand/libsa/libx68k.h:1.5 src/sys/arch/x68k/stand/libsa/libx68k.h:1.6
--- src/sys/arch/x68k/stand/libsa/libx68k.h:1.5	Sun Nov 18 04:59:51 2007
+++ src/sys/arch/x68k/stand/libsa/libx68k.h	Fri Oct 12 20:15:52 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: libx68k.h,v 1.5 2007/11/18 04:59:51 isaki Exp $	*/
+/*	$NetBSD: libx68k.h,v 1.6 2012/10/12 20:15:52 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 2001 Minoura Makoto
@@ -34,6 +34,7 @@ struct devspec {
 	const char *ds_name;
 	int ds_dev;
 	int ds_maxunit;
+	int ds_net;
 };
 
 /* consio.c */
@@ -68,3 +69,7 @@ extern int devopen_open_dir;
 
 /* chdsk.c */
 int changedisk_hook(struct open_file *);
+
+/* clock.c */
+void delay(int);
+extern int rtc_offset;

Added files:

Index: src/sys/arch/x68k/stand/boot/dp8390.c
diff -u /dev/null src/sys/arch/x68k/stand/boot/dp8390.c:1.1
--- /dev/null	Fri Oct 12 20:15:53 2012
+++ src/sys/arch/x68k/stand/boot/dp8390.c	Fri Oct 12 20:15:52 2012
@@ -0,0 +1,300 @@
+/*	$NetBSD: dp8390.c,v 1.1 2012/10/12 20:15:52 tsutsui Exp $	*/
+/*	Id: dp8390.c,v 1.14 2011/10/05 13:16:20 isaki Exp 	*/
+
+/*
+ * This file is derived from sys/arch/i386/stand/lib/netif/dp8390.c
+ * NetBSD: dp8390.c,v 1.6 2008/12/14 18:46:33 christos Exp
+ */
+
+/*
+ * Polling driver for National Semiconductor DS8390/WD83C690 based
+ * ethernet adapters.
+ *
+ * Copyright (c) 1998 Matthias Drochner.  All rights reserved.
+ *
+ * Copyright (c) 1994, 1995 Charles M. Hannum.  All rights reserved.
+ *
+ * Copyright (C) 1993, David Greenman.  This software may be used, modified,
+ * copied, distributed, and sold, in both source and binary form provided that
+ * the above copyright and these terms are retained.  Under no circumstances is
+ * the author responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with its use.
+ */
+
+
+#include <sys/types.h>
+
+#include <lib/libsa/stand.h>
+#include <libx68k.h>
+
+#include <dev/ic/dp8390reg.h>
+#include "dp8390.h"
+#include "ne.h"
+
+int dp8390_iobase, dp8390_membase, dp8390_memsize;
+#if defined(SUPPORT_WD80X3) && defined(SUPPORT_SMC_ULTRA)
+int dp8390_is790;
+#endif
+uint8_t dp8390_cr_proto;
+uint8_t dp8390_dcr_reg;
+
+#define WE_IOBASE dp8390_iobase
+
+static u_short rec_page_start;
+static u_short rec_page_stop;
+static u_short next_packet;
+
+extern u_char eth_myaddr[6];
+
+static void dp8390_read(int, char *, u_short);
+
+#define NIC_GET(reg) inb(WE_IOBASE + (reg) * 2)
+#define NIC_PUT(reg, val) outb(WE_IOBASE + (reg) * 2, val)
+
+static void
+dp8390_init(void)
+{
+	int i;
+
+	/*
+	 * Initialize the NIC in the exact order outlined in the NS manual.
+	 * This init procedure is "mandatory"...don't change what or when
+	 * things happen.
+	 */
+
+	/* Set interface for page 0, remote DMA complete, stopped. */
+	NIC_PUT(ED_P0_CR, dp8390_cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
+
+	if ((dp8390_dcr_reg & ED_DCR_LS)) {
+		NIC_PUT(ED_P0_DCR, dp8390_dcr_reg);
+	} else {
+		/*
+		 * Set FIFO threshold to 8, No auto-init Remote DMA, byte
+		 * order=80x86, byte-wide DMA xfers,
+		 */
+		NIC_PUT(ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
+	}
+
+	/* Clear remote byte count registers. */
+	NIC_PUT(ED_P0_RBCR0, 0);
+	NIC_PUT(ED_P0_RBCR1, 0);
+
+	/* Tell RCR to do nothing for now. */
+	NIC_PUT(ED_P0_RCR, ED_RCR_MON);
+
+	/* Place NIC in internal loopback mode. */
+	NIC_PUT(ED_P0_TCR, ED_TCR_LB0);
+
+	/* Set lower bits of byte addressable framing to 0. */
+	if (dp8390_is790)
+		NIC_PUT(0x09, 0);
+
+	/* Initialize receive buffer ring. */
+	NIC_PUT(ED_P0_BNRY, rec_page_start);
+	NIC_PUT(ED_P0_PSTART, rec_page_start);
+	NIC_PUT(ED_P0_PSTOP, rec_page_stop);
+
+	/*
+	 * Clear all interrupts.  A '1' in each bit position clears the
+	 * corresponding flag.
+	 */
+	NIC_PUT(ED_P0_ISR, 0xff);
+
+	/*
+	 * Disable all interrupts.
+	 */
+	NIC_PUT(ED_P0_IMR, 0);
+
+	/* Program command register for page 1. */
+	NIC_PUT(ED_P0_CR, dp8390_cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
+
+	/* Copy out our station address. */
+	for (i = 0; i < 6; i++)
+		NIC_PUT(ED_P1_PAR0 + i, eth_myaddr[i]);
+
+	/*
+	 * Set current page pointer to one page after the boundary pointer, as
+	 * recommended in the National manual.
+	 */
+	next_packet = rec_page_start + 1;
+	NIC_PUT(ED_P1_CURR, next_packet);
+
+	/* Program command register for page 0. */
+	NIC_PUT(ED_P1_CR, dp8390_cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
+
+	/* directed and broadcast */
+	NIC_PUT(ED_P0_RCR, ED_RCR_AB);
+
+	/* Take interface out of loopback. */
+	NIC_PUT(ED_P0_TCR, 0);
+
+	/* Fire up the interface. */
+	NIC_PUT(ED_P0_CR, dp8390_cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
+}
+
+int
+dp8390_config(void)
+{
+
+	rec_page_start = TX_PAGE_START + ED_TXBUF_SIZE;
+	rec_page_stop = TX_PAGE_START + (dp8390_memsize >> ED_PAGE_SHIFT);
+
+	dp8390_init();
+
+	return 0;
+}
+
+void
+dp8390_stop(void)
+{
+	int n = 5000;
+
+	/* Stop everything on the interface, and select page 0 registers. */
+	NIC_PUT(ED_P0_CR, dp8390_cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
+
+	/*
+	 * Wait for interface to enter stopped state, but limit # of checks to
+	 * 'n' (about 5ms).  It shouldn't even take 5us on modern DS8390's, but
+	 * just in case it's an old one.
+	 */
+	while (((NIC_GET(ED_P0_ISR) & ED_ISR_RST) == 0) && --n)
+		continue;
+}
+
+int
+EtherSend(char *pkt, int len)
+{
+	ne2000_writemem(pkt, dp8390_membase, len);
+
+	/* Set TX buffer start page. */
+	NIC_PUT(ED_P0_TPSR, TX_PAGE_START);
+
+	/* Set TX length. */
+	NIC_PUT(ED_P0_TBCR0, len < 60 ? 60 : len);
+	NIC_PUT(ED_P0_TBCR1, len >> 8);
+
+	/* Set page 0, remote DMA complete, transmit packet, and *start*. */
+	NIC_PUT(ED_P0_CR, dp8390_cr_proto | ED_CR_PAGE_0 | ED_CR_TXP | ED_CR_STA);
+
+	return len;
+}
+
+static void
+dp8390_read(int buf, char *dest, u_short len)
+{
+	u_short tmp_amount;
+
+	/* Does copy wrap to lower addr in ring buffer? */
+	if (buf + len > dp8390_membase + dp8390_memsize) {
+		tmp_amount = dp8390_membase + dp8390_memsize - buf;
+
+		/* Copy amount up to end of NIC memory. */
+		ne2000_readmem(buf, dest, tmp_amount);
+
+		len -= tmp_amount;
+		buf = RX_BUFBASE + (rec_page_start << ED_PAGE_SHIFT);
+		dest += tmp_amount;
+	}
+	ne2000_readmem(buf, dest, len);
+}
+
+int
+EtherReceive(char *pkt, int maxlen)
+{
+	struct dp8390_ring packet_hdr;
+	int packet_ptr;
+	u_short len;
+	u_char boundary, current;
+#ifdef DP8390_OLDCHIPS
+	u_char nlen;
+#endif
+
+	if (!(NIC_GET(ED_P0_RSR) & ED_RSR_PRX))
+		return 0; /* XXX error handling */
+
+	/* Set NIC to page 1 registers to get 'current' pointer. */
+	NIC_PUT(ED_P0_CR, dp8390_cr_proto | ED_CR_PAGE_1 | ED_CR_STA);
+
+	/*
+	 * 'sc->next_packet' is the logical beginning of the ring-buffer - i.e.
+	 * it points to where new data has been buffered.  The 'CURR' (current)
+	 * register points to the logical end of the ring-buffer - i.e. it
+	 * points to where additional new data will be added.  We loop here
+	 * until the logical beginning equals the logical end (or in other
+	 * words, until the ring-buffer is empty).
+	 */
+	current = NIC_GET(ED_P1_CURR);
+
+	/* Set NIC to page 0 registers to update boundary register. */
+	NIC_PUT(ED_P1_CR, dp8390_cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
+
+	if (next_packet == current)
+		return 0;
+
+	/* Get pointer to this buffer's header structure. */
+	packet_ptr = RX_BUFBASE + (next_packet << ED_PAGE_SHIFT);
+
+	/*
+	 * The byte count includes a 4 byte header that was added by
+	 * the NIC.
+	 */
+	ne2000_readmem(packet_ptr, (void *)&packet_hdr, 4);
+
+	len = le16toh(packet_hdr.count);
+
+#ifdef DP8390_OLDCHIPS
+	/*
+	 * Try do deal with old, buggy chips that sometimes duplicate
+	 * the low byte of the length into the high byte.  We do this
+	 * by simply ignoring the high byte of the length and always
+	 * recalculating it.
+	 *
+	 * NOTE: sc->next_packet is pointing at the current packet.
+	 */
+	if (packet_hdr.next_packet >= next_packet)
+		nlen = (packet_hdr.next_packet - next_packet);
+	else
+		nlen = ((packet_hdr.next_packet - rec_page_start) +
+			(rec_page_stop - next_packet));
+	--nlen;
+	if ((len & ED_PAGE_MASK) + sizeof(packet_hdr) > ED_PAGE_SIZE)
+		--nlen;
+	len = (len & ED_PAGE_MASK) | (nlen << ED_PAGE_SHIFT);
+#ifdef DIAGNOSTIC
+	if (len != packet_hdr.count) {
+		printf(IFNAME ": length does not match next packet pointer\n");
+		printf(IFNAME ": len %04x nlen %04x start %02x "
+		       "first %02x curr %02x next %02x stop %02x\n",
+		       packet_hdr.count, len,
+		       rec_page_start, next_packet, current,
+		       packet_hdr.next_packet, rec_page_stop);
+	}
+#endif
+#endif
+
+	if (packet_hdr.next_packet < rec_page_start ||
+	    packet_hdr.next_packet >= rec_page_stop)
+		panic(IFNAME ": RAM corrupt");
+
+	len -= sizeof(struct dp8390_ring);
+	if (len <= maxlen) {
+		/* Go get packet. */
+		dp8390_read(packet_ptr + sizeof(struct dp8390_ring),
+			    pkt, len);
+	} else
+		len = 0;
+
+	/* Update next packet pointer. */
+	next_packet = packet_hdr.next_packet;
+
+	/*
+	 * Update NIC boundary pointer - being careful to keep it one
+	 * buffer behind (as recommended by NS databook).
+	 */
+	boundary = next_packet - 1;
+	if (boundary < rec_page_start)
+		boundary = rec_page_stop - 1;
+	NIC_PUT(ED_P0_BNRY, boundary);
+
+	return len;
+}
Index: src/sys/arch/x68k/stand/boot/dp8390.h
diff -u /dev/null src/sys/arch/x68k/stand/boot/dp8390.h:1.1
--- /dev/null	Fri Oct 12 20:15:53 2012
+++ src/sys/arch/x68k/stand/boot/dp8390.h	Fri Oct 12 20:15:52 2012
@@ -0,0 +1,36 @@
+/*	$NetBSD: dp8390.h,v 1.1 2012/10/12 20:15:52 tsutsui Exp $	*/
+/*	Id: dp8390.h,v 1.7 2011/10/05 13:16:20 isaki Exp 	*/
+
+/*
+ * This file is derived from sys/arch/i386/stand/lib/netif/dp8390.h
+ * NetBSD: dp8390.h,v 1.6 2008/12/14 18:46:33 christos Exp
+ */
+
+int dp8390_config(void);
+void dp8390_stop(void);
+
+extern int dp8390_iobase;
+extern int dp8390_membase;
+extern int dp8390_memsize;
+#ifdef SUPPORT_WD80X3
+#ifdef SUPPORT_SMC_ULTRA
+extern int dp8390_is790;
+#else
+#define dp8390_is790 0
+#endif
+#else
+#ifdef SUPPORT_SMC_ULTRA
+#define dp8390_is790 1
+#endif
+#endif
+
+#define dp8390_is790 0
+#define IFNAME "ne"
+#define RX_BUFBASE 0
+#define TX_PAGE_START (dp8390_membase >> ED_PAGE_SHIFT)
+
+extern uint8_t dp8390_cr_proto; /* values always set in CR */
+extern uint8_t dp8390_dcr_reg; /* override DCR if LS is set */
+
+int  EtherSend(char *, int);
+int  EtherReceive(char *, int);
Index: src/sys/arch/x68k/stand/boot/if_ne.c
diff -u /dev/null src/sys/arch/x68k/stand/boot/if_ne.c:1.1
--- /dev/null	Fri Oct 12 20:15:53 2012
+++ src/sys/arch/x68k/stand/boot/if_ne.c	Fri Oct 12 20:15:52 2012
@@ -0,0 +1,156 @@
+/* $NetBSD: if_ne.c,v 1.1 2012/10/12 20:15:52 tsutsui Exp $ */
+/* Id: if_ne.c,v 1.28 2011/10/05 13:17:06 isaki Exp  */
+
+/*
+ * Copyright (c) 2003 Tetsuya Isaki. 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.
+ *
+ * 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/systm.h>
+
+#include <net/if.h>
+#include <net/if_ether.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <lib/libsa/stand.h>
+#include <lib/libsa/net.h>
+#include <lib/libsa/netif.h>
+
+#include "ne.h"
+#include "dp8390.h"
+
+extern int badbaddr(void *);
+
+static int  ne_match(struct netif *, void *);
+static int  ne_probe(struct netif *, void *);
+static void ne_init(struct iodesc *, void *);
+static int  ne_get(struct iodesc *, void *, size_t, saseconds_t);
+static int  ne_put(struct iodesc *, void *, size_t);
+static void ne_end(struct netif *);
+
+uint neaddr_conf[] = {
+	0xece200,	/* Neptune-X at ISA addr 0x300 */
+	0xece300,	/* Nereid #1 */
+	0xeceb00,	/* Nereid #2 */
+};
+uint neaddr;
+
+
+static int
+ne_match(struct netif *nif, void *machdep_hint)
+{
+	int i;
+
+	for (i = 0; i < sizeof(neaddr_conf) / sizeof(neaddr_conf[0]); i++) {
+		if (!badbaddr((void *)neaddr_conf[i])) {
+			neaddr = neaddr_conf[i];
+			return 1;
+		}
+	}
+	printf("ne_match: no match\n");
+	return 0;
+}
+
+static int
+ne_probe(struct netif *nif, void *machdep_hint)
+{
+
+	return 0;
+}
+
+static void
+ne_init(struct iodesc *desc, void *machdep_hint)
+{
+
+#ifdef DEBUG
+	printf("ne_init\n");
+#endif
+	if (EtherInit(desc->myea) == 0) {
+		printf("EtherInit failed?\n");
+		exit(1);
+	}
+
+	printf("ethernet address = %s\n", ether_sprintf(desc->myea));
+}
+
+static int
+ne_get(struct iodesc *desc, void *pkt, size_t maxlen, saseconds_t timeout)
+{
+	int len = 0;
+	saseconds_t t;
+
+	t = getsecs() + timeout;
+	while (getsecs() < t) {
+		len = EtherReceive(pkt, maxlen);
+		if (len)
+			break;
+	}
+
+	return len;
+}
+
+static int
+ne_put(struct iodesc *desc, void *pkt, size_t len)
+{
+#ifdef DEBUG
+ 	struct ether_header *eh;
+ 
+ 	eh = pkt;
+ 	printf("dst:  %s\n", ether_sprintf(eh->ether_dhost));
+ 	printf("src:  %s\n", ether_sprintf(eh->ether_shost));
+ 	printf("type: 0x%x\n", eh->ether_type & 0xffff);
+#endif
+ 
+	return EtherSend(pkt, len);
+}
+
+static void
+ne_end(struct netif *nif)
+{
+
+#ifdef DEBUG
+	printf("ne_end\n");
+#endif
+
+	EtherStop();
+}
+
+
+struct netif_stats ne_stats;
+struct netif_dif ne_ifs[] = {
+	{ 0, 1, &ne_stats, 0, 0, },
+};
+
+struct netif_driver ne_netif_driver = {
+	"ne",
+	ne_match,
+	ne_probe,
+	ne_init,
+	ne_get,
+	ne_put,
+	ne_end,
+	ne_ifs,
+	sizeof(ne_ifs) / sizeof(ne_ifs[0]),
+};
Index: src/sys/arch/x68k/stand/boot/ne.c
diff -u /dev/null src/sys/arch/x68k/stand/boot/ne.c:1.1
--- /dev/null	Fri Oct 12 20:15:53 2012
+++ src/sys/arch/x68k/stand/boot/ne.c	Fri Oct 12 20:15:52 2012
@@ -0,0 +1,272 @@
+/*	$NetBSD: ne.c,v 1.1 2012/10/12 20:15:52 tsutsui Exp $	*/
+/*	Id: ne.c,v 1.22 2011/10/05 13:16:20 isaki Exp 	*/
+
+/*
+ * This file is derived from sys/arch/i386/stand/lib/netif/ne.c
+ * NetBSD: ne.c,v 1.7 2008/12/14 18:46:33 christos Exp
+ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*
+ * Device driver for National Semiconductor DS8390/WD83C690 based ethernet
+ * adapters.
+ *
+ * Copyright (c) 1994, 1995 Charles M. Hannum.  All rights reserved.
+ *
+ * Copyright (C) 1993, David Greenman.  This software may be used, modified,
+ * copied, distributed, and sold, in both source and binary form provided that
+ * the above copyright and these terms are retained.  Under no circumstances is
+ * the author responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with its use.
+ */
+
+/*
+ * this code is mainly obtained from /sys/dev/ic/ne2000.c .
+ */
+
+#include <sys/types.h>
+
+#include <lib/libsa/stand.h>
+#include <libx68k.h>
+
+#include <lib/libkern/libkern.h>
+
+#include <dev/ic/dp8390reg.h>
+#include <dev/ic/ne2000reg.h>
+#include "dp8390.h"
+#include "ne.h"
+
+#define	NE_BASEREG	neaddr
+#define NE_ASIC_BASEREG (NE_BASEREG + NE2000_ASIC_OFFSET * 2)
+
+#define NIC_PORT(x)	(NE_BASEREG + (x) * 2)
+#define NIC_INB(x)	inb(NIC_PORT(x))
+#define NIC_OUTB(x, b)	outb(NIC_PORT(x), (b))
+
+#define NE_16BIT
+
+#define DELAY(x) delay(x)
+
+/*
+ * NE2000 on Neptune-X and Nereid has the following regsiter mappings:
+ *  - 8bit NIC registers are mapped at sparse even addresses
+ *  - 16bit data registers on NE2000 ASIC are used to transfer stream data
+ *    so no software byte swap ops are necessary even on word access
+ */
+#define ASIC_PORT(x)	(NE_ASIC_BASEREG + (x) * 2)
+#define ASIC_INB(x)	inb(ASIC_PORT(x))
+#define ASIC_INW(x)	inw(ASIC_PORT(x))
+#define ASIC_OUTB(x, b)	outb(ASIC_PORT(x), (b))
+#define ASIC_OUTW(x, b)	outw(ASIC_PORT(x), (b))
+
+uint8_t eth_myaddr[6];
+
+int
+EtherInit(unsigned char *myadr)
+{
+	uint8_t romdata[16];
+	uint8_t tmp;
+	int i;
+
+	printf("ne: trying iobase=0x%x\n", NE_BASEREG);
+
+	dp8390_iobase = NE_BASEREG;
+	dp8390_membase = 16384;
+#ifdef NE_16BIT
+	dp8390_memsize = 16384;
+#else
+	dp8390_memsize = 8192;
+#endif
+	dp8390_cr_proto = ED_CR_RD2;
+	dp8390_dcr_reg = ED_DCR_FT1 | ED_DCR_LS;
+#ifdef NE_16BIT
+	dp8390_dcr_reg |= ED_DCR_WTS;
+#endif
+
+	/* reset */
+	tmp = ASIC_INB(NE2000_ASIC_RESET);
+	DELAY(10000);
+	ASIC_OUTB(NE2000_ASIC_RESET, tmp);
+	DELAY(5000);
+
+	NIC_OUTB(ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
+	DELAY(5000);
+
+	tmp = NIC_INB(ED_P0_CR);
+	if ((tmp & (ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) !=
+		(ED_CR_RD2 | ED_CR_STP)) {
+		goto out;
+	}
+
+	tmp = NIC_INB(ED_P0_ISR);
+	if ((tmp & ED_ISR_RST) != ED_ISR_RST) {
+		goto out;
+	}
+
+	NIC_OUTB(ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
+
+	for (i = 0; i < 100; i++) {
+		if ((NIC_INB(ED_P0_ISR) & ED_ISR_RST) == ED_ISR_RST) {
+			/* Ack the reset bit. */
+			NIC_OUTB(ED_P0_ISR, ED_ISR_RST);
+			break;
+		}
+		DELAY(100);
+	}
+
+	printf("ne: found\n");
+
+	/*
+	 * This prevents packets from being stored in the NIC memory when
+	 * the readmem routine turns on the start bit in the CR.
+	 */
+	NIC_OUTB(ED_P0_RCR, ED_RCR_MON);
+
+	/* Temporarily initialize DCR for to read romdata. */
+#ifdef NE_16BIT
+	NIC_OUTB(ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS | ED_DCR_WTS);
+#else
+	NIC_OUTB(ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
+#endif
+
+#if 0
+	/*
+	 * dp8390_config() will init these registers later.
+	 * Note sys/dev/ic/ne2000.c sets these values to detect NE1000.
+	 */
+	NIC_OUTB(ED_P0_PSTART, 8192 >> ED_PAGE_SHIFT);
+	NIC_OUTB(ED_P0_PSTOP, 16384 >> ED_PAGE_SHIFT);
+#endif
+
+	ne2000_readmem(0, romdata, sizeof(romdata));
+	for (i = 0; i < 6; i++)
+		myadr[i] = eth_myaddr[i] = romdata[i * 2];
+
+	if (dp8390_config())
+		goto out;
+
+	return 1;
+ out:
+	return 0;
+}
+
+void
+EtherStop(void)
+{
+	uint8_t tmp;
+
+	dp8390_stop();
+
+	tmp = ASIC_INB(NE2000_ASIC_RESET);
+	DELAY(10000);
+	ASIC_OUTB(NE2000_ASIC_RESET, tmp);
+	DELAY(5000);
+
+	NIC_OUTB(ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
+	DELAY(5000);
+}
+
+void
+ne2000_writemem(uint8_t *src, int dst, size_t len)
+{
+	size_t i;
+	int maxwait = 100;	/* about 120us */
+
+	/* Select page 0 registers. */
+	NIC_OUTB(ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
+
+	/* Reset remote DMA complete flag. */
+	NIC_OUTB(ED_P0_ISR, ED_ISR_RDC);
+
+	/* Set up DMA byte count. */
+	NIC_OUTB(ED_P0_RBCR0, len);
+	NIC_OUTB(ED_P0_RBCR1, len >> 8);
+
+	/* Set up destination address in NIC mem. */
+	NIC_OUTB(ED_P0_RSAR0, dst);
+	NIC_OUTB(ED_P0_RSAR1, dst >> 8);
+
+	/* Set remote DMA write. */
+	NIC_OUTB(ED_P0_CR, ED_CR_RD1 | ED_CR_PAGE_0 | ED_CR_STA);
+
+#ifdef NE_16BIT
+	for (i = 0; i < len; i += 2, src += 2)
+		ASIC_OUTW(NE2000_ASIC_DATA, *(uint16_t *)src);
+#else
+	for (i = 0; i < len; i++)
+		ASIC_OUTB(NE2000_ASIC_DATA, *src++);
+#endif
+
+	/*
+	 * Wait for remote DMA to complete.  This is necessary because on the
+	 * transmit side, data is handled internally by the NIC in bursts, and
+	 * we can't start another remote DMA until this one completes.  Not
+	 * waiting causes really bad things to happen - like the NIC wedging
+	 * the bus.
+	 */
+	while (((NIC_INB(ED_P0_ISR) & ED_ISR_RDC) != ED_ISR_RDC) && --maxwait)
+		DELAY(1);
+
+	if (maxwait == 0)
+		printf("ne2000_writemem: failed to complete\n");
+}
+
+void
+ne2000_readmem(int src, uint8_t *dst, size_t amount)
+{
+	size_t i;
+
+	/* Select page 0 registers. */
+	NIC_OUTB(ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
+
+	/* Round up to a word. */
+	if (amount & 1)
+		++amount;
+
+	/* Set up DMA byte count. */
+	NIC_OUTB(ED_P0_RBCR0, amount);
+	NIC_OUTB(ED_P0_RBCR1, amount >> 8);
+
+	/* Set up source address in NIC mem. */
+	NIC_OUTB(ED_P0_RSAR0, src);
+	NIC_OUTB(ED_P0_RSAR1, src >> 8);
+
+	NIC_OUTB(ED_P0_CR, ED_CR_RD0 | ED_CR_PAGE_0 | ED_CR_STA);
+
+#ifdef NE_16BIT
+	for (i = 0; i < amount; i += 2, dst += 2)
+		*(uint16_t *)dst = ASIC_INW(NE2000_ASIC_DATA);
+#else
+	for (i = 0; i < amount; i++)
+		*dst++ = ASIC_INB(NE2000_ASIC_DATA);
+#endif
+}
Index: src/sys/arch/x68k/stand/boot/ne.h
diff -u /dev/null src/sys/arch/x68k/stand/boot/ne.h:1.1
--- /dev/null	Fri Oct 12 20:15:53 2012
+++ src/sys/arch/x68k/stand/boot/ne.h	Fri Oct 12 20:15:52 2012
@@ -0,0 +1,38 @@
+/*	$NetBSD: ne.h,v 1.1 2012/10/12 20:15:52 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2003 Tetsuya Isaki. 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.
+ *
+ * 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 inb(x)     *(volatile uint8_t *)(x)
+#define inw(x)     *(volatile uint16_t *)(x)
+#define outb(x, b) *(volatile uint8_t *)(x) = (b)
+#define outw(x, w) *(volatile uint16_t *)(x) = (w)
+
+extern uint neaddr;
+
+int  EtherInit(unsigned char *);
+void EtherStop(void);
+void ne2000_readmem(int, uint8_t *, size_t);
+void ne2000_writemem(uint8_t *, int, size_t);

Index: src/sys/arch/x68k/stand/libsa/clock.c
diff -u /dev/null src/sys/arch/x68k/stand/libsa/clock.c:1.1
--- /dev/null	Fri Oct 12 20:15:53 2012
+++ src/sys/arch/x68k/stand/libsa/clock.c	Fri Oct 12 20:15:52 2012
@@ -0,0 +1,112 @@
+/* $NetBSD: clock.c,v 1.1 2012/10/12 20:15:52 tsutsui Exp $ */
+/* Id: clock.c,v 1.4 2011/04/10 09:21:45 isaki Exp  */
+
+/*
+ * Copyright (c) 2003 Tetsuya Isaki. 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.
+ *
+ * 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/types.h>
+#include <lib/libsa/stand.h>
+#include <lib/libsa/net.h>
+#include "iocs.h"
+#include "libx68k.h"
+#include "consio.h"	/* XXX: for MFP_TIMERC */
+
+/* x68k's RTC is defunct 2079, so there is no y2100 problem. */
+#define LEAPYEAR(y)	(((y) % 4) == 0)
+#define SECDAY	(24 * 60 * 60)
+
+int rtc_offset;
+
+const int yday[] = {
+	0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+};
+
+satime_t
+getsecs(void)
+{
+	int val;
+	int sec, min, hour, day, mon, year;
+	int days, y;
+
+	/* Get date & time via IOCS */
+	val  = IOCS_DATEBIN(IOCS_BINDATEGET());
+	year = ((val & 0x0fff0000) >> 16) + 1980;
+	mon  = ((val & 0x0000ff00) >>  8);
+	day  =  (val & 0x000000ff);
+
+	val  = IOCS_TIMEBIN(IOCS_TIMEGET());
+	hour = ((val & 0x00ff0000) >> 16);
+	min  = ((val & 0x0000ff00) >>  8);
+	sec  =  (val & 0x000000ff);
+
+	/* simple sanity checks */
+	if (mon < 1 || mon > 12 || day < 1 || day > 31)
+		return 0;
+	if (hour > 23 || min > 59 || sec > 59)
+		return 0;
+
+	days = 0;
+	for (y = 1970; y < year; y++)
+		days += 365 + LEAPYEAR(y);
+	days += yday[mon - 1] + day - 1;
+	if (LEAPYEAR(y) && mon > 2)
+		days++;
+
+	/* now we have days since Jan 1, 1970. the rest is easy... */
+	return (days * SECDAY) + (hour * 3600) + (min * 60) + sec
+		+ (rtc_offset * 60);
+}
+
+void
+delay(int us)
+{
+	int end;
+
+	/* sanity check */
+	if (us < 1)
+		return;
+
+	/*
+	 * assume IPLROM initializes MFP Timer-C as following:
+	 *  - free run down count
+	 *  - 1/200 presclaer (50us with 4MHz clock)
+	 *
+	 * Note we can't change MFP_TCDR reload value (200)
+	 * because awaitkey_1sec() in consio.c assumes that value.
+	 */
+
+	/* handle >5ms delays first */
+	for (; us > 5000; us -= 5000) {
+		MFP_TIMERC = 200;
+		while (MFP_TIMERC >= 100)
+			continue;
+	}
+
+	/* count rest fractions */
+	end = 200 - (us / 50);
+	MFP_TIMERC = 200;
+	while (MFP_TIMERC >= end)
+		continue;
+}

Index: src/sys/arch/x68k/stand/netboot/Makefile
diff -u /dev/null src/sys/arch/x68k/stand/netboot/Makefile:1.1
--- /dev/null	Fri Oct 12 20:15:53 2012
+++ src/sys/arch/x68k/stand/netboot/Makefile	Fri Oct 12 20:15:53 2012
@@ -0,0 +1,72 @@
+#	$NetBSD: Makefile,v 1.1 2012/10/12 20:15:53 tsutsui Exp $
+#	Id: Makefile,v 1.14 2011/10/04 12:59:33 isaki Exp 
+
+NOMAN=		# defined
+
+.include <bsd.own.mk>
+
+BOOT=		Netboot
+VERSIONFILE=	${.CURDIR}/version
+VERSION!=	${TOOL_AWK} -F: '$$1 ~ /^[0-9.]*$$/ { it = $$1; } \
+			END { print it }' ${VERSIONFILE}
+NEWVERSWHAT=	"${BOOT}"
+
+# text address
+TEXT=		006000
+
+# RTC offset
+RTC_OFFSET=	-540
+
+PROG=		netboot
+BINDIR=		/usr/mdec
+BINMODE=	444
+STRIPFLAG=
+
+BFDNAME=	a.out-m68k-netbsd
+STRIP?=		/usr/bin/strip
+OBJCOPY?=	/usr/bin/objcopy
+
+# XXX shared sources should be in COMMONDIR
+BOOTDIR=	${.CURDIR}/../boot
+.PATH:		${BOOTDIR}
+
+SRCS=		srt0.S boot.c conf.c exec_image.S if_ne.c ne.c dp8390.c
+S=		${.CURDIR}/../../../..
+M=		${.CURDIR}/../..
+COMMONDIR=	$M/stand/common
+.PATH:		${COMMONDIR}
+
+SRCS+=		vers.c
+CLEANFILES+=	vers.c
+vers.c:	${VERSIONFILE}
+	${_MKTARGET_CREATE}
+	${HOST_SH} ${S}/conf/newvers_stand.sh ${${MKREPRO} == "yes" :?:-D} \
+	    ${.ALLSRC} ${MACHINE} ${NEWVERSWHAT}
+
+CPPFLAGS+=	-nostdinc -I$S -I${.OBJDIR} -I$M/stand/libsa
+CPPFLAGS+=	-I$M/stand/libiocs -I${COMMONDIR}
+CPPFLAGS+=	-D_STANDALONE -DHEAP_VARIABLE
+CPPFLAGS+=	-DTEXTADDR="0x${TEXT}" 
+CPPFLAGS+=	-DBOOT=\"${BOOT}\" -DBOOT_VERS=\"${VERSION}\"
+CPPFLAGS+=	-DLIBSA_ENABLE_LS_OP
+CPPFLAGS+=	-DRTC_OFFSET=${RTC_OFFSET}
+CPPFLAGS+=	-DSUPPORT_BOOTP -DSUPPORT_DHCP
+CFLAGS=		-Wno-main -Os -m68020-60
+LINKFLAGS=	-N -static -T ${BOOTDIR}/boot.ldscript
+LIBIOCS!=	cd $M/stand/libiocs && ${PRINTOBJDIR}
+LIBSA!=		cd $M/stand/libsa && ${PRINTOBJDIR}
+L=		${LIBSA}/lib
+LDLIBS= 	${L}/sa/libsa.a ${L}/kern/libkern.a ${L}/z/libz.a
+LDLIBS+=	${LIBIOCS}/libiocs.a
+
+.include "../Makefile.booters"
+
+realall: ${PROG}
+${PROG}:	${OBJS} ${LDLIBS}
+	${_MKTARGET_LINK}
+	${LD} ${LINKFLAGS} -o ${PROG}.sym ${OBJS} ${LDLIBS}
+	${STRIP} -F ${BFDNAME} -o ${PROG} ${PROG}.sym
+
+CLEANFILES+=	${PROG}.sym
+
+.include <bsd.prog.mk>
Index: src/sys/arch/x68k/stand/netboot/boot.c
diff -u /dev/null src/sys/arch/x68k/stand/netboot/boot.c:1.1
--- /dev/null	Fri Oct 12 20:15:53 2012
+++ src/sys/arch/x68k/stand/netboot/boot.c	Fri Oct 12 20:15:53 2012
@@ -0,0 +1,249 @@
+/*	$NetBSD: boot.c,v 1.1 2012/10/12 20:15:53 tsutsui Exp $	*/
+/*	Id: boot.c,v 1.19 2011/10/04 12:45:16 isaki Exp 	*/
+
+/*
+ * Copyright (c) 2001 Minoura Makoto
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/param.h>
+#include <machine/bootinfo.h>
+
+#include <lib/libsa/stand.h>
+#include <lib/libsa/loadfile.h>
+#include <lib/libsa/ufs.h>
+#include <lib/libsa/dev_net.h>
+#include <lib/libkern/libkern.h>
+
+#include "libx68k.h"
+#include "iocs.h"
+
+#include "exec_image.h"
+
+
+#define HEAP_START	((void*) 0x00080000)
+#define HEAP_END	((void*) 0x000fffff)
+#define EXSCSI_BDID	((void*) 0x00ea0001)
+#define SRAM_MEMSIZE	(*((long*) 0x00ed0008))
+
+char default_kernel[20] = "nfs:netbsd";
+int mpu;
+int console_device = -1;
+
+#ifdef DEBUG
+int debug = 1;
+#endif
+
+static void help(void);
+static void doboot(const char *, int);
+static void boot(char *);
+int bootmenu(void);
+void bootmain(int);
+extern int detectmpu(void);
+extern int badbaddr(void *);
+
+static void
+help(void)
+{
+	printf("Usage:\n");
+	printf("boot [dev:][file] -[flags]\n");
+	printf(" dev:   nfs, first probed NE2000 is used.\n");
+	printf(" file:  netbsd, netbsd.gz, etc.\n");
+	printf(" flags: abdqsv\n");
+	printf("halt\nreboot\n");
+}
+
+static void
+doboot(const char *file, int flags)
+{
+	u_long		marks[MARK_MAX];
+	int fd;
+	int dev, unit, part;
+	char *name;
+	short *p;
+	int loadflag;
+
+	printf("Starting %s, flags 0x%x\n", file, flags);
+
+	loadflag = LOAD_KERNEL;
+	if (file[0] == 'f')
+		loadflag &= ~LOAD_BACKWARDS;
+		
+	marks[MARK_START] = 0x100000;
+	if ((fd = loadfile(file, marks, loadflag)) == -1) {
+		printf("loadfile failed\n");
+		return;
+	}
+	close(fd);
+
+	if (devparse(file, &dev, &unit, &part, &name) != 0) {
+		printf("XXX: unknown corruption in /boot.\n");
+	}
+
+	printf("dev = %x, unit = %d, name = %s\n",
+	       dev, unit, name);
+
+	dev = X68K_MAKEBOOTDEV(X68K_MAJOR_NE, unit, 0);
+	printf("boot device = %x\n", dev);
+	printf("if = %d, unit = %d\n",
+	       B_X68K_SCSI_IF(dev),
+	       B_X68K_SCSI_IF_UN(dev));
+
+	p = ((short*) marks[MARK_ENTRY]) - 1;
+	printf("Kernel Version: 0x%x\n", *p);
+	if (*p != 0x4e73 && *p != 0) {
+		/*
+		 * XXX temporary solution; compatibility loader
+		 * must be written.
+		 */
+		printf("This kernel is too new to be loaded by "
+		       "this version of /boot.\n");
+		return;
+	}
+
+	exec_image(marks[MARK_START], 0, marks[MARK_ENTRY]-marks[MARK_START],
+		   marks[MARK_END]-marks[MARK_START], dev, flags);
+
+	return;
+}
+
+static void
+boot(char *arg)
+{
+	char filename[80];
+	char *p;
+	int flags = 0;
+
+	if (*arg == 0 || *arg == '-') {
+		strcpy(filename, default_kernel);
+		if (*arg == '-')
+			if (parseopts(arg, &flags) == 0) {
+				help();
+				return;
+			}
+		doboot(filename, flags);
+		return;
+	} else {
+		p = gettrailer(arg);
+		if (strchr(arg, ':')) {
+			strcpy(filename, arg);
+			if (arg[strlen(arg) - 1] == ':')
+				strcat(filename, "netbsd");
+		} else {
+			strcpy(filename, default_kernel);
+			strcpy(strchr(filename, ':') + 1, arg);
+		}
+		if (*p == '-') {
+			if (parseopts(p, &flags) == 0)
+				return;
+		} else if (*p != 0) {
+			help();
+			return;
+		}
+
+		doboot(filename, flags);
+		return;
+	}
+}
+
+int
+bootmenu(void)
+{
+	char input[80];
+	int n = 5, c;
+
+	printf("Press return to boot now, any other key for boot menu\n");
+	printf("booting %s - starting in %d seconds. ",
+		default_kernel, n);
+	while (n-- > 0 && (c = awaitkey_1sec()) == 0) {
+		printf("\r");
+		printf("booting %s - starting in %d seconds. ",
+		       default_kernel, n);
+	}
+	printf("\r");
+	printf("booting %s - starting in %d seconds. ", default_kernel, 0);
+	printf("\n");
+	
+	if (c == 0 || c == '\r') {
+		doboot(default_kernel, 0);
+		printf("Could not start %s; ", default_kernel);
+		strcat(default_kernel, ".gz");
+		printf("trying %s.\n", default_kernel);
+		doboot(default_kernel, 0);
+		printf("Could not start %s; ", default_kernel);
+	}
+
+	printf("Please use the absolute unit# (e.g. SCSI ID)"
+	       " instead of the NetBSD logical #.\n");
+	for (;;) {
+		char *p, *options;
+
+		printf("> ");
+		gets(input);
+
+		for (p = &input[0]; p - &input[0] < 80 && *p == ' '; p++)
+			;
+		options = gettrailer(p);
+		if (strcmp("boot", p) == 0)
+			boot(options);
+		else if (strcmp("help", p) == 0 || strcmp("?", p) == 0)
+			help();
+		else if (strcmp("halt", p) == 0 || strcmp("reboot", p) == 0)
+			exit(0);
+		else
+			printf("Unknown command %s\n", p);
+	}
+}
+
+
+extern const char bootprog_rev[];
+extern const char bootprog_name[];
+
+/*
+ * Arguments from the boot block:
+ *   bootdev - specifies the device from which /boot was read, in 
+ *		bootdev format.
+ */
+void
+bootmain(int bootdev)
+{
+	mpu = detectmpu();
+	rtc_offset = RTC_OFFSET;
+	try_bootp = 1;
+
+	if (mpu < 3) {		/* not tested on 68020 */
+		printf("This MPU cannot run NetBSD.\n");
+		exit(1);
+	}
+	if (SRAM_MEMSIZE < 4*1024*1024) {
+		printf("Main memory too small.\n");
+		exit(1);
+	}
+
+	console_device = consio_init(console_device);
+	setheap(HEAP_START, HEAP_END);
+
+	print_title("%s, Revision %s\n", bootprog_name, bootprog_rev);
+	bootmenu();
+}
Index: src/sys/arch/x68k/stand/netboot/conf.c
diff -u /dev/null src/sys/arch/x68k/stand/netboot/conf.c:1.1
--- /dev/null	Fri Oct 12 20:15:53 2012
+++ src/sys/arch/x68k/stand/netboot/conf.c	Fri Oct 12 20:15:53 2012
@@ -0,0 +1,64 @@
+/*	$NetBSD: conf.c,v 1.1 2012/10/12 20:15:53 tsutsui Exp $	*/
+/*	Id: conf.c,v 1.7 2011/04/10 09:20:27 isaki Exp 	*/
+
+/*
+ * Copyright (c) 2001 Minoura Makoto
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/param.h>
+#include <lib/libsa/stand.h>
+#include <lib/libsa/dev_net.h>
+#include <netinet/in.h>
+#include <lib/libsa/nfs.h>
+#include <lib/libsa/ufs.h>
+#include <lib/libsa/lfs.h>
+#include <lib/libsa/cd9660.h>
+#include <lib/libsa/ustarfs.h>
+
+#include "libx68k.h"
+
+struct devsw devsw[] = {
+	{ "nfs", net_strategy, net_open, net_close, net_ioctl },
+};
+int ndevs = sizeof(devsw) / sizeof(devsw[0]);
+
+const struct devspec devspec[] = {
+	{ "nfs", 0, 1, 1 },
+	{ 0,    0, 0, 0 },
+};
+
+struct fs_ops file_system[] = {
+	FS_OPS(nfs),
+};
+int nfsys = sizeof(file_system) / sizeof(file_system[0]);
+
+struct open_file files[SOPEN_MAX];
+
+extern struct netif_driver ne_netif_driver;
+
+struct netif_driver *netif_drivers[] = {
+	&ne_netif_driver,
+};
+int n_netif_drivers = sizeof(netif_drivers) / sizeof(netif_drivers[0]);
Index: src/sys/arch/x68k/stand/netboot/version
diff -u /dev/null src/sys/arch/x68k/stand/netboot/version:1.1
--- /dev/null	Fri Oct 12 20:15:53 2012
+++ src/sys/arch/x68k/stand/netboot/version	Fri Oct 12 20:15:53 2012
@@ -0,0 +1,7 @@
+$NetBSD: version,v 1.1 2012/10/12 20:15:53 tsutsui Exp $
+
+NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.  The format of this
+file is important - make sure the entries are appended on end, last item
+is taken as the current.
+
+0.1:	Initial netboot

Reply via email to