NetBSD/x68k 用 netboot の残骸。 isaki@NetBSD.org 2011/10/09 経緯など 2001年〜2003年頃 PRO-II + Xellent30 (68030/25MHz) で動作して いた。DHCP でアドレス取得、たぶん NFS でカーネルを取得して 起動、そのカーネルの Root FS を NFS にしておくことで、 SCSI インタフェースを持たない機種でも、Neptune-X や Nereid が あれば、ディスクレスで NetBSD/x68k が起動が出来ていた。 なおその当時から、うちの X68030 (68030/30MHz) では動作しな かった。たぶん手抜き実装によるタイミングとかじゃないかなあ。 2011/10 頃の -current に合わせて適当にソースを最新のものに 揃えるとかしたので 2011/10 現在ビルドは通るが、 PRO-II + Xellent30、X68030 いずれも最初の DHCP 要求パケットは 出すが DHCP サーバが返した応答を受け取れていないようだ。 ビルド方法 この diff を展開して sys/arch/x68k/stand 以下あたりで make dependall とかすればたぶんいいはず。 stand/netboot の下に boot が出来ている。 (名前、netboot に変えたほうがいい?) インストール方法 この netboot を boot の代わりに書き込めばよい。 インストールフロッピーの1麻衣目を作って上書きするのが楽かも。 たぶんこんな感じ。 # cp sys/arch/x68k/stand/netboot/boot USTAR.volsize.4540 # tar cf netboot.tar USTAR.volsize.4540 # dd if=netboot.tar of=sysinst1.fs bs=512 seek=16 後は任せた! sys/lib/libsa/dev_net.c はただの typo。 netboot はほぼ隣の boot からコピーして派生しているので、 もうちょっとマシな構造にしたほうがいいかも。 x68k/stand/libsa/clock.c は mvme68k/stand/libsa/clock.c を ベースにしているのでそちらも参照のこと。 NE2000 関連は sys/arch/i386/stand/lib/netif/ あたりから拝借 したのでそちらも参照のこと。 i386 の dp8390.c には一か所 le16toh() が抜けてるところがある (i386 と NE2000 が両方 LE だからあっちは動いてる)。 連絡先 isaki@NetBSD.org --- sys/lib/libsa/dev_net.c 4 Oct 2011 07:46:45 -0000 1.1.1.7 +++ sys/lib/libsa/dev_net.c 4 Oct 2011 08:23:18 -0000 1.9 @@ -122,7 +122,7 @@ fail: netif_close(netdev_sock); netdev_sock = -1; - return error; + return errno; } #ifdef NETIF_DEBUG if (debug) --- sys/lib/libsa/strerror.c 15 Mar 2008 04:33:32 -0000 1.1.1.7 +++ sys/lib/libsa/strerror.c 15 Mar 2008 04:46:17 -0000 1.8 @@ -54,6 +54,7 @@ { ENOTDIR, "Not a directory" }, { EOFFSET, "invalid file offset" }, { EACCES, "Permission denied" }, + { ETIMEDOUT, "Operation timed out" }, { 0, 0 }, }; --- sys/arch/x68k/stand/Makefile 5 Oct 2002 06:14:18 -0000 1.1.1.1 +++ sys/arch/x68k/stand/Makefile 4 Oct 2011 12:47:44 -0000 1.2 @@ -1,6 +1,6 @@ # $NetBSD: Makefile,v 1.8 2002/01/27 01:07:00 minoura Exp $ SUBDIR= mboot newdisk aout2hux libdos libiocs .WAIT loadbsd # common -SUBDIR+= libsa .WAIT boot boot_ufs boot_ustar installboot +SUBDIR+= libsa .WAIT boot netboot boot_ufs boot_ustar installboot .include --- sys/arch/x68k/stand/libsa/Makefile 4 Oct 2011 07:46:45 -0000 1.1.1.14 +++ sys/arch/x68k/stand/libsa/Makefile 4 Oct 2011 12:47:23 -0000 1.23 @@ -8,6 +8,7 @@ CPPFLAGS+= -DHEAP_VARIABLE CPPFLAGS+= -DHAVE_CHANGEDISK_HOOK CPPFLAGS+= -DUSTAR_SECT_PER_CYL=16 +CPPFLAGS+= -DSUPPORT_DHCP #CPPFLAGS+= -DDEBUG .PATH: ${LIBSADIR} ${LIBKERNDIR} ${LIBZDIR} ${LIBZDIST} @@ -31,7 +32,11 @@ ### find out what to use for libsa SA_AS= library -SAMISCMAKEFLAGS= SA_USE_CREAD=yes SA_USE_LOADFILE=yes SA_EXTRADIR=${.CURDIR} +SAMISCMAKEFLAGS= \ + SA_USE_CREAD=yes \ + SA_USE_LOADFILE=yes \ + SA_INCLUDE_NET=yes \ + SA_EXTRADIR=${.CURDIR} .include "${S}/lib/libsa/Makefile.inc" LIBSA= ${SALIB} --- sys/arch/x68k/stand/libsa/Makefile.inc 4 Oct 2011 07:46:45 -0000 1.1.1.1 +++ sys/arch/x68k/stand/libsa/Makefile.inc 4 Oct 2011 12:47:23 -0000 1.2 @@ -7,5 +7,7 @@ SRCS+= consio.c devopen.c parseutils.c sdcd.c fd.c fdsub.S chdsk.c SRCS+= putimage.S +SRCS+= clock.c -#SRCS+= dev_net.c +SRCS+= dev_net.c +CPPFLAGS+= -DSUPPORT_BOOTP --- /dev/null 2011-10-09 03:24:27.000000000 +0900 +++ sys/arch/x68k/stand/libsa/clock.c 2011-04-10 18:21:45.000000000 +0900 @@ -0,0 +1,53 @@ +/* $Id: clock.c,v 1.4 2011/04/10 09:21:45 isaki Exp $ */ + +/* copyright (c) 2003 by isaki */ + +#include +#include +#include "iocs.h" + +/* 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); +} --- sys/arch/x68k/stand/libsa/devopen.c 4 Oct 2011 07:46:45 -0000 1.1.1.4 +++ sys/arch/x68k/stand/libsa/devopen.c 4 Oct 2011 08:23:08 -0000 1.5 @@ -64,10 +64,13 @@ 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_part) { + *part = *s++ - 'a'; + if (*part < 0 || *part > MAXPARTITIONS) + /* bad partition */ + return ENODEV; + } if (*s++ != ':') return ENODEV; --- sys/arch/x68k/stand/libsa/libx68k.h 15 Mar 2008 04:33:03 -0000 1.1.1.2 +++ sys/arch/x68k/stand/libsa/libx68k.h 29 Nov 2008 07:58:09 -0000 1.5 @@ -34,6 +34,7 @@ const char *ds_name; int ds_dev; int ds_maxunit; + int ds_part; /* 1 = partition exists (i.e., not network device) */ }; /* consio.c */ @@ -68,3 +69,6 @@ /* chdsk.c */ int changedisk_hook(struct open_file *); + +/* clock.c */ +int rtc_offset; --- /dev/null 2011-10-08 18:45:34.000000000 +0900 +++ sys/arch/x68k/stand/netboot/Makefile 2011-10-08 21:32:33.000000000 +0900 @@ -0,0 +1,67 @@ +# $Id: Makefile,v 1.14 2011/10/04 12:59:33 isaki Exp $ +# $NetBSD: Makefile,v 1.20 2011/04/12 14:07:35 tsutsui Exp $ + +NOMAN= # defined + +.include + +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= boot +BINDIR= /usr/mdec +BINMODE= 444 +STRIPFLAG= + +BFDNAME= a.out-m68k-netbsd +STRIP?= /usr/bin/strip +OBJCOPY?= /usr/bin/objcopy + +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+= -DRTC_OFFSET=${RTC_OFFSET} +CPPFLAGS+= -DSUPPORT_BOOTP +CFLAGS= -Wno-main -Os -m68020-60 +LINKFLAGS= -N -static -T ${.CURDIR}/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 --- /dev/null 2011-10-08 18:45:34.000000000 +0900 +++ sys/arch/x68k/stand/netboot/boot.c 2011-10-04 21:45:16.000000000 +0900 @@ -0,0 +1,249 @@ +/* $Id: boot.c,v 1.19 2011/10/04 12:45:16 isaki Exp $ */ +/* $NetBSD: boot.c,v 1.16 2011/01/22 19:19:24 joerg 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 +#include + +#include +#include +#include +#include +#include + +#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] = "ne0: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: ne, UNIT=0-1\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(); +} --- /dev/null 2011-10-08 21:33:25.000000000 +0900 +++ sys/arch/x68k/stand/netboot/boot.ldscript 2011-04-10 17:49:51.000000000 +0900 @@ -0,0 +1,51 @@ +/* /boot must be a.out, OMAGIC starting from 0x8000. */ +OUTPUT_FORMAT("a.out-m68k-netbsd", "a.out-m68k-netbsd", + "a.out-m68k-netbsd") +OUTPUT_ARCH(m68k) +ENTRY(start) +SEARCH_DIR(/usr/lib); +/*__DYNAMIC = 0; */ +PROVIDE (__stack = 0); +SECTIONS +{ + . = 0x6000; + .text : + { + CREATE_OBJECT_SYMBOLS + *(.text) + *(.rodata) + *(.rodata.str1.1) + /* The next six sections are for SunOS dynamic linking. The order + is important. */ + *(.dynrel) + *(.hash) + *(.dynsym) + *(.dynstr) + *(.rules) + *(.need) + etext = .; + _etext = .; + } +/* . = ALIGN(0x2000); */ + .data : + { + /* The first three sections are for SunOS dynamic linking. */ + *(.dynamic) + *(.got) + *(.plt) + *(.data) + *(.linux-dynamic) /* For Linux dynamic linking. */ + CONSTRUCTORS + edata = .; + _edata = .; + } + .bss : + { + __bss_start = .; + *(.bss) + *(COMMON) + end = ALIGN(4) ; + _end = ALIGN(4) ; + } + /DISCARD/ : { *(.ident) *(.stab) *(.stabstr) *(.comment) } +} --- /dev/null 2011-10-08 21:33:25.000000000 +0900 +++ sys/arch/x68k/stand/netboot/conf.c 2011-04-10 18:20:27.000000000 +0900 @@ -0,0 +1,64 @@ +/* $Id: conf.c,v 1.7 2011/04/10 09:20:27 isaki Exp $ */ +/* $NetBSD: conf.c,v 1.8 2005/12/11 12:19:44 christos 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libx68k.h" + +struct devsw devsw[] = { + { "net", net_strategy, net_open, net_close, net_ioctl }, +}; +int ndevs = sizeof(devsw) / sizeof(devsw[0]); + +const struct devspec devspec[] = { + { "ne", 0, 1, 0 }, + { 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]); --- /dev/null 2011-10-08 21:33:25.000000000 +0900 +++ sys/arch/x68k/stand/netboot/dp8390.c 2011-10-05 22:16:20.000000000 +0900 @@ -0,0 +1,294 @@ +/* $Id: dp8390.c,v 1.14 2011/10/05 13:16:20 isaki Exp $ */ +/* $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 + +#include +#include + +#include +#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; +} --- /dev/null 2011-10-08 21:33:25.000000000 +0900 +++ sys/arch/x68k/stand/netboot/dp8390.h 2011-10-05 22:16:20.000000000 +0900 @@ -0,0 +1,31 @@ +/* $Id: dp8390.h,v 1.7 2011/10/05 13:16:20 isaki Exp $ */ +/* $NetBSD: dp8390.h,v 1.6 2008/12/14 18:46:33 christos Exp $ */ + +extern int dp8390_config(void); +extern 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 */ + +extern int EtherSend(char *, int); +extern int EtherReceive(char *, int); --- /dev/null 2011-10-08 21:33:25.000000000 +0900 +++ sys/arch/x68k/stand/netboot/if_ne.c 2011-10-05 22:17:06.000000000 +0900 @@ -0,0 +1,141 @@ +/* $Id: if_ne.c,v 1.28 2011/10/05 13:17:06 isaki Exp $ */ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "iocs.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[] = { + 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) +{ +#if 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) +{ +#if 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) +{ +#if DEBUG + printf("ne_end\n"); +#endif + + EtherStop(); +} + +/* XXX AD-HOC delay(us) */ +void +delay(int us) +{ + int cnt, start; + + cnt = us / 1000 / 10; /* 10msec unit */ + if (cnt == 0) + cnt = 1; + start = IOCS_ONTIME(); + while (IOCS_ONTIME() >= start + cnt) + ; +} + + +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]), +}; --- /dev/null 2011-10-08 21:33:25.000000000 +0900 +++ sys/arch/x68k/stand/netboot/ne.c 2011-10-05 22:16:20.000000000 +0900 @@ -0,0 +1,254 @@ +/* $Id: ne.c,v 1.22 2011/10/05 13:16:20 isaki Exp $ */ +/* $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 + +#include +#include + +#include + +#include +#include +#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) + +#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)) + +u_char eth_myaddr[6]; + +int +EtherInit(unsigned char *myadr) +{ + uint8_t romdata[32]; + uint8_t tmp; + int i; + + printf("ne: trying iobase=0x%x\n", NE_BASEREG); + + dp8390_iobase = NE_BASEREG; + dp8390_membase = dp8390_memsize = 8192*2; + dp8390_cr_proto = ED_CR_RD2; + dp8390_dcr_reg = ED_DCR_FT1 | ED_DCR_LS +#ifdef NE_16BIT + | 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 byte operations. */ + NIC_OUTB(ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS); + + NIC_OUTB(ED_P0_PSTART, 8192 >> ED_PAGE_SHIFT); + NIC_OUTB(ED_P0_PSTOP, 16384 >> ED_PAGE_SHIFT); + +#ifdef NE_16BIT + ne2000_readmem(0, romdata, 6 * 4); +#else + ne2000_readmem(0, romdata, 6 * 2); +#endif + for (i = 0; i < 6; i++) +#ifdef NE_16BIT + myadr[i] = eth_myaddr[i] = romdata[i*4]; +#else + myadr[i] = eth_myaddr[i] = romdata[i*2]; +#endif + + 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 +} --- /dev/null 2011-10-08 21:33:25.000000000 +0900 +++ sys/arch/x68k/stand/netboot/ne.h 2011-10-05 22:17:06.000000000 +0900 @@ -0,0 +1,16 @@ +/* $Id: ne.h,v 1.9 2011/10/05 13:17:06 isaki Exp $ */ +/* $NetBSD: ne.h,v 1.3 2008/12/14 18:46:33 christos Exp $ */ + +#define inb(x) *(u_char *)(x) +#define inw(x) *(u_short*)(x) +#define outb(x, b) *(u_char *)(x) = (b) +#define outw(x, w) *(u_short*)(x) = (w) + +extern uint neaddr; + +extern int EtherInit(unsigned char *); +extern void EtherStop(void); +extern void ne2000_readmem(int, uint8_t *, size_t); +extern void ne2000_writemem(uint8_t *, int, size_t); + +extern void delay(int); --- /dev/null 2011-10-08 21:33:25.000000000 +0900 +++ sys/arch/x68k/stand/netboot/srt0.S 2011-10-04 17:33:33.000000000 +0900 @@ -0,0 +1,115 @@ +/* $NetBSD: srt0.S,v 1.2 2011/04/12 14:07:35 tsutsui 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 + +ASENTRY(start) + bra start0 + .ascii BOOT + .byte 0x20 + .asciz BOOT_VERS + .even + +/* + * via stack: (firstpa, physsize, esym) + * via regs: %d6: bootdev + * %d7: boothowto + * for /boot, only %d6 is used. + */ +start0: + moveml %sp@+,%d0-%d2 + lea %pc@(start),%sp + + movl %d6,%sp@- + jbsr _C_LABEL(bootmain) + +ENTRY_NOPROFILE(_rtt) + pea %pc@(reboot_msg) + jbsr _C_LABEL(printf) + jbsr _C_LABEL(getchar) + trap #10 + +reboot_msg: .asciz "\n[Hit key to reboot]" + .even + +/* + * Detect MPU type. From locore.s. + * Note we've already confirmed it is not 68000/010. + */ +ENTRY_NOPROFILE(detectmpu) + movl #0x200,%d0 | data freeze bit + movc %d0,%cacr | only exists on 68030 + movc %cacr,%d0 | read it back + tstl %d0 | zero? + jeq Lnot68030 | yes, we have 68020/68040/68060 + moveq #3,%d0 + jra Lgo | no, we have 68030 +Lnot68030: + bset #31,%d0 | data cache enable bit + movc %d0,%cacr | only exists on 68040/68060 + movc %cacr,%d0 | read it back + tstl %d0 | zero? + jeq Lis68020 | yes, we have 68020 + moveq #0,%d0 | now turn it back off + movec %d0,%cacr | before we access any data + .word 0xf4d8 | cinva bc - invalidate caches XXX + bset #30,%d0 | data cache no allocate mode bit + movc %d0,%cacr | only exists on 68060 + movc %cacr,%d0 | read it back + tstl %d0 | zero? + jeq Lis68040 | yes, we have 68040 + moveq #6,%d0 + jra Lgo +Lis68040: + moveq #4,%d0 + jra Lgo +Lis68020: + movl #2,%d0 | and a 68020 CPU +Lgo: + rts + +/* + * Check if the given address is valid for byte read. + * From boot_ufs/boot.S. + */ +ENTRY_NOPROFILE(badbaddr) + lea 0x0008:W,%a1 | MPU Bus Error vector + moveq #1,%d0 + lea %pc@(badr1),%a0 + movew %sr,%sp@- + oriw #0x0700,%sr | keep out interrupts + movel %a1@,%sp@- + movel %a0,%a1@ | set bus error vector + movel %sp,%d1 | save sp + moveal %sp@(10),%a0 + tstb %a0@ | try read... + moveq #0,%d0 | this is skipped on bus error +badr1: moveal %d1,%sp | restore sp + movel %sp@+,%a1@ + movew %sp@+,%sr + rts --- /dev/null 2011-10-08 21:33:25.000000000 +0900 +++ sys/arch/x68k/stand/netboot/version 2007-05-20 19:33:18.000000000 +0900 @@ -0,0 +1,8 @@ +$Id: version,v 1.4 2007/05/20 10:33:18 isaki Exp $ +$NetBSD: version,v 1.2 2001/11/09 19:53:16 scw Exp $ + +NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this +file is important - make sure the entries are appended on end, last item +is taken as the current. + +0.1: netboot test