from nivas.
Userland and compiler still need to be worked on.
Make certain what directory the import is done from.
--- /dev/null
+#
+# This configuration file contains all possible options
+#
+
+machine m88k
+
+maxusers 8
+
+options TIMEZONE=300, DST=1
+
+#
+# processors this kernel should support
+#
+options "M88000" # support for 88K
+options MVME187 # support for 187
+
+options SWAPPAGER # Pager for processes (Required)
+options VNODEPAGER # Pager for vnodes (Required)
+options DEVPAGER # Pager for devices (Required)
+
+options SYSVSHM
+options SYSVSEM
+options SYSVMSG
+
+#options CD9660 # ISO 9660 + Rock Ridge file system
+#options MSDOSFS # MS-DOS file system
+options FDESC # /dev/fd
+#options FIFO # FIFOs; RECOMMENDED
+options KERNFS # /kern
+options NULLFS # loopback file system
+#options PORTAL # ?
+options PROCFS # /proc
+#options UMAPFS # NULLFS + uid and gid remapping
+options UNION # union file system
+#
+# Networking options
+options INET
+options TCP_COMPAT_42 # compatibility with 4.2BSD TCP/IP
+#options GATEWAY # IP packet forwarding
+#options ISO # OSI networking
+#options TPIP
+#options EON
+options COMPAT_43
+options EXEC_COFF
+
+options LKM
+
+#
+
+#
+# File system related options
+#
+#options QUOTA # Disk quotas for local disks
+#options NFSSERVER # Network File System server side code
+#options NFSCLIENT # Network File System client side code
+
+#
+# File systems
+#
+options FFS # Berkeley fast file system
+options MFS # Memory based filesystem
+options FIFO # FIFO operations on vnodes (Recommended)
+
+#
+# Compatability options for various existing systems
+#
+#options "COMPAT_NOMID" # allow nonvalid machine id executables
+
+#
+# Support for System V IPC facilities.
+#
+
+#
+# Support for various kernel options
+#
+#options DIAGNOSTIC # Add additional error checking code
+options "NKMEMCLUSTERS=256" # Size of kernel malloc area
+
+#
+# Misc. debuging options
+#
+options PANICWAIT # Require keystroke to dump/reboot
+#options DEBUG # Add debugging statements
+options DDB # Kernel debugger
+options SYSCALL_DEBUG # debug all syscalls.
+options KTRACE # debug all syscalls.
+
+#
+# devices
+#
+mainbus0 at root
+# mainbus devices
+#sram0 at mainbus0 addr 0xffe00000
+vme0 at mainbus0 addr 0xfff40000
+pcctwo0 at mainbus0 addr 0xfff42000
+# pcctwo devices
+clock0 at pcctwo0 addr 0xfff42000 ipl 5
+nvram0 at pcctwo0 addr 0xfffc0000 size 0x10000
+ie0 at pcctwo0 addr 0xfff46000 ipl 3 size 0x1000
+cl0 at pcctwo0 addr 0xfff45000 ipl 4 size 0x200
+siop0 at pcctwo0 addr 0xfff47000 ipl 2 size 0x1000
+#lptwo0 at pcctwo0 addr 0xfff45000 ipl 1 size
+#mcecc0 at pcctwo0 addr 0xfff43000
+#mcecc1 at pcctwo0 addr 0xfff43100
+#memc0 at pcctwo0 addr 0xfff43000
+#memc1 at pcctwo0 addr 0xfff43100
+
+bugtty0 at mainbus0
+
+#vme0 devices
+vmes0 at vme0
+vmel0 at vme0
+
+scsibus* at siop?
+#
+#sd0 at scsibus? target 0 lun 0
+#sd1 at scsibus? target 2 lun 0
+sd* at scsibus? target ? lun ?
+st* at scsibus? target ? lun ?
+cd* at scsibus? target ? lun ?
+
+pseudo-device vnd 2
+pseudo-device bpfilter
+pseudo-device sl # slip
+pseudo-device ppp 2 # ppp
+pseudo-device pty 16 # pseudo terminals
+pseudo-device loop # network loopback
+
+config netbsd root on sd1 swap on sd1
--- /dev/null
+# @(#)Makefile.hp300 7.10 (Berkeley) 6/27/91
+# $Id: Makefile.mvme88k,v 1.1.1.1 1997/03/03 19:31:53 rahnds Exp $
+#
+# Makefile for NetBSD
+#
+# This makefile is constructed from a machine description:
+# config machineid
+# Most changes should be made in the machine description
+# /sys/arch/mvme88k/conf/``machineid''
+# after which you should do
+# config machineid
+# Machine generic makefile changes should be made in
+# /sys/arch/mvme88k/conf/Makefile.mvme88k
+# after which config should be rerun for all machines of that type.
+#
+# N.B.: NO DEPENDENCIES ON FOLLOWING FLAGS ARE VISIBLE TO MAKEFILE
+# IF YOU CHANGE THE DEFINITION OF ANY OF THESE RECOMPILE EVERYTHING
+#
+# -DTRACE compile in kernel tracing hooks
+# -DQUOTA compile in file system quotas
+
+
+# DEBUG is set to -g by config if debugging is requested (config -g).
+# PROF is set to -pg by config if profiling is requested (config -p).
+AS= as ${DEBUG}
+AWK= awk
+CC= cc ${DEBUG}
+CPP= cpp
+LD= ld
+TOUCH= touch -f -c
+
+.ifndef HOSTCC
+HOSTCC=cc
+.endif
+
+# source tree is located via $S relative to the compilation directory
+S= ../../../..
+MVME88K= ../..
+
+INCLUDES= -I. -I$S/arch -I$S -I$S/sys
+.if defined(DESTDIR)
+INCLUDES+= -nostdinc -idirafter ${DESTDIR}/usr/include
+.endif
+CPPFLAGS= ${INCLUDES} ${IDENT} -DKERNEL -D_KERNEL -Dmvme88k -Dm88k
+CFLAGS= -O ${DEBUG} #-Werror
+
+### find out what to use for libkern
+.include "$S/lib/libkern/Makefile.inc"
+.ifndef PROF
+LIBKERN= ${KERNLIB}
+.else
+LIBKERN= ${KERNLIB_PROF}
+.endif
+
+### find out what to use for libcompat
+.include "$S/compat/common/Makefile.inc"
+.ifndef PROF
+LIBCOMPAT= ${COMPATLIB}
+.else
+LIBCOMPAT= ${COMPATLIB_PROF}
+.endif
+
+# compile rules: rules are named ${TYPE}_${SUFFIX}${CONFIG_DEP}
+# where TYPE is NORMAL, DRIVER, or PROFILE}; SUFFIX is the file suffix,
+# capitalized (e.g. C for a .c file), and CONFIG_DEP is _C if the file
+# is marked as config-dependent.
+
+NORMAL_C= ${CC} -c ${CFLAGS} ${CPPFLAGS} ${PROF} $<
+NORMAL_C_C= ${CC} -c ${CFLAGS} ${CPPFLAGS} ${PROF} ${PARAM} $<
+
+DRIVER_C= ${CC} -c ${CFLAGS} ${CPPFLAGS} ${PROF} $<
+DRIVER_C_C= ${CC} -c ${CFLAGS} ${CPPFLAGS} ${PROF} ${PARAM} $<
+
+PROFILE_C= ${CC} -S -c ${CFLAGS} ${CPPFLAGS} $<; \
+ sed -e s/_mcount/mcount/ -e s/subrmcount/subr_mcount/ <$*.s | \
+ ${AS} -o $@; \
+ rm -f $*.s
+
+NORMAL_S= ${CC} -E ${CFLAGS} ${CPPFLAGS} $< | ${AS} -o $@
+NORMAL_S_C= ${CC} -E ${CFLAGS} ${CPPFLAGS} ${PARAM} $< | ${AS} -o $@
+
+%OBJS
+
+%CFILES
+
+# load lines for config "xxx" will be emitted as:
+# xxx: ${SYSTEM_DEP} swapxxx.o
+# ${SYSTEM_LD_HEAD}
+# ${SYSTEM_LD} swapxxx.o
+# ${SYSTEM_LD_TAIL}
+# Kernel is linked as a ZMAGIC executable, with start at 10020
+SYSTEM_OBJ= locore.o ${OBJS} param.o ioconf.o \
+ ${LIBKERN} ${LIBCOMPAT}
+SYSTEM_DEP= Makefile ${SYSTEM_OBJ}
+SYSTEM_LD_HEAD= @echo loading $@; rm -f $@
+SYSTEM_LD= -@if [ X${DEBUG} = X-g ]; \
+ then strip=-X; \
+ else strip=-x; \
+ fi; \
+ echo ${LD} $$strip -Ttext 0x10000 -o $@ ${SYSTEM_OBJ} libgcc.a vers.o; \
+ ${LD} $$strip -Ttext 0x10000 -e start -o $@ ${SYSTEM_OBJ} \
+ libgcc.a vers.o
+
+SYSTEM_LD_TAIL= @size $@; chmod 755 $@; \
+ [ X${DEBUG} = X-g ] && { \
+ echo cp $@ $@.gdb; rm -f $@.gdb; cp $@ $@.gdb; \
+ echo strip -d $@; strip -d $@; } || true
+
+%LOAD
+
+assym.s: genassym
+ ./genassym >assym.s
+ cp assym.s ${.CURDIR}/../../include
+
+genassym:
+ ${HOSTCC} -static ${INCLUDES} ${IDENT} ${PARAM} -Dmvme88k -Dm88k \
+ -o genassym ${MVME88K}/mvme88k/genassym.c
+
+vers.o: newvers
+
+newvers: ${SYSTEM_DEP} ${SYSTEM_SWAP_DEP}
+ sh $S/conf/newvers.sh
+ ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c vers.c
+
+clean::
+ rm -f eddep *bsd bsd.gdb tags *.o locore.i \
+ [a-z]*.s [Ee]rrs errs linterrs makelinks
+
+lint: /tmp param.c
+ @lint -hbxn -DGENERIC -Dvolatile= ${CFLAGS} ${CPPFLAGS} ${PARAM} -UKGDB \
+ ${MVME88K}/mvme88k/Locore.c ${CFILES} ${MVME88K}/mvme88k/swapgeneric.c \
+ ioconf.c param.c| \
+ grep -v 'struct/union .* never defined' | \
+ grep -v 'possible pointer alignment problem'
+
+locore.o: assym.s ${MVME88K}/mvme88k/eh.S ${MVME88K}/mvme88k/locore.S
+locore.o: machine/trap.h machine/psl.h machine/cpu.h
+ ${CPP} -DLOCORE ${CPPFLAGS} ${MVME88K}/mvme88k/locore.S | ${AS} -o locore.o
+
+# depend on root or device configuration
+autoconf.o conf.o: Makefile
+
+# depend on network or filesystem configuration
+uipc_domain.o uipc_proto.o vfs_conf.o: Makefile
+if_tun.o if_loop.o if_ethersubr.o: Makefile
+in_proto.o: Makefile
+
+# depend on maxusers
+genassym.o machdep.o: Makefile
+
+# depend on CPU configuration
+locore.o machdep.o: Makefile
+
+depend:: .depend
+.depend: assym.s param.c vnode_if.h
+ mkdep ${CFLAGS} ${CPPFLAGS} ${CFILES} ioconf.c param.c
+ mkdep -a -p ${INCLUDES} ${IDENT} ${PARAM} ${MVME88K}/mvme88k/genassym.c
+
+links:
+ egrep '#if' ${CFILES} | sed -f $S/conf/defines | \
+ sed -e 's/:.*//' -e 's/\.c/.o/' | sort -u > dontlink
+ echo ${CFILES} | tr -s ' ' '\12' | sed 's/\.c/.o/' | \
+ sort -u | comm -23 - dontlink | \
+ sed 's,../.*/\(.*.o\),rm -f \1;ln -s ../GENERIC/\1 \1,' > makelinks
+ sh makelinks && rm -f dontlink
+
+tags:
+ @echo "see $S/kern/Makefile for tags"
+
+param.c: $S/conf/param.c
+ rm -f param.c
+ cp $S/conf/param.c .
+
+param.o: param.c Makefile
+ ${NORMAL_C_C}
+
+ioconf.o: ioconf.c
+ ${NORMAL_C}
+
+%RULES
--- /dev/null
+#
+# This configuration file contains all possible options
+#
+
+machine mvme88k
+
+maxusers 32
+
+options TIMEZONE=300, DST=1
+
+options __OpenBSD__
+#
+# processors this kernel should support
+#
+options "M88000" # support for 88K
+options MVME187 # support for 187
+
+options SWAPPAGER # Pager for processes (Required)
+options VNODEPAGER # Pager for vnodes (Required)
+options DEVPAGER # Pager for devices (Required)
+
+options SYSVSHM
+options SYSVSEM
+options SYSVMSG
+
+#options CD9660 # ISO 9660 + Rock Ridge file system
+#options MSDOSFS # MS-DOS file system
+options FDESC # /dev/fd
+#options FIFO # FIFOs; RECOMMENDED
+options KERNFS # /kern
+options NULLFS # loopback file system
+#options PORTAL # ?
+options PROCFS # /proc
+#options UMAPFS # NULLFS + uid and gid remapping
+options UNION # union file system
+#
+# Networking options
+options INET
+options TCP_COMPAT_42 # compatibility with 4.2BSD TCP/IP
+#options GATEWAY # IP packet forwarding
+#options ISO # OSI networking
+#options TPIP
+#options EON
+options COMPAT_43
+options EXEC_COFF
+
+options LKM
+
+#
+
+#
+# File system related options
+#
+#options QUOTA # Disk quotas for local disks
+options NFSSERVER # Network File System server side code
+options NFSCLIENT # Network File System client side code
+
+#
+# File systems
+#
+options FFS # Berkeley fast file system
+options MFS # Memory based filesystem
+options FIFO # FIFO operations on vnodes (Recommended)
+
+#
+# Compatability options for various existing systems
+#
+#options "COMPAT_NOMID" # allow nonvalid machine id executables
+
+#
+# Support for System V IPC facilities.
+#
+
+#
+# Support for various kernel options
+#
+#options DIAGNOSTIC # Add additional error checking code
+options "NKMEMCLUSTERS=256" # Size of kernel malloc area
+
+#
+# Misc. debuging options
+#
+options PANICWAIT # Require keystroke to dump/reboot
+#options DEBUG # Add debugging statements
+options DDB # Kernel debugger
+options SYSCALL_DEBUG # debug all syscalls.
+options KTRACE # debug all syscalls.
+
+#
+# devices
+#
+mainbus0 at root
+# mainbus devices
+#sram0 at mainbus0 addr 0xffe00000
+vme0 at mainbus0 addr 0xfff40000
+pcctwo0 at mainbus0 addr 0xfff42000
+# pcctwo devices
+clock0 at pcctwo0 addr 0xfff42000 ipl 5
+nvram0 at pcctwo0 addr 0xfffc0000 size 0x10000
+ie0 at pcctwo0 addr 0xfff46000 ipl 3 size 0x1000
+cl0 at pcctwo0 addr 0xfff45000 ipl 4 size 0x200
+siop0 at pcctwo0 addr 0xfff47000 ipl 2 size 0x1000
+#lptwo0 at pcctwo0 addr 0xfff45000 ipl 1 size
+#mcecc0 at pcctwo0 addr 0xfff43000
+#mcecc1 at pcctwo0 addr 0xfff43100
+#memc0 at pcctwo0 addr 0xfff43000
+#memc1 at pcctwo0 addr 0xfff43100
+
+bugtty0 at mainbus0
+
+#vme0 devices
+vmes0 at vme0
+vmel0 at vme0
+
+scsibus* at siop?
+#
+#sd0 at scsibus? target 0 lun 0
+#sd1 at scsibus? target 2 lun 0
+sd* at scsibus? target ? lun ?
+st* at scsibus? target ? lun ?
+cd* at scsibus? target ? lun ?
+
+pseudo-device vnd 2
+pseudo-device bpfilter
+pseudo-device sl # slip
+pseudo-device ppp 2 # ppp
+pseudo-device pty 16 # pseudo terminals
+pseudo-device loop # network loopback
+
+config bsd root on sd0 swap on sd0
--- /dev/null
+maxpartitions 16
+
+device mainbus { [addr = -1 ] }
+attach mainbus at root
+
+# this should be removed after bringup
+
+device bugtty: tty
+attach bugtty at mainbus
+file arch/mvme88k/dev/bugtty.c bugtty needs-count
+device cpu
+attach cpu at mainbus
+device vme { [addr = -1], [size = -1], [ipl = 0], [vec = -1] }
+attach vme at mainbus
+device pcctwo { [addr = -1], [size = 4096], [ipl = 0] }
+attach pcctwo at mainbus
+file arch/mvme88k/dev/pcctwo.c pcctwo needs-count
+device clock
+attach clock at pcctwo
+file arch/mvme88k/dev/clock.c clock
+device nvram
+attach nvram at pcctwo
+file arch/mvme88k/dev/nvram.c nvram
+device cl: tty
+attach cl at pcctwo
+file arch/mvme88k/dev/cl.c cl needs-count
+#device ether at pcctwo
+
+include "../../../scsi/files.scsi"
+
+major { sd = 4 }
+major { st = 5 }
+major { cd = 6 }
+major { vnd = 8 }
+
+device siop: scsi
+attach siop at pcctwo
+file arch/mvme88k/dev/siop.c siop
+file arch/mvme88k/dev/siopdma.c siop
+
+device vmes
+attach vmes at vme
+device vmel
+attach vmel at vme
+
+#device vme at mainbus { }
+#device vmes at vme { [addr = -1], [len = -1], [vec = -1], [ipl = 0] }
+#device vmel at vme { [addr = -1], [len = -1], [vec = -1], [ipl = 0] }
+
+file arch/mvme88k/dev/vme.c vme | vmes | vmel
+file arch/mvme88k/dev/vmes.c vmes needs-count
+file arch/mvme88k/dev/vmel.c vmel needs-count
+
+# list of standard files
+file dev/cons.c ite | ser | tty
+file dev/cninit.c
+#file scsi/scsi_base.c scsi
+#file scsi/scsi_ioctl.c scsi
+#file scsi/scsiconf.c scsi
+
+file netinet/in_cksum.c
+file netns/ns_cksum.c ns
+
+file arch/mvme88k/mvme88k/autoconf.c
+file arch/mvme88k/mvme88k/conf.c
+file arch/mvme88k/mvme88k/cmmu.c
+file arch/mvme88k/mvme88k/disksubr.c
+file arch/mvme88k/mvme88k/dkbad.c
+file arch/mvme88k/mvme88k/eh.S
+file arch/mvme88k/mvme88k/locore_asm_routines.S
+file arch/mvme88k/mvme88k/locore_c_routines.c
+file arch/mvme88k/mvme88k/m88100_fp.S
+file arch/mvme88k/mvme88k/machdep.c
+file arch/mvme88k/mvme88k/mem.c
+file arch/mvme88k/mvme88k/pmap.c
+file arch/mvme88k/mvme88k/process.S
+file arch/mvme88k/mvme88k/process_machdep.c
+file arch/mvme88k/mvme88k/trap.c
+file arch/mvme88k/mvme88k/vm_machdep.c
+
+file arch/mvme88k/ddb/db_disasm.c
+file arch/mvme88k/ddb/db_interface.c
+file arch/mvme88k/ddb/db_sstep.c
+file arch/mvme88k/ddb/db_trace.c
+
+file arch/mvme88k/dev/mainbus.c
+file arch/mvme88k/dev/bugio.c
+
+
+device ie: ifnet, ether
+attach ie at pcctwo: ifnet, ether
+file arch/mvme88k/dev/if_ie.c ie
+
--- /dev/null
+# standard amiga information
+# $Id: std.mvme88k,v 1.1.1.1 1997/03/03 19:31:52 rahnds Exp $
+machine mvme88k
+
+mainbus0 at root
+#pcc0 at mainbus0
+#scsi0 at pcc0
--- /dev/null
+#include <machine/bugio.h>
+
+#define INCHR "0x0000"
+#define INSTAT "0x0001"
+#define INLN "0x0002"
+#define READSTR "0x0003"
+#define READLN "0x0004"
+#define DSKRD "0x0010"
+#define DSKWR "0x0011"
+#define DSKCFIG "0x0012"
+#define NETCTRL "0x001D"
+#define OUTCHR "0x0020"
+#define OUTSTR "0x0021"
+#define PCRLF "0x0026"
+#define TMDISP "0x0042"
+#define DELAY "0x0043"
+#define RTC_DSP "0x0052"
+#define RTC_RD "0x0053"
+#define RETURN "0x0063"
+#define BRD_ID "0x0070"
+#define BUGTRAP "0x01F0"
+
+int ossr0, ossr1, ossr2, ossr3;
+int bugsr0, bugsr1, bugsr2, bugsr3;
+
+#define BUGCTXT() \
+{ \
+ asm volatile ("ldcr %0, cr17" : "=r" (ossr0)); \
+ asm volatile ("ldcr %0, cr18" : "=r" (ossr1)); \
+ asm volatile ("ldcr %0, cr19" : "=r" (ossr2)); \
+ asm volatile ("ldcr %0, cr20" : "=r" (ossr3)); \
+ \
+ asm volatile ("stcr %0, cr17" :: "r"(bugsr0)); \
+ asm volatile ("stcr %0, cr18" :: "r"(bugsr1)); \
+ asm volatile ("stcr %0, cr19" :: "r"(bugsr2)); \
+ asm volatile ("stcr %0, cr20" :: "r"(bugsr3)); \
+}
+
+#define OSCTXT() \
+{ \
+ asm volatile ("ldcr %0, cr17" : "=r" (bugsr0):: "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13"); \
+ asm volatile ("ldcr %0, cr18" : "=r" (bugsr1)); \
+ asm volatile ("ldcr %0, cr19" : "=r" (bugsr2)); \
+ asm volatile ("ldcr %0, cr20" : "=r" (bugsr3)); \
+ \
+ asm volatile ("stcr %0, cr17" :: "r"(ossr0)); \
+ asm volatile ("stcr %0, cr18" :: "r"(ossr1)); \
+ asm volatile ("stcr %0, cr19" :: "r"(ossr2)); \
+ asm volatile ("stcr %0, cr20" :: "r"(ossr3)); \
+}
+
+void
+buginit()
+{
+ asm volatile ("ldcr %0, cr17" : "=r" (bugsr0));
+ asm volatile ("ldcr %0, cr18" : "=r" (bugsr1));
+ asm volatile ("ldcr %0, cr19" : "=r" (bugsr2));
+ asm volatile ("ldcr %0, cr20" : "=r" (bugsr3));
+}
+
+char
+buginchr(void)
+{
+ register int cc asm("r2");
+
+ BUGCTXT();
+ asm volatile ("or r9,r0," INCHR);
+ asm volatile ("tb0 0,r0,0x1F0");
+ /*asm("or %0,r0,r2" : "=r" (cc) : );*/
+ OSCTXT();
+ return ((char)cc & 0xFF);
+}
+
+/* return 1 if not empty else 0 */
+
+buginstat(void)
+{
+ int ret;
+
+ BUGCTXT();
+ asm volatile ("or r9,r0," INSTAT);
+ asm volatile ("tb0 0,r0,0x1F0");
+ asm volatile ("or %0,r0,r2" : "=r" (ret) : );
+ OSCTXT();
+ return (ret & 0x40 ? 1 : 0);
+}
+
+bugoutchr(unsigned char c)
+{
+ unsigned char cc;
+
+ if ((cc = c) == '\n') {
+ bugpcrlf();
+ return;
+ }
+
+ BUGCTXT();
+
+ asm("or r2,r0,%0" : : "r" (cc));
+ asm("or r9,r0," OUTCHR);
+ asm("tb0 0,r0,0x1F0");
+
+ OSCTXT();
+}
+
+bugoutstr(char *s, char *se)
+{
+ BUGCTXT();
+ asm("or r9,r0," OUTSTR);
+ asm("tb0 0,r0,0x1F0");
+ OSCTXT();
+}
+
+bugpcrlf(void)
+{
+ BUGCTXT();
+ asm("or r9,r0," PCRLF);
+ asm("tb0 0,r0,0x1F0");
+ OSCTXT();
+}
+
+/* return 0 on success */
+
+bugdskrd(struct bugdisk_io *arg)
+{
+ int ret;
+
+ BUGCTXT();
+ asm("or r9,r0, " DSKRD);
+ asm("tb0 0,r0,0x1F0");
+ asm("or %0,r0,r2" : "=r" (ret) : );
+ OSCTXT();
+
+ return ((ret&0x4) == 0x4 ? 1 : 0);
+}
+
+/* return 0 on success */
+
+bugdskwr(struct bugdisk_io *arg)
+{
+ int ret;
+ BUGCTXT();
+ asm("or r9,r0, " DSKWR);
+ asm("tb0 0,r0,0x1F0");
+ asm("or %0,r0,r2" : "=r" (ret) : );
+ OSCTXT();
+ return ((ret&0x4) == 0x4 ? 1 : 0);
+}
+
+bugrtcrd(struct bugrtc *rtc)
+{
+ BUGCTXT();
+ asm("or r9,r0, " RTC_RD);
+ asm("tb0 0,r0,0x1F0");
+ OSCTXT();
+}
+
+bugreturn(void)
+{
+ BUGCTXT();
+ asm("or r9,r0, " RETURN);
+ asm("tb0 0,r0,0x1F0");
+ OSCTXT();
+}
+
+bugbrdid(struct bugbrdid *id)
+{
+ struct bugbrdid *ptr;
+ BUGCTXT();
+ asm("or r9,r0, " BRD_ID);
+ asm("tb0 0,r0,0x1F0");
+ asm("or %0,r0,r2" : "=r" (ptr) : );
+ OSCTXT();
+ bcopy(ptr, id, sizeof(struct bugbrdid));
+}
+
+bugnetctrl(struct bugniocall *niocall)
+{
+ BUGCTXT();
+ asm("or r2,r0,%0" : : "r" (niocall));
+ asm("or r9,r0, " NETCTRL);
+ asm("tb0 0,r0,0x1F0");
+ OSCTXT();
+}
--- /dev/null
+/* $OpenBSD: cl.c,v 1.1.1.1 1997/03/03 19:32:04 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Dale Rahn. All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Dale Rahn.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* DMA mode still does not work!!! */
+
+#include <sys/param.h>
+#include <sys/callout.h>
+#include <sys/conf.h>
+#include <sys/ioctl.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/uio.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <sys/device.h>
+/* #include <sys/queue.h> */
+#include <machine/cpu.h>
+#include <machine/autoconf.h>
+#include <dev/cons.h>
+#if defined(MVME187)
+#include <mvme88k/dev/clreg.h>
+#else
+#include <mvme68k/dev/clreg.h>
+#endif
+#include <sys/syslog.h>
+#include "cl.h"
+
+#include "pcctwo.h"
+
+#if NPCCTWO > 0
+#if defined(MVME187)
+#include <mvme88k/dev/pcctworeg.h>
+#else
+#include <mvme68k/dev/pcctworeg.h>
+#endif
+#endif
+
+#if defined(MVME187)
+#include <machine/psl.h>
+#define splcl() splx(IPL_TTY)
+#else
+#define splcl() spl3()
+#endif
+
+/* min timeout 0xa, what is a good value */
+#define CL_TIMEOUT 0x10
+#define CL_FIFO_MAX 0x10
+#define CL_FIFO_CNT 0xc
+#define CL_RX_TIMEOUT 0x10
+
+#define CL_RXDMAINT 0x82
+#define CL_TXDMAINT 0x42
+#define CL_TXMASK 0x47
+#define CL_RXMASK 0x87
+#define CL_TXINTR 0x02
+#define CL_RXINTR 0x02
+
+struct cl_cons {
+ void *cl_paddr;
+ volatile struct clreg *cl_vaddr;
+ volatile struct pcc2reg *pcctwoaddr;
+ u_char channel;
+} cl_cons;
+
+struct cl_info {
+ struct tty *tty;
+ u_char cl_swflags;
+ u_char cl_softchar;
+ u_char cl_consio;
+ u_char cl_speed;
+ u_char cl_parstop; /* parity, stop bits. */
+ u_char cl_rxmode;
+ u_char cl_txmode;
+ u_char cl_clen;
+ u_char cl_parity;
+ u_char transmitting;
+ u_long txcnt;
+ u_long rxcnt;
+
+ void *rx[2];
+ void *rxp[2];
+ void *tx[2];
+ void *txp[2];
+};
+#define CLCD_PORTS_PER_CHIP 4
+#define CL_BUFSIZE 256
+
+#ifndef DO_MALLOC
+/* four (4) buffers per port */
+char cl_dmabuf [CLCD_PORTS_PER_CHIP * CL_BUFSIZE * 4];
+#endif
+
+struct clsoftc {
+ struct device sc_dev;
+ struct evcnt sc_txintrcnt;
+ struct evcnt sc_rxintrcnt;
+ struct evcnt sc_mxintrcnt;
+ time_t sc_rotime; /* time of last ring overrun */
+ time_t sc_fotime; /* time of last fifo overrun */
+ u_char *pbase;
+ struct clreg *cl_reg;
+ struct cl_info sc_cl[CLCD_PORTS_PER_CHIP];
+ struct intrhand sc_ih_e;
+ struct intrhand sc_ih_m;
+ struct intrhand sc_ih_t;
+ struct intrhand sc_ih_r;
+ struct pcc2reg *sc_pcctwo;
+ int sc_flags;
+};
+struct {
+ u_int speed;
+ u_char divisor;
+ u_char clock;
+ u_char rx_timeout;
+} cl_clocks[] = {
+ { 64000, 0x26, 0, 0x01},
+ { 56000, 0x2c, 0, 0x01},
+ { 38400, 0x40, 0, 0x01},
+ { 19200, 0x81, 0, 0x02},
+ { 9600, 0x40, 1, 0x04},
+ { 7200, 0x56, 1, 0x04},
+ { 4800, 0x81, 1, 0x08},
+ { 3600, 0xad, 1, 0x08},
+ { 2400, 0x40, 2, 0x10},
+ { 1200, 0x81, 2, 0x20},
+ { 600, 0x40, 3, 0x40},
+ { 300, 0x81, 3, 0x80},
+ { 150, 0x40, 3, 0x80},
+ { 110, 0x58, 4, 0xff},
+ { 50, 0xC2, 4, 0xff},
+ { 0, 0x00, 0, 0},
+};
+
+/* prototypes */
+int clcnprobe __P((struct consdev *cp));
+int clcninit __P((struct consdev *cp));
+int clcngetc __P((dev_t dev));
+int clcnputc __P((dev_t dev, u_char c));
+u_char cl_clkdiv __P((int speed));
+u_char cl_clknum __P((int speed));
+u_char cl_clkrxtimeout __P((int speed));
+void clstart __P((struct tty *tp));
+void cl_unblock __P((struct tty *tp));
+int clccparam __P((struct clsoftc *sc, struct termios *par, int channel));
+
+int clparam __P((struct tty *tp, struct termios *t));
+int cl_mintr __P((struct clsoftc *sc));
+int cl_txintr __P((struct clsoftc *sc));
+int cl_rxintr __P((struct clsoftc *sc));
+void cl_overflow __P((struct clsoftc *sc, int channel, long *ptime, u_char *msg));
+void cl_parity __P((struct clsoftc *sc, int channel));
+void cl_frame __P((struct clsoftc *sc, int channel));
+void cl_break __P(( struct clsoftc *sc, int channel));
+int clmctl __P((dev_t dev, int bits, int how));
+void cl_dumpport __P((int channel));
+
+int clprobe __P((struct device *parent, void *self, void *aux));
+void clattach __P((struct device *parent, struct device *self, void *aux));
+
+int clopen __P((dev_t dev, int flag, int mode, struct proc *p));
+int clclose __P((dev_t dev, int flag, int mode, struct proc *p));
+int clread __P((dev_t dev, struct uio *uio, int flag));
+int clwrite __P((dev_t dev, struct uio *uio, int flag));
+int clioctl __P((dev_t dev, int cmd, caddr_t data, int flag, struct proc *p));
+int clstop __P((struct tty *tp, int flag));
+
+static void cl_initchannel __P((struct clsoftc *sc, int channel));
+static void clputc __P((struct clsoftc *sc, int unit, u_char c));
+static u_char clgetc __P((struct clsoftc *sc, int *channel));
+static void cloutput __P( (struct tty *tp));
+
+struct cfattach cl_ca = {
+ sizeof(struct clsoftc), clprobe, clattach
+};
+
+struct cfdriver cl_cd = {
+ NULL, "cl", DV_TTY, 0
+};
+
+#define CLCDBUF 80
+
+int dopoll = 1;
+
+#define CL_UNIT(x) (minor(x) >> 2)
+#define CL_CHANNEL(x) (minor(x) & 3)
+#define CL_TTY(x) (minor(x))
+
+extern int cputyp;
+
+struct tty * cltty(dev)
+ dev_t dev;
+{
+ int unit, channel;
+ struct clsoftc *sc;
+ unit = CL_UNIT(dev);
+ if (unit >= cl_cd.cd_ndevs ||
+ (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
+ return (NULL);
+ }
+ channel = CL_CHANNEL(dev);
+ return sc->sc_cl[channel].tty;
+}
+
+int clprobe(parent, self, aux)
+ struct device *parent;
+ void *self;
+ void *aux;
+{
+ /* probing onboard 166/167/187 CL-cd2400
+ * should be previously configured,
+ * we can check the value before resetting the chip
+ */
+ struct clreg *cl_reg;
+ struct confargs *ca = aux;
+ register struct cfdata *cf = self;
+ caddr_t base;
+
+ int ret;
+#if 0
+ if (cputyp != CPU_167 && cputyp != CPU_166
+#ifdef CPU_187
+ && cputyp != CPU_187
+#endif
+ )
+ {
+ return 0;
+ }
+#endif /* 0 */
+ if (cputyp != CPU_187) {
+ return 0;
+ }
+
+ /*
+ * If bus or name do not match, fail.
+ */
+ if (ca->ca_bustype != BUS_PCCTWO ||
+ strcmp(cf->cf_driver->cd_name, "cl")) {
+ return 0;
+ }
+
+ base = (caddr_t)cf->cf_loc[0];
+
+ if (badpaddr(base, 1) == -1) {
+ return 0;
+ }
+
+ /*
+ * tell our parent our requirements
+ */
+ ca->ca_paddr = (caddr_t)CD2400_BASE_ADDR;
+ ca->ca_size = CD2400_SIZE;
+ ca->ca_ipl = IPL_TTY;
+
+ return 1;
+}
+
+void
+clattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct clsoftc *sc = (struct clsoftc *)self;
+ struct confargs *ca = aux;
+ int i;
+
+ sc->cl_reg = (struct clreg *)ca->ca_vaddr;
+ sc->sc_pcctwo = (struct pcc2reg *)ca->ca_parent;
+
+ if ((u_char *)ca->ca_paddr == (u_char *)cl_cons.cl_paddr) {
+ /* if this device is configured as console,
+ * line cl_cons.channel is the console */
+ sc->sc_cl[cl_cons.channel].cl_consio = 1;
+ printf(" console");
+ } else {
+ /* reset chip only if we are not console device */
+ /* wait for GFRCR */
+ }
+ /* set up global registers */
+ sc->cl_reg->cl_tpr = CL_TIMEOUT;
+ sc->cl_reg->cl_rpilr = 0x03;
+ sc->cl_reg->cl_tpilr = 0x02;
+ sc->cl_reg->cl_mpilr = 0x01;
+
+#ifdef DO_MALLOC
+ sc->sc_cl[0].rx[0] = (void *)(dvma_malloc(16 * CL_BUFSIZE));
+#else
+ sc->sc_cl[0].rx[0] = (void *) (&cl_dmabuf);
+#endif
+ sc->sc_cl[0].rx[1] = (void *)(((int)sc->sc_cl[0].rx[0]) + CL_BUFSIZE);
+ sc->sc_cl[1].rx[0] = (void *)(((int)sc->sc_cl[0].rx[1]) + CL_BUFSIZE);
+ sc->sc_cl[1].rx[1] = (void *)(((int)sc->sc_cl[1].rx[0]) + CL_BUFSIZE);
+
+ sc->sc_cl[2].rx[0] = (void *)(((int)sc->sc_cl[1].rx[1]) + CL_BUFSIZE);
+ sc->sc_cl[2].rx[1] = (void *)(((int)sc->sc_cl[2].rx[0]) + CL_BUFSIZE);
+ sc->sc_cl[3].rx[0] = (void *)(((int)sc->sc_cl[2].rx[1]) + CL_BUFSIZE);
+ sc->sc_cl[3].rx[1] = (void *)(((int)sc->sc_cl[3].rx[0]) + CL_BUFSIZE);
+
+ sc->sc_cl[0].tx[0] = (void *)(((int)sc->sc_cl[3].rx[1]) + CL_BUFSIZE);
+ sc->sc_cl[0].tx[1] = (void *)(((int)sc->sc_cl[0].tx[0]) + CL_BUFSIZE);
+ sc->sc_cl[1].tx[0] = (void *)(((int)sc->sc_cl[0].tx[1]) + CL_BUFSIZE);
+ sc->sc_cl[1].tx[1] = (void *)(((int)sc->sc_cl[1].tx[0]) + CL_BUFSIZE);
+
+ sc->sc_cl[2].tx[0] = (void *)(((int)sc->sc_cl[1].tx[1]) + CL_BUFSIZE);
+ sc->sc_cl[2].tx[1] = (void *)(((int)sc->sc_cl[2].tx[0]) + CL_BUFSIZE);
+ sc->sc_cl[3].tx[0] = (void *)(((int)sc->sc_cl[2].tx[1]) + CL_BUFSIZE);
+ sc->sc_cl[3].tx[1] = (void *)(((int)sc->sc_cl[3].tx[0]) + CL_BUFSIZE);
+ for (i = 0; i < CLCD_PORTS_PER_CHIP; i++) {
+ int j;
+#if 0
+ for (j = 0; j < 2 ; j++) {
+ sc->sc_cl[i].rxp[j] = (void *)kvtop(sc->sc_cl[i].rx[j]);
+ printf("cl[%d].rxbuf[%d] %x p %x\n",
+ i, j, sc->sc_cl[i].rx[j], sc->sc_cl[i].rxp[j]);
+ sc->sc_cl[i].txp[j] = (void *)kvtop(sc->sc_cl[i].tx[j]);
+ printf("cl[%d].txbuf[%d] %x p %x\n",
+ i, j, sc->sc_cl[i].tx[j], sc->sc_cl[i].txp[j]);
+ }
+#endif
+#if 0
+ sc->sc_cl[i].cl_rxmode =
+ !(!((flags >> (i * CL_FLAG_BIT_PCH)) & 0x01));
+ sc->sc_cl[i].cl_txmode =
+ !(!((flags >> (i * CL_FLAG_BIT_PCH)) & 0x02));
+ sc->sc_cl[i].cl_softchar =
+ !(!((flags >> (i * CL_FLAG_BIT_PCH)) & 0x04));
+#endif
+ cl_initchannel(sc, i);
+ }
+ /* enable interrupts */
+ sc->sc_ih_e.ih_fn = cl_rxintr;
+ sc->sc_ih_e.ih_arg = sc;
+ sc->sc_ih_e.ih_ipl = ca->ca_ipl;
+ sc->sc_ih_e.ih_wantframe = 0;
+
+ sc->sc_ih_m.ih_fn = cl_mintr;
+ sc->sc_ih_m.ih_arg = sc;
+ sc->sc_ih_m.ih_ipl = ca->ca_ipl;
+ sc->sc_ih_m.ih_wantframe = 0;
+
+ sc->sc_ih_t.ih_fn = cl_txintr;
+ sc->sc_ih_t.ih_arg = sc;
+ sc->sc_ih_t.ih_ipl = ca->ca_ipl;
+ sc->sc_ih_t.ih_wantframe = 0;
+
+ sc->sc_ih_r.ih_fn = cl_rxintr;
+ sc->sc_ih_r.ih_arg = sc;
+ sc->sc_ih_r.ih_ipl = ca->ca_ipl;
+ sc->sc_ih_r.ih_wantframe = 0;
+ switch (ca->ca_bustype) {
+ case BUS_PCCTWO:
+ dopoll = 0;
+ intr_establish(PCC2_VECT + SRXEIRQ, &sc->sc_ih_e);
+ intr_establish(PCC2_VECT + SMOIRQ, &sc->sc_ih_m);
+ intr_establish(PCC2_VECT + STxIRQ, &sc->sc_ih_t);
+ intr_establish(PCC2_VECT + SRxIRQ, &sc->sc_ih_r);
+ sc->sc_pcctwo = (struct pcc2reg *)ca->ca_parent;
+ sc->sc_pcctwo->pcc2_sccerrstat = 0x01; /* clear errors */
+
+ /* enable all interrupts at ca_ipl */
+ sc->sc_pcctwo->pcc2_sccmoirq = 0x10 | (ca->ca_ipl & 0x7);
+ sc->sc_pcctwo->pcc2_scctxirq = 0x10 | (ca->ca_ipl & 0x7);
+ sc->sc_pcctwo->pcc2_sccrxirq = 0x10 | (ca->ca_ipl & 0x7);
+ break;
+ default:
+ /* oops */
+ panic ("cl driver on unknown bus\n");
+ }
+
+ evcnt_attach(&sc->sc_dev, "intr", &sc->sc_txintrcnt);
+ evcnt_attach(&sc->sc_dev, "intr", &sc->sc_rxintrcnt);
+ evcnt_attach(&sc->sc_dev, "intr", &sc->sc_mxintrcnt);
+ printf("\n");
+}
+static void
+cl_initchannel(sc, channel)
+ struct clsoftc *sc;
+ int channel;
+{
+ int s;
+ struct clreg *cl_reg = sc->cl_reg;
+ /* set up option registers */
+ sc->sc_cl[channel].tty = NULL;
+ s = splhigh();
+ cl_reg->cl_car = (u_char) channel;
+ cl_reg->cl_livr = PCC2_VECT + 0xc;/* set vector base at 5C */
+ cl_reg->cl_ier = 0x00;
+ /* if the port is not the console, should be init for all ports??*/
+ if (sc->sc_cl[channel].cl_consio != 1) {
+ cl_reg->cl_cmr = 0x02;
+ cl_reg->cl_cor1 = 0x17;
+ cl_reg->cl_cor2 = 0x00;
+ cl_reg->cl_cor3 = 0x02;
+ cl_reg->cl_cor4 = 0xec;
+ cl_reg->cl_cor5 = 0xec;
+ cl_reg->cl_cor6 = 0x00;
+ cl_reg->cl_cor7 = 0x00;
+ cl_reg->cl_schr1 = 0x00;
+ cl_reg->cl_schr2 = 0x00;
+ cl_reg->cl_schr3 = 0x00;
+ cl_reg->cl_schr4 = 0x00;
+ cl_reg->cl_scrl = 0x00;
+ cl_reg->cl_scrh = 0x00;
+ cl_reg->cl_lnxt = 0x00;
+ cl_reg->cl_rbpr = 0x40; /* 9600 */
+ cl_reg->cl_rcor = 0x01;
+ cl_reg->cl_tbpr = 0x40; /* 9600 */
+ cl_reg->cl_tcor = 0x01 << 5;
+ /* console port should be 0x88 already */
+ cl_reg->cl_msvr_rts = 0x00;
+ cl_reg->cl_msvr_dtr = 0x00;
+ cl_reg->cl_rtprl = CL_RX_TIMEOUT;
+ cl_reg->cl_rtprh = 0x00;
+ }
+ sc->cl_reg->cl_ccr = 0x20;
+ while (sc->cl_reg->cl_ccr != 0) {
+ }
+
+ splx(s);
+}
+
+
+int cldefaultrate = TTYDEF_SPEED;
+
+int clmctl (dev, bits, how)
+ dev_t dev;
+ int bits;
+ int how;
+{
+ int s;
+ struct clsoftc *sc;
+ /* should only be called with valid device */
+ sc = (struct clsoftc *) cl_cd.cd_devs[CL_UNIT(dev)];
+ /*
+ printf("mctl: dev %x, bits %x, how %x,\n",dev, bits, how);
+ */
+ /* settings are currently ignored */
+ s = splcl();
+ switch (how) {
+ case DMSET:
+ if( bits & TIOCM_RTS) {
+ sc->cl_reg->cl_msvr_rts = 0x01;
+ } else {
+ sc->cl_reg->cl_msvr_rts = 0x00;
+ }
+ if( bits & TIOCM_DTR) {
+ sc->cl_reg->cl_msvr_dtr = 0x02;
+ } else {
+ sc->cl_reg->cl_msvr_dtr = 0x00;
+ }
+ break;
+
+ case DMBIC:
+ if( bits & TIOCM_RTS) {
+ sc->cl_reg->cl_msvr_rts = 0x00;
+ }
+ if( bits & TIOCM_DTR) {
+ sc->cl_reg->cl_msvr_dtr = 0x00;
+ }
+ break;
+
+ case DMBIS:
+ if( bits & TIOCM_RTS) {
+ sc->cl_reg->cl_msvr_rts = 0x01;
+ }
+ if( bits & TIOCM_DTR) {
+ sc->cl_reg->cl_msvr_dtr = 0x02;
+ }
+ break;
+
+ case DMGET:
+ bits = 0;
+
+ {
+ u_char msvr;
+ msvr = sc->cl_reg->cl_msvr_rts;
+ if( msvr & 0x80) {
+ bits |= TIOCM_DSR;
+ }
+ if( msvr & 0x40) {
+ bits |= TIOCM_CD;
+ }
+ if( msvr & 0x20) {
+ bits |= TIOCM_CTS;
+ }
+ if( msvr & 0x10) {
+ bits |= TIOCM_DTR;
+ }
+ if( msvr & 0x02) {
+ bits |= TIOCM_DTR;
+ }
+ if( msvr & 0x01) {
+ bits |= TIOCM_RTS;
+ }
+
+ }
+ break;
+ }
+ (void)splx(s);
+#if 0
+ bits = 0;
+ /* proper defaults? */
+ bits |= TIOCM_DTR;
+ bits |= TIOCM_RTS;
+ bits |= TIOCM_CTS;
+ bits |= TIOCM_CD;
+ /* bits |= TIOCM_RI; */
+ bits |= TIOCM_DSR;
+#endif
+
+ /*
+ printf("retbits %x\n", bits);
+ */
+ return(bits);
+}
+
+int clopen (dev, flag, mode, p)
+ dev_t dev;
+ int flag;
+ int mode;
+ struct proc *p;
+{
+ int s, unit, channel;
+ struct cl_info *cl;
+ struct clsoftc *sc;
+ struct tty *tp;
+
+ unit = CL_UNIT(dev);
+ if (unit >= cl_cd.cd_ndevs ||
+ (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
+ return (ENODEV);
+ }
+ channel = CL_CHANNEL(dev);
+ cl = &sc->sc_cl[channel];
+ s = splcl();
+ if (cl->tty) {
+ tp = cl->tty;
+ } else {
+ tp = cl->tty = ttymalloc();
+/* tty_attach(tp);*/
+ }
+ tp->t_oproc = clstart;
+ tp->t_param = clparam;
+ tp->t_dev = dev;
+
+ if ((tp->t_state & TS_ISOPEN) == 0) {
+ tp->t_state |= TS_WOPEN;
+ ttychars(tp);
+ if (tp->t_ispeed == 0) {
+ /*
+ * only when cleared do we reset to defaults.
+ */
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_lflag = TTYDEF_LFLAG;
+ tp->t_ispeed = tp->t_ospeed = cldefaultrate;
+
+ if(sc->sc_cl[channel].cl_consio == 1) {
+ /* console is 8N1 */
+ tp->t_cflag = (CREAD | CS8 | HUPCL);
+ } else {
+ tp->t_cflag = TTYDEF_CFLAG;
+ }
+ }
+ /*
+ * do these all the time
+ */
+ if (cl->cl_swflags & TIOCFLAG_CLOCAL)
+ tp->t_cflag |= CLOCAL;
+ if (cl->cl_swflags & TIOCFLAG_CRTSCTS)
+ tp->t_cflag |= CRTSCTS;
+ if (cl->cl_swflags & TIOCFLAG_MDMBUF)
+ tp->t_cflag |= MDMBUF;
+ clparam(tp, &tp->t_termios);
+ ttsetwater(tp);
+
+ (void)clmctl(dev, TIOCM_DTR | TIOCM_RTS, DMSET);
+#ifdef XXX
+ if ((cl->cl_swflags & TIOCFLAG_SOFTCAR) ||
+ (clmctl(dev, 0, DMGET) & TIOCM_CD)) {
+ tp->t_state |= TS_CARR_ON;
+ } else {
+ tp->t_state &= ~TS_CARR_ON;
+ }
+#endif
+ tp->t_state |= TS_CARR_ON;
+ {
+ u_char save = sc->cl_reg->cl_car;
+ sc->cl_reg->cl_car = channel;
+ sc->cl_reg->cl_ier = 0x88;
+#ifdef CL_DMA_WORKS
+ {
+ sc->cl_reg->cl_cmr =
+ /* CL_TXDMAINT | */ CL_RXDMAINT;
+ sc->cl_reg->cl_ier = 0xa8;
+ sc->cl_reg->cl_licr = 0x00;
+ }
+ sc->cl_reg->cl_arbadrl =
+ ((u_long)sc->sc_cl[channel].rxp[0]) & 0xffff;
+ sc->cl_reg->cl_arbadru =
+ ((u_long)sc->sc_cl[channel].rxp[0]) >> 16;
+ sc->cl_reg->cl_brbadrl =
+ ((u_long)sc->sc_cl[channel].rxp[1]) & 0xffff;
+ sc->cl_reg->cl_brbadru =
+ ((u_long)sc->sc_cl[channel].rxp[1]) >> 16;
+ sc->cl_reg->cl_atbadrl =
+ ((u_long)sc->sc_cl[channel].txp[0]) & 0xffff;
+ sc->cl_reg->cl_atbadru =
+ ((u_long)sc->sc_cl[channel].txp[0]) >> 16;
+ sc->cl_reg->cl_btbadrl =
+ ((u_long)sc->sc_cl[channel].txp[1]) & 0xffff;
+ sc->cl_reg->cl_btbadru =
+ ((u_long)sc->sc_cl[channel].txp[1]) >> 16;
+ sc->cl_reg->cl_arbcnt = CL_BUFSIZE;
+ sc->cl_reg->cl_brbcnt = CL_BUFSIZE;
+ sc->cl_reg->cl_arbsts = 0x01;
+ sc->cl_reg->cl_brbsts = 0x01;
+if (channel == 2) { /* test one channel now */
+ /* shift for tx DMA */
+ /* no shift for rx DMA */
+#if 0
+ /* tx only */
+ sc->cl_reg->cl_licr = (CL_DMAMODE << 4);
+ sc->cl_reg->cl_cmr = 0x42;
+#endif
+ /* rx only */
+ sc->cl_reg->cl_licr = 0x00;
+ sc->cl_reg->cl_cmr = 0x82;
+}
+ sc->cl_reg->cl_ccr = 0x20;
+ while (sc->cl_reg->cl_ccr != 0) {
+ }
+#endif /* CL_DMA_WORKS */
+ sc->cl_reg->cl_car = save;
+ }
+ } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
+ splx(s);
+ return(EBUSY);
+ }
+#ifdef XXX
+ /*
+ * if NONBLOCK requested, ignore carrier
+ */
+ if (flag & O_NONBLOCK)
+ goto done;
+#endif
+
+ splx(s);
+ /*
+ * Reset the tty pointer, as there could have been a dialout
+ * use of the tty with a dialin open waiting.
+ */
+ tp->t_dev = dev;
+#ifdef DEBUG
+ cl_dumpport(channel);
+#endif
+ return((*linesw[tp->t_line].l_open)(dev, tp));
+}
+int clparam(tp, t)
+ struct tty *tp;
+ struct termios *t;
+{
+ int unit, channel;
+ struct clsoftc *sc;
+ int s;
+ dev_t dev;
+
+ dev = tp->t_dev;
+ unit = CL_UNIT(dev);
+ if (unit >= cl_cd.cd_ndevs ||
+ (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
+ return (ENODEV);
+ }
+ channel = CL_CHANNEL(dev);
+ tp->t_ispeed = t->c_ispeed;
+ tp->t_ospeed = t->c_ospeed;
+ tp->t_cflag = t->c_cflag;
+ clccparam(sc, t, channel);
+ s = splcl();
+ cl_unblock(tp);
+ splx(s);
+ return 0;
+}
+
+void cloutput(tp)
+ struct tty *tp;
+{
+ int cc, s, unit, cnt;
+ u_char *tptr;
+ int channel;
+ struct clsoftc *sc;
+ dev_t dev;
+ u_char cl_obuffer[CLCDBUF+1];
+
+ dev = tp->t_dev;
+ unit = CL_UNIT(dev);
+ if (unit >= cl_cd.cd_ndevs ||
+ (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
+ return;
+ }
+ channel = CL_CHANNEL(dev);
+
+ if ((tp->t_state & TS_ISOPEN) == 0)
+ return;
+
+ s = splcl();
+ cc = tp->t_outq.c_cc;
+ while (cc > 0) {
+/*XXX*/
+ cnt = min (CLCDBUF,cc);
+ cnt = q_to_b(&tp->t_outq, cl_obuffer, cnt);
+ if (cnt == 0) {
+ break;
+ }
+ for (tptr = cl_obuffer; tptr < &cl_obuffer[cnt]; tptr++) {
+ clputc(sc, channel, *tptr);
+ }
+ cc -= cnt;
+ }
+ splx(s);
+}
+
+int clclose (dev, flag, mode, p)
+ dev_t dev;
+ int flag;
+ int mode;
+ struct proc *p;
+{
+ int unit, channel;
+ struct tty *tp;
+ struct cl_info *cl;
+ struct clsoftc *sc;
+ int s;
+ unit = CL_UNIT(dev);
+ if (unit >= cl_cd.cd_ndevs ||
+ (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
+ return (ENODEV);
+ }
+ channel = CL_CHANNEL(dev);
+ cl = &sc->sc_cl[channel];
+ tp = cl->tty;
+ (*linesw[tp->t_line].l_close)(tp, flag);
+
+ s = splcl();
+
+ sc->cl_reg->cl_car = channel;
+ if(cl->cl_consio == 0 && (tp->t_cflag & HUPCL) != 0) {
+ sc->cl_reg->cl_msvr_rts = 0x00;
+ sc->cl_reg->cl_msvr_dtr = 0x00;
+ sc->cl_reg->cl_ccr = 0x05;
+ }
+
+ splx(s);
+ ttyclose(tp);
+
+#if 0
+ cl->tty = NULL;
+#endif
+#ifdef DEBUG
+ cl_dumpport(channel);
+#endif
+
+ return 0;
+}
+int clread (dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+int flag;
+{
+ int unit, channel;
+ struct tty *tp;
+ struct cl_info *cl;
+ struct clsoftc *sc;
+ unit = CL_UNIT(dev);
+ if (unit >= cl_cd.cd_ndevs ||
+ (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
+ return (ENODEV);
+ }
+ channel = CL_CHANNEL(dev);
+ cl = &sc->sc_cl[channel];
+ tp = cl->tty;
+ if (!tp)
+ return ENXIO;
+ return((*linesw[tp->t_line].l_read)(tp, uio, flag));
+}
+int clwrite (dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ int unit, channel;
+ struct tty *tp;
+ struct cl_info *cl;
+ struct clsoftc *sc;
+ unit = CL_UNIT(dev);
+ if (unit >= cl_cd.cd_ndevs ||
+ (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
+ return (ENODEV);
+ }
+ channel = CL_CHANNEL(dev);
+ cl = &sc->sc_cl[channel];
+ tp = cl->tty;
+ if (!tp)
+ return ENXIO;
+ return((*linesw[tp->t_line].l_write)(tp, uio, flag));
+}
+int clioctl (dev, cmd, data, flag, p)
+ dev_t dev;
+ int cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ int error;
+ int unit, channel;
+ struct tty *tp;
+ struct cl_info *cl;
+ struct clsoftc *sc;
+ unit = CL_UNIT(dev);
+ if (unit >= cl_cd.cd_ndevs ||
+ (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
+ return (ENODEV);
+ }
+ channel = CL_CHANNEL(dev);
+ cl = &sc->sc_cl[channel];
+ tp = cl->tty;
+ if (!tp)
+ return ENXIO;
+
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return(error);
+
+ error = ttioctl(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return(error);
+
+ switch (cmd) {
+ case TIOCSBRK:
+ /* */
+ break;
+
+ case TIOCCBRK:
+ /* */
+ break;
+
+ case TIOCSDTR:
+ (void) clmctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIS);
+ break;
+
+ case TIOCCDTR:
+ (void) clmctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIC);
+ break;
+
+ case TIOCMSET:
+ (void) clmctl(dev, *(int *) data, DMSET);
+ break;
+
+ case TIOCMBIS:
+ (void) clmctl(dev, *(int *) data, DMBIS);
+ break;
+
+ case TIOCMBIC:
+ (void) clmctl(dev, *(int *) data, DMBIC);
+ break;
+
+ case TIOCMGET:
+ *(int *)data = clmctl(dev, 0, DMGET);
+ break;
+ case TIOCGFLAGS:
+ *(int *)data = cl->cl_swflags;
+ break;
+ case TIOCSFLAGS:
+ error = suser(p->p_ucred, &p->p_acflag);
+ if (error != 0)
+ return(EPERM);
+
+ cl->cl_swflags = *(int *)data;
+ cl->cl_swflags &= /* only allow valid flags */
+ (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS);
+ break;
+ default:
+ return(ENOTTY);
+ }
+
+ return 0;
+}
+int
+clstop(tp, flag)
+ struct tty *tp;
+ int flag;
+{
+ int s;
+
+ s = splcl();
+ if (tp->t_state & TS_BUSY) {
+ if ((tp->t_state & TS_TTSTOP) == 0)
+ tp->t_state |= TS_FLUSH;
+ }
+ splx(s);
+ return 0;
+}
+
+/*
+ * clcn* stuff happens before configure() runs kicking off
+ * autoconfig. Use a virtual mapping set up in locore till
+ * the device is actually configured. Need mappings for
+ * pcc2 space and Cirrus chip area.
+ */
+
+int
+clcnprobe(cp)
+ struct consdev *cp;
+{
+ /* always there ? */
+ /* serial major */
+ int maj;
+
+ /* locate the major number */
+ for (maj = 0; maj < nchrdev; maj++)
+ if (cdevsw[maj].d_open == clopen)
+ break;
+ cp->cn_dev = makedev (maj, 0);
+ cp->cn_pri = CN_NORMAL;
+
+ return 1;
+}
+
+int
+clcninit(cp)
+struct consdev *cp;
+{
+#if defined(MVME187)
+ volatile struct clreg *cl_reg;
+ extern vm_offset_t clconsvaddr, pcc2consvaddr;
+
+ cl_cons.cl_paddr = (void *)CD2400_BASE_ADDR;
+ cl_cons.cl_vaddr = (struct clreg *)CD2400_BASE_ADDR;
+ cl_cons.pcctwoaddr = (struct pcc2reg *)PCC2_BASE_ADDR;
+#else
+#ifdef MAP_DOES_WORK
+ int size = (0x1ff + PGOFSET) & ~PGOFSET;
+ int pcc2_size = (0x3C + PGOFSET) & ~PGOFSET;
+#endif
+ struct clreg *cl_reg;
+
+ cl_cons.cl_paddr = (void *)0xfff45000;
+#ifdef MAP_DOES_WORK
+ cl_cons.cl_vaddr = mapiodev(cl_cons.cl_paddr,size);
+ cd_pcc2_base = mapiodev(0xfff42000,pcc2_size);
+#else
+ cl_cons.cl_vaddr = (struct clreg *)IIOV(cl_cons.cl_paddr);
+ cl_cons.pcctwoaddr = (void *)IIOV(0xfff42000);
+#endif
+#endif /* defined(MVME187)
+ cl_reg = cl_cons.cl_vaddr;
+ /* reset the chip? */
+#ifdef CLCD_DO_RESET
+#endif
+ /* set up globals */
+#ifdef NOT_ALREADY_SETUP
+ cl_reg->cl_tftc = 0x10;
+ cl_reg->cl_tpr = CL_TIMEOUT; /* is this correct?? */
+ cl_reg->cl_rpilr = 0x03;
+ cl_reg->cl_tpilr = 0x02;
+ cl_reg->cl_mpilr = 0x01;
+
+ /* set up the tty00 to be 9600 8N1 */
+ cl_reg->cl_car = 0x00;
+ cl_reg->cl_cor1 = 0x17; /* No parity, ignore parity, 8 bit char */
+ cl_reg->cl_cor2 = 0x00;
+ cl_reg->cl_cor3 = 0x02; /* 1 stop bit */
+ cl_reg->cl_cor4 = 0x00;
+ cl_reg->cl_cor5 = 0x00;
+ cl_reg->cl_cor6 = 0x00;
+ cl_reg->cl_cor7 = 0x00;
+ cl_reg->cl_schr1 = 0x00;
+ cl_reg->cl_schr2 = 0x00;
+ cl_reg->cl_schr3 = 0x00;
+ cl_reg->cl_schr4 = 0x00;
+ cl_reg->cl_scrl = 0x00;
+ cl_reg->cl_scrh = 0x00;
+ cl_reg->cl_lnxt = 0x00;
+ cl_reg->cl_cpsr = 0x00;
+#endif
+ return 0;
+}
+
+int
+cl_instat(sc)
+ struct clsoftc *sc;
+{
+ volatile struct clreg *cl_reg;
+ if ( NULL == sc) {
+ cl_reg = cl_cons.cl_vaddr;
+ } else {
+ cl_reg = sc->cl_reg;
+ }
+ return (cl_reg->cl_rir & 0x40);
+}
+int
+clcngetc(dev)
+ dev_t dev;
+{
+ u_char val, reoir, licr, isrl, data, status, fifo_cnt;
+ int got_char = 0;
+ u_char ier_old = 0xff;
+ volatile struct clreg *cl_reg = cl_cons.cl_vaddr;
+ volatile struct pcc2reg *pcc2_base = cl_cons.pcctwoaddr;
+ cl_reg->cl_car = 0;
+ if (!(cl_reg->cl_ier & 0x08)) {
+ ier_old = cl_reg->cl_ier;
+ cl_reg->cl_ier = 0x08;
+ }
+ while (got_char == 0) {
+ val = cl_reg->cl_rir;
+ /* if no receive interrupt pending wait */
+ if (!(val & 0x80)) {
+ continue;
+ }
+ /* XXX do we need to suck the entire FIFO contents? */
+ reoir = pcc2_base->pcc2_sccrxpiack; /* receive PIACK */
+ licr = cl_reg->cl_licr;
+ if (((licr >> 2) & 0x3) == 0) {
+ /* is the interrupt for us (port 0) */
+ /* the character is for us yea. */
+ isrl = cl_reg->cl_risrl;
+#if 0
+ if (isrl & 0x01) {
+ status = BREAK;
+ }
+ if (isrl & 0x02) {
+ status = FRAME;
+ }
+ if (isrl & 0x04) {
+ status = PARITY;
+ }
+ if (isrl & 0x08) {
+ status = OVERFLOW;
+ }
+ /* we do not have special characters ;-) */
+#endif
+ fifo_cnt = cl_reg->cl_rfoc;
+ data = cl_reg->cl_rdr;
+ if (ier_old != 0xff) {
+ cl_reg->cl_ier = ier_old;
+ }
+ got_char = 1;
+ cl_reg->cl_teoir = 0x00;
+ } else {
+ data = cl_reg->cl_rdr;
+ cl_reg->cl_teoir = 0x00;
+ }
+ }
+
+ return data;
+}
+
+int
+clcnputc(dev, c)
+ dev_t dev;
+ u_char c;
+{
+ /* is this the correct location for the cr -> cr/lf tranlation? */
+ if (c == '\n')
+ clputc(0, 0, '\r');
+
+ clputc(0, 0, c);
+ return 0;
+}
+clcnpollc(dev, on)
+ dev_t dev;
+ int on;
+{
+ if (1 == on) {
+ /* enable polling */
+ } else {
+ /* disable polling */
+ }
+ return;
+}
+static void
+clputc(sc, unit, c)
+ struct clsoftc *sc;
+ int unit;
+ u_char c;
+{
+ int s;
+ u_char schar;
+ u_char oldchannel;
+ volatile struct clreg *cl_reg;
+ if (0 == sc) {
+ /* output on console */
+ cl_reg = cl_cons.cl_vaddr;
+ } else {
+ cl_reg = sc->cl_reg;
+ }
+#ifdef NEW_CLCD_STRUCT
+ /* should we disable, flush and all that goo? */
+ cl->car = unit;
+ schar = cl->schr3;
+ cl->schr3 = c;
+ cl->stcr = 0x08 | 0x03; /* send special char, char 3 */
+ while (0 != cl->stcr) {
+ /* wait until cl notices the command
+ * otherwise it may not notice the character
+ * if we send characters too fast.
+ */
+ }
+ cl->schr3 = schar;
+#else
+if (unit == 0) {
+ s = splhigh();
+ oldchannel = cl_reg->cl_car;
+ cl_reg->cl_car = unit;
+ schar = cl_reg->cl_schr3;
+ cl_reg->cl_schr3 = c;
+ cl_reg->cl_stcr = 0x08 | 0x03; /* send special char, char 3 */
+ while (0 != cl_reg->cl_stcr) {
+ /* wait until cl notices the command
+ * otherwise it may not notice the character
+ * if we send characters too fast.
+ */
+ }
+ DELAY(5);
+ cl_reg->cl_schr3 = schar;
+ cl_reg->cl_car = oldchannel;
+ splx(s);
+} else {
+ s = splhigh();
+ oldchannel = cl_reg->cl_car;
+ cl_reg->cl_car = unit;
+ if (cl_reg->cl_tftc > 0) {
+ cl_reg->cl_tdr = c;
+ }
+ cl_reg->cl_car = oldchannel;
+ splx(s);
+}
+#endif
+ return;
+}
+
+/*
+#ifdef CLCD_DO_POLLED_INPUT
+*/
+#if 1
+void
+cl_chkinput()
+{
+ struct tty *tp;
+ int unit;
+ struct clsoftc *sc;
+ int channel;
+
+ if (dopoll == 0)
+ return;
+ for (unit = 0; unit < cl_cd.cd_ndevs; unit++) {
+ if (unit >= cl_cd.cd_ndevs ||
+ (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
+ continue;
+ }
+ if (cl_instat(sc)) {
+ while (cl_instat(sc)){
+ int ch;
+ u_char c;
+ /*
+ *(pinchar++) = clcngetc();
+ */
+ ch = clgetc(sc,&channel) & 0xff;
+ c = ch;
+
+ tp = sc->sc_cl[channel].tty;
+ if (NULL != tp) {
+ (*linesw[tp->t_line].l_rint)(c,tp);
+ }
+ }
+ /*
+ wakeup(tp);
+ */
+ }
+ }
+}
+#endif
+static u_char
+clgetc(sc, channel)
+ struct clsoftc *sc;
+ int *channel;
+{
+ volatile struct clreg *cl_reg;
+ volatile struct pcc2reg *pcc2_base;
+ u_char val, reoir, licr, isrl, fifo_cnt, data;
+ if (0 == sc) {
+ cl_reg = cl_cons.cl_vaddr;
+ pcc2_base = cl_cons.pcctwoaddr;
+ } else {
+ cl_reg = sc->cl_reg;
+ pcc2_base = sc->sc_pcctwo;
+ }
+ val = cl_reg->cl_rir;
+ /* if no receive interrupt pending wait */
+ if (!(val & 0x80)) {
+ return 0;
+ }
+ /* XXX do we need to suck the entire FIFO contents? */
+ reoir = pcc2_base->pcc2_sccrxpiack; /* receive PIACK */
+ licr = cl_reg->cl_licr;
+ *channel = (licr >> 2) & 0x3;
+ /* is the interrupt for us (port 0) */
+ /* the character is for us yea. */
+ isrl = cl_reg->cl_risrl;
+#if 0
+ if (isrl & 0x01) {
+ status = BREAK;
+ }
+ if (isrl & 0x02) {
+ status = FRAME;
+ }
+ if (isrl & 0x04) {
+ status = PARITY;
+ }
+ if (isrl & 0x08) {
+ status = OVERFLOW;
+ }
+ /* we do not have special characters ;-) */
+#endif
+ fifo_cnt = cl_reg->cl_rfoc;
+ if (fifo_cnt > 0) {
+ data = cl_reg->cl_rdr;
+ cl_reg->cl_teoir = 0x00;
+ } else {
+ data = 0;
+ cl_reg->cl_teoir = 0x08;
+ }
+ return data;
+}
+int
+clccparam(sc, par, channel)
+ struct clsoftc *sc;
+ struct termios *par;
+ int channel;
+{
+ u_int divisor, clk, clen;
+ int s, imask, ints;
+
+ s = splcl();
+ sc->cl_reg->cl_car = channel;
+ if (par->c_ospeed == 0) {
+ /* dont kill the console */
+ if(sc->sc_cl[channel].cl_consio == 0) {
+ /* disconnect, drop RTS DTR stop reciever */
+ sc->cl_reg->cl_msvr_rts = 0x00;
+ sc->cl_reg->cl_msvr_dtr = 0x00;
+ sc->cl_reg->cl_ccr = 0x05;
+ }
+ splx(s);
+ return (0xff);
+ }
+
+ sc->cl_reg->cl_msvr_rts = 0x03;
+ sc->cl_reg->cl_msvr_dtr = 0x03;
+
+ divisor = cl_clkdiv(par->c_ospeed);
+ clk = cl_clknum(par->c_ospeed);
+ sc->cl_reg->cl_tbpr = divisor;
+ sc->cl_reg->cl_tcor = clk << 5;
+ divisor = cl_clkdiv(par->c_ispeed);
+ clk = cl_clknum(par->c_ispeed);
+ sc->cl_reg->cl_rbpr = divisor;
+ sc->cl_reg->cl_rcor = clk;
+ sc->cl_reg->cl_rtprl = cl_clkrxtimeout(par->c_ispeed);
+ sc->cl_reg->cl_rtprh = 0x00;
+
+ switch (par->c_cflag & CSIZE) {
+ case CS5:
+ clen = 4; /* this is the mask for the chip. */
+ imask = 0x1F;
+ break;
+ case CS6:
+ clen = 5;
+ imask = 0x3F;
+ break;
+ case CS7:
+ clen = 6;
+ imask = 0x7F;
+ break;
+ default:
+ clen = 7;
+ imask = 0xFF;
+ }
+ sc->cl_reg->cl_cor3 = par->c_cflag & PARENB ? 4 : 2;
+
+ {
+ u_char cor1;
+ if (par->c_cflag & PARENB) {
+ if (par->c_cflag & PARODD) {
+ cor1 = 0xE0 | clen ; /* odd */
+ } else {
+ cor1 = 0x40 | clen ; /* even */
+ }
+ } else {
+ cor1 = 0x10 | clen; /* ignore parity */
+ }
+ if (sc->cl_reg->cl_cor1 != cor1) {
+ sc->cl_reg->cl_cor1 = cor1;
+ sc->cl_reg->cl_ccr = 0x20;
+ while (sc->cl_reg->cl_ccr != 0) {
+ }
+ }
+ }
+
+ if (sc->sc_cl[channel].cl_consio == 0
+ && (par->c_cflag & CREAD) == 0 )
+ {
+ sc->cl_reg->cl_ccr = 0x08;
+ } else {
+ sc->cl_reg->cl_ccr = 0x0a;
+ }
+ while (sc->cl_reg->cl_ccr != 0) {
+ }
+ ints = 0;
+#define SCC_DSR 0x80
+#define SCC_DCD 0x40
+#define SCC_CTS 0x20
+ if ((par->c_cflag & CLOCAL) == 0) {
+ ints |= SCC_DCD;
+ }
+ if ((par->c_cflag & CCTS_OFLOW) != 0) {
+ ints |= SCC_CTS;
+ }
+ if ((par->c_cflag & CRTSCTS) != 0) {
+ ints |= SCC_CTS;
+ }
+#ifdef DONT_LET_HARDWARE
+ if ((par->c_cflag & CCTS_IFLOW) != 0) {
+ ints |= SCC_DSR;
+ }
+#endif
+ sc->cl_reg->cl_cor4 = ints | CL_FIFO_CNT;
+ sc->cl_reg->cl_cor5 = ints | CL_FIFO_CNT;
+
+ return imask;
+}
+static int clknum = 0;
+u_char
+cl_clkdiv(speed)
+ int speed;
+{
+ int i = 0;
+ if (cl_clocks[clknum].speed == speed) {
+ return cl_clocks[clknum].divisor;
+ }
+ for (i = 0; cl_clocks[i].speed != 0; i++) {
+ if (cl_clocks[i].speed == speed) {
+ clknum = i;
+ return cl_clocks[clknum].divisor;
+ }
+ }
+ /* return some sane value if unknown speed */
+ return cl_clocks[4].divisor;
+}
+u_char
+cl_clknum(speed)
+ int speed;
+{
+ int found = 0;
+ int i = 0;
+ if (cl_clocks[clknum].speed == speed) {
+ return cl_clocks[clknum].clock;
+ }
+ for (i = 0; found != 0 && cl_clocks[i].speed != 0; i++) {
+ if (cl_clocks[clknum].speed == speed) {
+ clknum = i;
+ return cl_clocks[clknum].clock;
+ }
+ }
+ /* return some sane value if unknown speed */
+ return cl_clocks[4].clock;
+}
+u_char
+cl_clkrxtimeout(speed)
+ int speed;
+{
+ int i = 0;
+ if (cl_clocks[clknum].speed == speed) {
+ return cl_clocks[clknum].rx_timeout;
+ }
+ for (i = 0; cl_clocks[i].speed != 0; i++) {
+ if (cl_clocks[i].speed == speed) {
+ clknum = i;
+ return cl_clocks[clknum].rx_timeout;
+ }
+ }
+ /* return some sane value if unknown speed */
+ return cl_clocks[4].rx_timeout;
+}
+void
+cl_unblock(tp)
+ struct tty *tp;
+{
+ tp->t_state &= ~TS_FLUSH;
+ if (tp->t_outq.c_cc != 0)
+ clstart(tp);
+}
+void
+clstart(tp)
+ struct tty *tp;
+{
+ dev_t dev;
+ u_char cbuf;
+ struct clsoftc *sc;
+ int channel, unit, s, cnt;
+
+ dev = tp->t_dev;
+ channel = CL_CHANNEL(dev);
+/* hack to test output on non console only */
+#if 0
+ if (channel == 0) {
+ cloutput(tp);
+ return;
+ }
+#endif
+ unit = CL_UNIT(dev);
+ if (unit >= cl_cd.cd_ndevs ||
+ (sc = (struct clsoftc *) cl_cd.cd_devs[unit]) == NULL) {
+ return;
+ }
+
+ if ((tp->t_state & TS_ISOPEN) == 0)
+ return;
+
+ s = splcl();
+#if 0
+ if (sc->sc_cl[channel].transmitting == 1) {
+ /* i'm busy, go away, I will get to it later. */
+ splx(s);
+ return;
+ }
+ cnt = q_to_b(&tp->t_outq, &cbuf, 1);
+ if ( cnt != 0 ) {
+ sc->sc_cl[channel].transmitting = 1;
+ sc->cl_reg->cl_car = channel;
+ sc->cl_reg->cl_tdr = cbuf;
+ } else {
+ sc->sc_cl[channel].transmitting = 0;
+ }
+#else
+ if ((tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP | TS_FLUSH)) == 0)
+ {
+ tp->t_state |= TS_BUSY;
+ sc->cl_reg->cl_car = channel;
+ sc->cl_reg->cl_ier = sc->cl_reg->cl_ier | 0x3;
+ }
+#endif
+ splx(s);
+ return;
+}
+int
+cl_mintr(sc)
+ struct clsoftc *sc;
+{
+ u_char mir, misr, msvr;
+ int channel;
+ struct tty *tp;
+ if(((mir = sc->cl_reg->cl_mir) & 0x40) == 0x0) {
+ /* only if intr is not shared? */
+ log(LOG_WARNING, "cl_mintr extra intr\n");
+ return 0;
+ }
+ sc->sc_mxintrcnt.ev_count++;
+
+ channel = mir & 0x03;
+ misr = sc->cl_reg->cl_misr;
+ msvr = sc->cl_reg->cl_msvr_rts;
+ if (misr & 0x01) {
+ /* timers are not currently used?? */
+ log(LOG_WARNING, "cl_mintr: channel %x timer 1 unexpected\n",channel);
+ }
+ if (misr & 0x02) {
+ /* timers are not currently used?? */
+ log(LOG_WARNING, "cl_mintr: channel %x timer 2 unexpected\n",channel);
+ }
+ if (misr & 0x20) {
+ log(LOG_WARNING, "cl_mintr: channel %x cts %x\n",channel,
+ ((msvr & 0x20) != 0x0)
+ );
+ }
+ if (misr & 0x40) {
+ struct tty *tp = sc->sc_cl[channel].tty;
+ log(LOG_WARNING, "cl_mintr: channel %x cd %x\n",channel,
+ ((msvr & 0x40) != 0x0)
+ );
+ ttymodem(tp, ((msvr & 0x40) != 0x0) );
+ }
+ if (misr & 0x80) {
+ log(LOG_WARNING, "cl_mintr: channel %x dsr %x\n",channel,
+ ((msvr & 0x80) != 0x0)
+ );
+ }
+ sc->cl_reg->cl_meoir = 0x00;
+ return 1;
+}
+
+int
+cl_txintr(sc)
+ struct clsoftc *sc;
+{
+ static empty = 0;
+ u_char tir, cmr, teoir;
+ u_char max;
+ int channel;
+ struct tty *tp;
+ int cnt;
+ u_char buffer[CL_FIFO_MAX +1];
+ u_char *tptr;
+ if(((tir = sc->cl_reg->cl_tir) & 0x40) == 0x0) {
+ /* only if intr is not shared ??? */
+ log(LOG_WARNING, "cl_txintr extra intr\n");
+ return 0;
+ }
+ sc->sc_txintrcnt.ev_count++;
+
+ channel = tir & 0x03;
+ cmr = sc->cl_reg->cl_cmr;
+
+ sc->sc_cl[channel].txcnt ++;
+
+ tp = sc->sc_cl[channel].tty;
+ if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0) {
+ sc->cl_reg->cl_ier = sc->cl_reg->cl_ier & ~0x3;
+ sc->cl_reg->cl_teoir = 0x08;
+ return 1;
+ }
+ switch (cmr & CL_TXMASK) {
+ case CL_TXDMAINT:
+ {
+ u_char dmabsts;
+ int nbuf, busy, resid;
+ void *pbuffer;
+ dmabsts = sc->cl_reg->cl_dmabsts;
+ log(LOG_WARNING, "cl_txintr: DMAMODE channel %x dmabsts %x\n",
+ channel, dmabsts);
+ nbuf = ((dmabsts & 0x8) >> 3) & 0x1;
+ busy = ((dmabsts & 0x4) >> 2) & 0x1;
+
+ do {
+ pbuffer = sc->sc_cl[channel].tx[nbuf];
+ resid = tp->t_outq.c_cc;
+ cnt = min (CL_BUFSIZE,resid);
+ log(LOG_WARNING, "cl_txintr: resid %x cnt %x pbuf %x\n",
+ resid, cnt, pbuffer);
+ if (cnt != 0) {
+ cnt = q_to_b(&tp->t_outq, pbuffer, cnt);
+ resid -= cnt;
+ if (nbuf == 0) {
+ sc->cl_reg->cl_atbadru =
+ ((u_long) sc->sc_cl[channel].txp[nbuf]) >> 16;
+ sc->cl_reg->cl_atbadrl =
+ ((u_long) sc->sc_cl[channel].txp[nbuf]) & 0xffff;
+ sc->cl_reg->cl_atbcnt = cnt;
+ sc->cl_reg->cl_atbsts = 0x43;
+ } else {
+ sc->cl_reg->cl_btbadru =
+ ((u_long) sc->sc_cl[channel].txp[nbuf]) >> 16;
+ sc->cl_reg->cl_btbadrl =
+ ((u_long) sc->sc_cl[channel].txp[nbuf]) & 0xffff;
+ sc->cl_reg->cl_btbcnt = cnt;
+ sc->cl_reg->cl_btbsts = 0x43;
+ }
+ teoir = 0x08;
+ } else {
+ teoir = 0x08;
+ if (tp->t_state & TS_BUSY) {
+ tp->t_state &= ~(TS_BUSY | TS_FLUSH);
+ if (tp->t_state & TS_ASLEEP) {
+ tp->t_state &= ~TS_ASLEEP;
+ wakeup((caddr_t) &tp->t_outq);
+ }
+ selwakeup(&tp->t_wsel);
+ }
+ sc->cl_reg->cl_ier = sc->cl_reg->cl_ier & ~0x3;
+ }
+ nbuf = ~nbuf & 0x1;
+ busy--;
+ } while (resid != 0 && busy != -1);/* if not busy do other buffer */
+ log(LOG_WARNING, "cl_txintr: done\n");
+ }
+ break;
+ case CL_TXINTR:
+ max = sc->cl_reg->cl_tftc;
+ cnt = min ((int)max,tp->t_outq.c_cc);
+ if (cnt != 0) {
+ cnt = q_to_b(&tp->t_outq, buffer, cnt);
+ empty = 0;
+ for (tptr = buffer; tptr < &buffer[cnt]; tptr++) {
+ sc->cl_reg->cl_tdr = *tptr;
+ }
+ teoir = 0x00;
+ } else {
+ if (empty > 5 && ((empty % 20000 )== 0)) {
+ log(LOG_WARNING, "cl_txintr to many empty intr %d channel %d\n",
+ empty, channel);
+ }
+ empty++;
+ teoir = 0x08;
+ if (tp->t_state & TS_BUSY) {
+ tp->t_state &= ~(TS_BUSY | TS_FLUSH);
+ if (tp->t_state & TS_ASLEEP) {
+ tp->t_state &= ~TS_ASLEEP;
+ wakeup((caddr_t) &tp->t_outq);
+ }
+ selwakeup(&tp->t_wsel);
+ }
+ sc->cl_reg->cl_ier = sc->cl_reg->cl_ier & ~0x3;
+ }
+ break;
+ default:
+ log(LOG_WARNING, "cl_txintr unknown mode %x\n", cmr);
+ /* we probably will go to hell quickly now */
+ teoir = 0x08;
+ }
+ sc->cl_reg->cl_teoir = teoir;
+ return 1;
+}
+
+int
+cl_rxintr(sc)
+ struct clsoftc *sc;
+{
+ u_char rir, channel, cmr, risrl;
+ u_char c;
+ u_char fifocnt;
+ struct tty *tp;
+ int i;
+ u_char reoir;
+ u_char buffer[CL_FIFO_MAX +1];
+#ifdef CONSOLEBREAKDDB
+ int wantddb = 0;
+#endif
+
+ rir = sc->cl_reg->cl_rir;
+ if((rir & 0x40) == 0x0) {
+ /* only if intr is not shared ??? */
+ log(LOG_WARNING, "cl_rxintr extra intr\n");
+ return 0;
+ }
+ sc->sc_rxintrcnt.ev_count++;
+ channel = rir & 0x3;
+ cmr = sc->cl_reg->cl_cmr;
+ reoir = 0x08;
+
+ sc->sc_cl[channel].rxcnt ++;
+ risrl = sc->cl_reg->cl_risrl;
+ if (risrl & 0x80) {
+ /* timeout, no characters */
+ reoir = 0x08;
+ } else
+ /* We don't need no sinkin special characters */
+ if (risrl & 0x08) {
+ cl_overflow (sc, channel, &sc->sc_fotime, "fifo");
+ reoir = 0x08;
+ } else
+ if (risrl & 0x04) {
+ cl_parity(sc, channel);
+ reoir = 0x08;
+ } else
+ if (risrl & 0x02) {
+ cl_frame(sc, channel);
+ reoir = 0x08;
+ } else
+ if (risrl & 0x01) {
+#ifdef CONSOLEBREAKDDB
+ if (sc->sc_cl[channel].cl_consio)
+ wantddb = 1;
+#endif
+ cl_break(sc, channel);
+ reoir = 0x08;
+ }
+
+ switch (cmr & CL_RXMASK) {
+ case CL_RXDMAINT:
+ {
+ int nbuf;
+ u_short cnt;
+ int bufcomplete;
+ u_char status, dmabsts;
+ u_char risrh = sc->cl_reg->cl_risrh;
+ dmabsts = sc->cl_reg->cl_dmabsts;
+#ifdef DMA_DEBUG
+log(LOG_WARNING, "cl_txintr: DMAMODE channel %x dmabsts %x risrl %x risrh %x\n",
+ channel, dmabsts, risrl, risrh);
+#endif
+ nbuf = (risrh & 0x08) ? 1 : 0;
+ bufcomplete = (risrh & 0x20) ? 1 : 0;
+ if (nbuf == 0) {
+ cnt = sc->cl_reg->cl_arbcnt;
+ status = sc->cl_reg->cl_arbsts;
+ } else {
+ cnt = sc->cl_reg->cl_brbcnt;
+ status = sc->cl_reg->cl_brbsts;
+ }
+#ifdef DMA_DEBUG
+log(LOG_WARNING, "cl_rxintr: 1channel %x buf %x cnt %x status %x\n",
+channel, nbuf, cnt, status);
+#endif
+#if USE_BUFFER
+ cl_appendbufn(sc, channel, sc->rx[nbuf], cnt);
+#else
+ {
+ int i;
+ u_char *pbuf;
+ tp = sc->sc_cl[channel].tty;
+ pbuf = sc->sc_cl[channel].rx[nbuf];
+ /* this should be done at off level */
+{
+ u_short rcbadru, rcbadrl;
+ u_char arbsts, brbsts;
+ u_char *pbufs, *pbufe;
+ rcbadru = sc->cl_reg->cl_rcbadru;
+ rcbadrl = sc->cl_reg->cl_rcbadrl;
+ arbsts = sc->cl_reg->cl_arbsts;
+ brbsts = sc->cl_reg->cl_brbsts;
+ pbufs = sc->sc_cl[channel].rxp[nbuf];
+ pbufe = (u_char *)(((u_long)rcbadru << 16) | (u_long)rcbadrl);
+ cnt = pbufe - pbufs;
+#ifdef DMA_DEBUG
+ log(LOG_WARNING, "cl_rxintr: rcbadru %x rcbadrl %x arbsts %x brbsts %x cnt %x\n",
+ rcbadru, rcbadrl, arbsts, brbsts, cnt);
+#endif
+#ifdef DMA_DEBUG1
+ log(LOG_WARNING, "cl_rxintr: buf %x cnt %x\n",
+ nbuf, cnt);
+#endif
+}
+ reoir = 0x0 | (bufcomplete) ? 0 : 0xd0;
+ sc->cl_reg->cl_reoir = reoir;
+#ifdef DMA_DEBUG
+log(LOG_WARNING, "cl_rxintr: reoir %x\n", reoir);
+#endif
+ delay(10); /* give the chip a moment */
+#ifdef DMA_DEBUG
+log(LOG_WARNING, "cl_rxintr: 2channel %x buf %x cnt %x status %x\n",
+channel, nbuf, cnt, status);
+#endif
+ for (i = 0; i < cnt; i++) {
+ u_char c;
+ c = pbuf[i];
+ (*linesw[tp->t_line].l_rint)(c,tp);
+ }
+ /* this should be done at off level */
+ if (nbuf == 0) {
+ sc->cl_reg->cl_arbcnt = CL_BUFSIZE;
+ sc->cl_reg->cl_arbsts = 0x01;
+ } else {
+ sc->cl_reg->cl_brbcnt = CL_BUFSIZE;
+ sc->cl_reg->cl_brbsts = 0x01;
+ }
+ }
+#endif
+ }
+ sc->cl_reg->cl_reoir = reoir;
+ break;
+ case CL_RXINTR:
+ fifocnt = sc->cl_reg->cl_rfoc;
+ tp = sc->sc_cl[channel].tty;
+ for (i = 0; i < fifocnt; i++) {
+ buffer[i] = sc->cl_reg->cl_rdr;
+ }
+ if (NULL == tp) {
+ /* if the channel is not configured,
+ * dont send characters upstream.
+ * also fix problem with NULL dereference
+ */
+ reoir = 0x00;
+ break;
+ }
+
+ sc->cl_reg->cl_reoir = reoir;
+ for (i = 0; i < fifocnt; i++) {
+ u_char c;
+ c = buffer[i];
+#if USE_BUFFER
+ cl_appendbuf(sc, channel, c);
+#else
+ /* does any restricitions exist on spl
+ * for this call
+ */
+ (*linesw[tp->t_line].l_rint)(c,tp);
+ reoir = 0x00;
+#endif
+ }
+ break;
+ default:
+ log(LOG_WARNING, "cl_rxintr unknown mode %x\n", cmr);
+ /* we probably will go to hell quickly now */
+ reoir = 0x08;
+ sc->cl_reg->cl_reoir = reoir;
+ }
+#ifdef CONSOLEBREAKDDB
+ if (wantddb)
+ Debugger();
+#endif
+ return 1;
+}
+
+void
+cl_overflow (sc, channel, ptime, msg)
+struct clsoftc *sc;
+int channel;
+long *ptime;
+u_char *msg;
+{
+/*
+ if (*ptime != time.tv_sec) {
+*/
+ {
+/*
+ *ptime = time.tv_sec;
+*/
+ log(LOG_WARNING, "%s%d[%d]: %s overrun\n", cl_cd.cd_name,
+ 0 /* fix */, channel, msg);
+ }
+ return;
+}
+void
+cl_parity (sc, channel)
+ struct clsoftc *sc;
+ int channel;
+{
+ log(LOG_WARNING, "%s%d[%d]: parity error\n", cl_cd.cd_name, 0, channel);
+ return;
+}
+void
+cl_frame (sc, channel)
+ struct clsoftc *sc;
+ int channel;
+{
+ log(LOG_WARNING, "%s%d[%d]: frame error\n", cl_cd.cd_name, 0, channel);
+ return;
+}
+void
+cl_break (sc, channel)
+ struct clsoftc *sc;
+ int channel;
+{
+ log(LOG_WARNING, "%s%d[%d]: break detected\n", cl_cd.cd_name, 0, channel);
+ return;
+}
+
+void
+cl_dumpport0()
+{
+ cl_dumpport(0);
+ return;
+}
+void
+cl_dumpport1()
+{
+ cl_dumpport(1);
+ return;
+}
+void
+cl_dumpport2()
+{
+ cl_dumpport(2);
+ return;
+}
+void
+cl_dumpport3()
+{
+ cl_dumpport(3);
+ return;
+}
+
+void
+cl_dumpport(channel)
+ int channel;
+{
+ u_char livr, cmr, cor1, cor2, cor3, cor4, cor5, cor6, cor7,
+ schr1, schr2, schr3, schr4, scrl, scrh, lnxt,
+ rbpr, rcor, tbpr, tcor, rpilr, rir, tpr, ier, ccr,
+ dmabsts, arbsts, brbsts, atbsts, btbsts,
+ csr, rts, dtr, rtprl, rtprh;
+ volatile void * parbadru, *parbadrl, *parbsts, *parbcnt;
+ u_short rcbadru, rcbadrl, arbadru, arbadrl, arbcnt,
+ brbadru, brbadrl, brbcnt;
+ u_short tcbadru, tcbadrl, atbadru, atbadrl, atbcnt,
+ btbadru, btbadrl, btbcnt;
+ struct clsoftc *sc;
+
+ volatile struct clreg *cl_reg;
+ int s;
+
+ cl_reg = cl_cons.cl_vaddr;
+
+ sc = (struct clsoftc *) cl_cd.cd_devs[0];
+
+ s = splcl();
+ cl_reg->cl_car = (u_char) channel;
+ livr = cl_reg->cl_livr;
+ cmr = cl_reg->cl_cmr;
+ cor1 = cl_reg->cl_cor1;
+ cor2 = cl_reg->cl_cor2;
+ cor3 = cl_reg->cl_cor3;
+ cor4 = cl_reg->cl_cor4;
+ cor5 = cl_reg->cl_cor5;
+ cor6 = cl_reg->cl_cor6;
+ cor7 = cl_reg->cl_cor7;
+ schr1 = cl_reg->cl_schr1;
+ schr2 = cl_reg->cl_schr2;
+ schr3 = cl_reg->cl_schr3;
+ schr4 = cl_reg->cl_schr4;
+ scrl = cl_reg->cl_scrl;
+ scrh = cl_reg->cl_scrh;
+ lnxt = cl_reg->cl_lnxt;
+ rbpr = cl_reg->cl_rbpr;
+ rcor = cl_reg->cl_rcor;
+ tbpr = cl_reg->cl_tbpr;
+ rpilr = cl_reg->cl_rpilr;
+ ier = cl_reg->cl_ier;
+ ccr = cl_reg->cl_ccr;
+ tcor = cl_reg->cl_tcor;
+ csr = cl_reg->cl_csr;
+ tpr = cl_reg->cl_tpr;
+ rts = cl_reg->cl_msvr_rts;
+ dtr = cl_reg->cl_msvr_dtr;
+ rtprl = cl_reg->cl_rtprl;
+ rtprh = cl_reg->cl_rtprh;
+ dmabsts = cl_reg->cl_dmabsts;
+ tcbadru = cl_reg->cl_tcbadru;
+ tcbadrl = cl_reg->cl_tcbadrl;
+ rcbadru = cl_reg->cl_rcbadru;
+ rcbadrl = cl_reg->cl_rcbadrl;
+
+ parbadru = &(cl_reg->cl_arbadru);
+ parbadrl = &(cl_reg->cl_arbadrl);
+ parbcnt = &(cl_reg->cl_arbcnt);
+ parbsts = &(cl_reg->cl_arbsts);
+
+ arbadru = cl_reg->cl_arbadru;
+ arbadrl = cl_reg->cl_arbadrl;
+ arbcnt = cl_reg->cl_arbcnt;
+ arbsts = cl_reg->cl_arbsts;
+
+ brbadru = cl_reg->cl_brbadru;
+ brbadrl = cl_reg->cl_brbadrl;
+ brbcnt = cl_reg->cl_brbcnt;
+ brbsts = cl_reg->cl_brbsts;
+
+ atbadru = cl_reg->cl_atbadru;
+ atbadrl = cl_reg->cl_atbadrl;
+ atbcnt = cl_reg->cl_atbcnt;
+ atbsts = cl_reg->cl_atbsts;
+
+ btbadru = cl_reg->cl_btbadru;
+ btbadrl = cl_reg->cl_btbadrl;
+ btbcnt = cl_reg->cl_btbcnt;
+ btbsts = cl_reg->cl_btbsts;
+
+ splx(s);
+
+ printf("{ port %x livr %x cmr %x\n",
+ channel,livr, cmr);
+ printf("cor1 %x cor2 %x cor3 %x cor4 %x cor5 %x cor6 %x cor7 %x\n",
+ cor1, cor2, cor3, cor4, cor5, cor6, cor7);
+ printf("schr1 %x schr2 %x schr3 %x schr4 %x\n",
+ schr1, schr2, schr3, schr4);
+ printf("scrl %x scrh %x lnxt %x\n",
+ scrl, scrh, lnxt);
+ printf("rbpr %x rcor %x tbpr %x tcor %x\n",
+ rbpr, rcor, tbpr, tcor);
+ printf("rpilr %x rir %x ier %x ccr %x\n",
+ rpilr, rir, ier, ccr);
+ printf("tpr %x csr %x rts %x dtr %x\n",
+ tpr, csr, rts, dtr);
+ printf("rtprl %x rtprh %x\n",
+ rtprl, rtprh);
+ printf("rxcnt %x txcnt %x\n",
+ sc->sc_cl[channel].rxcnt, sc->sc_cl[channel].txcnt);
+ printf("dmabsts %x, tcbadru %x, tcbadrl %x, rcbadru %x, rcbadrl %x,\n",
+ dmabsts, tcbadru, tcbadrl, rcbadru, rcbadrl );
+ printf("parbadru %x, parbadrl %x, parbcnt %x, parbsts %x\n",
+ parbadru, parbadrl, parbcnt, parbsts);
+ printf("arbadru %x, arbadrl %x, arbcnt %x, arbsts %x\n",
+ arbadru, arbadrl, arbcnt, arbsts);
+ printf("brbadru %x, brbadrl %x, brbcnt %x, brbsts %x\n",
+ brbadru, brbadrl, brbcnt, brbsts);
+ printf("atbadru %x, atbadrl %x, atbcnt %x, atbsts %x\n",
+ atbadru, atbadrl, atbcnt, atbsts);
+ printf("btbadru %x, btbadrl %x, btbcnt %x, btbsts %x\n",
+ btbadru, btbadrl, btbcnt, btbsts);
+ printf("}\n");
+ return;
+}
--- /dev/null
+/* $NetBSD: clockreg.h,v 1.5 1994/11/20 20:54:07 deraadt 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
+ */
+
+#include <machine/idprom.h>
+
+/*
+ * Sun-4/Sun-4c/Sun-4m clock Mostek TOD clock.
+ */
+
+/*
+ * Mostek MK48T02 clock.
+ *
+ * The clock includes 2040 bytes of RAM, the last 32 of which serve to
+ * identify the kind of Sun 4c this is.
+ *
+ * or, the Mostek MK48T08 clock.
+ *
+ * This is used in the Sun 4m machines. It is identical to the MK48T02,
+ * except for being 8K in size. The following structure, then, describes
+ * the last 2K of it's 8K address space. We simply ignore the first 6K..
+ */
+struct clockreg {
+ char cl_nvram[2008]; /* `free' nonvolatile memory */
+ struct idprom cl_idprom; /* `id prom' */
+ 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) */
+
+#define CLK_MK48T08_OFF 6*1024 /* struct clockreg is 6K forward */
+
+struct clockreg *clockreg;
+
+/*
+ * Sun chose the year `68' as their base count, so that
+ * cl_year==0 means 1968.
+ */
+#define YEAR0 68
--- /dev/null
+/* $NetBSD$ */
+/*
+ * Copyright (c) 1995 Dale Rahn. All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Dale Rahn.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+struct clreg {
+ volatile u_char anon1[0x7];
+ volatile u_char cl_cor7; /* 0x07 */
+ volatile u_char anon2[0x1];
+ volatile u_char cl_livr; /* 0x09 */
+ volatile u_char anon3[0x6];
+ volatile u_char cl_cor1; /* 0x10 */
+ volatile u_char cl_ier; /* 0x11 */
+ volatile u_char cl_stcr; /* 0x12 */
+ volatile u_char cl_ccr; /* 0x13 */
+ volatile u_char cl_cor5; /* 0x14 */
+ volatile u_char cl_cor4; /* 0x15 */
+ volatile u_char cl_cor3; /* 0x16 */
+ volatile u_char cl_cor2; /* 0x17 */
+ volatile u_char cl_cor6; /* 0x18 */
+ volatile u_char cl_dmabsts; /* 0x19 */
+ volatile u_char cl_csr; /* 0x1a */
+ volatile u_char cl_cmr; /* 0x1b */
+ volatile u_char cl_schr4; /* 0x1c */
+ volatile u_char cl_schr3; /* 0x1d */
+ volatile u_char cl_schr2; /* 0x1e */
+ volatile u_char cl_schr1; /* 0x1f */
+ volatile u_char anon5[0x2];
+ volatile u_char cl_scrh; /* 0x22 */
+ volatile u_char cl_scrl; /* 0x23 */
+#define cl_rtpr rtpr.rtpr_rtpr
+#define cl_rtprh rtpr.hl.rtpr_rtprh
+#define cl_rtprl rtpr.hl.rtpr_rtprl
+ union {
+ volatile u_short rtpr_rtpr; /* 0x24 */
+ struct {
+ volatile u_char rtpr_rtprh; /* 0x24 */
+ volatile u_char rtpr_rtprl; /* 0x25 */
+ }hl;
+ }rtpr;
+ volatile u_char cl_licr; /* 0x26 */
+ volatile u_char anon6[0x7];
+ volatile u_char cl_lnxt; /* 0x2e */
+ volatile u_char anon7[0x1];
+ volatile u_char cl_rfoc; /* 0x30 */
+ volatile u_char anon8[0x7];
+ volatile u_short cl_tcbadru; /* 0x38 */
+ volatile u_short cl_tcbadrl; /* 0x3a */
+ volatile u_short cl_rcbadru; /* 0x3c */
+ volatile u_short cl_rcbadrl; /* 0x3e */
+ volatile u_short cl_arbadru; /* 0x40 */
+ volatile u_short cl_arbadrl; /* 0x42 */
+ volatile u_short cl_brbadru; /* 0x44 */
+ volatile u_short cl_brbadrl; /* 0x46 */
+ volatile u_short cl_brbcnt; /* 0x48 */
+ volatile u_short cl_arbcnt; /* 0x4a */
+ volatile u_char anoni[0x2];
+ volatile u_char cl_brbsts; /* 0x4e */
+ volatile u_char cl_arbsts; /* 0x4f */
+#define cl_atbadr atbadr.atbadr
+#define cl_atbadru atbadr.hl.atbadru
+#define cl_atbadrl atbadr.hl.atbadrl
+ union {
+ struct {
+ volatile u_short atbadru; /* 0x50 */
+ volatile u_short atbadrl; /* 0x52 */
+ }hl;
+ volatile u_long atbadr; /* 0x50 */
+ }atbadr;
+#define cl_btbadr btbadr.btbadr
+#define cl_btbadru btbadr.hl.btbadru
+#define cl_btbadrl btbadr.hl.btbadrl
+ union {
+ struct {
+ volatile u_short btbadru; /* 0x54 */
+ volatile u_short btbadrl; /* 0x56 */
+ }hl;
+ volatile u_long btbadr; /* 0x54 */
+ }btbadr;
+ volatile u_short cl_btbcnt; /* 0x58 */
+ volatile u_short cl_atbcnt; /* 0x5a */
+ volatile u_char anono[0x2];
+ volatile u_char cl_btbsts; /* 0x5e */
+ volatile u_char cl_atbsts; /* 0x5f */
+ volatile u_char anonp[0x20];
+ volatile u_char cl_tftc; /* 0x80 */
+ volatile u_char cl_gfrcr; /* 0x81 */
+ volatile u_char anonq[0x2];
+ volatile u_char cl_reoir; /* 0x84 */
+ volatile u_char cl_teoir; /* 0x85 */
+ volatile u_char cl_meoir; /* 0x86 */
+ volatile u_char anonr[0x1];
+#define cl_risr risr.risr_risr
+#define cl_risrl risr.hl.risr_risrl
+#define cl_risrh risr.hl.risr_risrh
+ union {
+ volatile u_short risr_risr; /* 0x88 */
+ struct {
+ volatile u_char risr_risrh; /* 0x88 */
+ volatile u_char risr_risrl; /* 0x89 */
+ }hl;
+ }risr;
+ volatile u_char cl_tisr; /* 0x8a */
+ volatile u_char cl_misr; /* 0x8b */
+ volatile u_char anons[0x2];
+ volatile u_char cl_bercnt; /* 0x8e */
+ volatile u_char anont[0x31];
+ volatile u_char cl_tcor; /* 0xc0 */
+ volatile u_char anonu[0x2];
+ volatile u_char cl_tbpr; /* 0xc3 */
+ volatile u_char anonv[0x4];
+ volatile u_char cl_rcor; /* 0xc8 */
+ volatile u_char anonw[0x2];
+ volatile u_char cl_rbpr; /* 0xcb */
+ volatile u_char anonx[0xa];
+ volatile u_char cl_cpsr; /* 0xd6 */
+ volatile u_char anony[0x3];
+ volatile u_char cl_tpr; /* 0xda */
+ volatile u_char anonz[0x3];
+ volatile u_char cl_msvr_rts; /* 0xde */
+ volatile u_char cl_msvr_dtr; /* 0xdf */
+ volatile u_char cl_tpilr; /* 0xe0 */
+ volatile u_char cl_rpilr; /* 0xe1 */
+ volatile u_char cl_stk; /* 0xe2 */
+ volatile u_char cl_mpilr; /* 0xe3 */
+ volatile u_char anonA[0x8];
+ volatile u_char cl_tir; /* 0xec */
+ volatile u_char cl_rir; /* 0xed */
+ volatile u_char cl_car; /* 0xee */
+ volatile u_char cl_mir; /* 0xef */
+ volatile u_char anonB[0x6];
+ volatile u_char cl_dmr; /* 0xf6 */
+ volatile u_char anonC[0x1];
+#define cl_rdr cl_tdr
+ volatile u_char cl_tdr; /* 0xf8 */
+ volatile u_char anonD[7];
+};
+
+
+#define CD2400_SIZE 0x200
+
+/*
+ * Cirrus chip base address on the mvme1x7 boards.
+ */
+#define CD2400_BASE_ADDR 0xfff45000
--- /dev/null
+/* $Id: i82586.h,v 1.1.1.1 1997/03/03 19:32:07 rahnds Exp $ */
+
+/*-
+ * Copyright (c) 1995 Theo de Raadt
+ * Copyright (c) 1992, University of Vermont and State Agricultural College.
+ * Copyright (c) 1992, Garrett A. Wollman.
+ * 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
+ * Vermont and State Agricultural College and Garrett A. Wollman.
+ * and
+ * This product includes software developed under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 4. Neither the name of the University nor the name of the author
+ * 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 UNIVERSITY OR 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.
+ */
+
+/*
+ * Intel 82586 Ethernet chip
+ * Register, bit, and structure definitions.
+ *
+ * Written by GAW with reference to the Clarkson Packet Driver code for this
+ * chip written by Russ Nelson and others.
+ *
+ * Sun support added by Charles D. Cranor, 25-Oct-94
+ */
+
+struct ie_en_addr {
+ u_char data[6];
+};
+
+/*
+ * This is the master configuration block. It tells the hardware where all
+ * the rest of the stuff is.
+ */
+struct ie_sys_conf_ptr {
+ u_char mbz1[3]; /* must be zero */
+ u_char ie_bus_use; /* true if 8-bit only */
+ u_char mbz2[4]; /* must be zero */
+ caddr_t ie_iscp_ptr; /* 24-bit physaddr of ISCP */
+};
+
+/*
+ * The tells the hardware where all the rest of the stuff is, too.
+ * FIXME: some of these should be re-commented after we figure out their
+ * REAL function.
+ */
+struct ie_int_sys_conf_ptr {
+ u_char mbz1[1];
+ u_char ie_busy; /* zeroed after init */
+ u_short ie_scb_offset; /* 16-bit physaddr of next struct */
+ caddr_t ie_base; /* 24-bit physaddr for all 16-bit vars */
+};
+
+/*
+ * This FINALLY tells the hardware what to do and where to put it.
+ */
+struct ie_sys_ctl_block {
+ u_short ie_status; /* status word */
+ u_short ie_command; /* command word */
+ u_short ie_command_list; /* 16-pointer to command block list */
+ u_short ie_recv_list; /* 16-pointer to receive frame list */
+ u_short ie_err_crc; /* CRC errors */
+ u_short ie_err_align; /* Alignment errors */
+ u_short ie_err_resource; /* Resource errors */
+ u_short ie_err_overrun; /* Overrun errors */
+};
+
+/* Command values */
+#define IE_RU_COMMAND SWAP(0x0070) /* mask for RU command */
+#define IE_RU_NOP SWAP(0) /* for completeness */
+#define IE_RU_START SWAP(0x0010) /* start receive unit command */
+#define IE_RU_ENABLE SWAP(0x0020) /* enable receiver command */
+#define IE_RU_DISABLE SWAP(0x0030) /* disable receiver command */
+#define IE_RU_ABORT SWAP(0x0040) /* abort current receive operation */
+
+#define IE_CU_COMMAND SWAP(0x0700) /* mask for CU command */
+#define IE_CU_NOP SWAP(0) /* included for completeness */
+#define IE_CU_START SWAP(0x0100) /* do-command command */
+#define IE_CU_RESUME SWAP(0x0200) /* resume a suspended cmd list */
+#define IE_CU_STOP SWAP(0x0300) /* SUSPEND was already taken */
+#define IE_CU_ABORT SWAP(0x0400) /* abort current command */
+
+#define IE_ACK_COMMAND SWAP(0xf000) /* mask for ACK command */
+#define IE_ACK_CX SWAP(0x8000) /* ack IE_ST_DONE */
+#define IE_ACK_FR SWAP(0x4000) /* ack IE_ST_RECV */
+#define IE_ACK_CNA SWAP(0x2000) /* ack IE_ST_ALLDONE */
+#define IE_ACK_RNR SWAP(0x1000) /* ack IE_ST_RNR */
+
+#define IE_ACTION_COMMAND(x) (((x) & IE_CU_COMMAND) == IE_CU_START)
+ /* is this command an action command? */
+
+/* Status values */
+#define IE_ST_WHENCE SWAP(0xf000) /* mask for cause of interrupt */
+#define IE_ST_DONE SWAP(0x8000) /* command with I bit completed */
+#define IE_ST_RECV SWAP(0x4000) /* frame received */
+#define IE_ST_ALLDONE SWAP(0x2000) /* all commands completed */
+#define IE_ST_RNR SWAP(0x1000) /* receive not ready */
+
+#define IE_CU_STATUS SWAP(0x700) /* mask for command unit status */
+#define IE_CU_ACTIVE SWAP(0x200) /* command unit is active */
+#define IE_CU_SUSPEND SWAP(0x100) /* command unit is suspended */
+
+#define IE_RU_STATUS SWAP(0x70) /* mask for receiver unit status */
+#define IE_RU_SUSPEND SWAP(0x10) /* receiver is suspended */
+#define IE_RU_NOSPACE SWAP(0x20) /* receiver has no resources */
+#define IE_RU_READY SWAP(0x40) /* reveiver is ready */
+
+/*
+ * This is filled in partially by the chip, partially by us.
+ */
+struct ie_recv_frame_desc {
+ u_short ie_fd_status; /* status for this frame */
+ u_short ie_fd_last; /* end of frame list flag */
+ u_short ie_fd_next; /* 16-pointer to next RFD */
+ u_short ie_fd_buf_desc; /* 16-pointer to list of buffer desc's */
+ struct ie_en_addr dest; /* destination ether */
+ struct ie_en_addr src; /* source ether */
+ u_short ie_length; /* 802 length/Ether type */
+ u_short mbz; /* must be zero */
+};
+
+#define IE_FD_LAST SWAP(0x8000) /* last rfd in list */
+#define IE_FD_SUSP SWAP(0x4000) /* suspend RU after receipt */
+
+#define IE_FD_COMPLETE SWAP(0x8000) /* frame is complete */
+#define IE_FD_BUSY SWAP(0x4000) /* frame is busy */
+#define IE_FD_OK SWAP(0x2000) /* frame is bad */
+#define IE_FD_RNR SWAP(0x0200) /* receiver out of resources here */
+
+/*
+ * linked list of buffers...
+ */
+struct ie_recv_buf_desc {
+ u_short ie_rbd_actual; /* status for this buffer */
+ u_short ie_rbd_next; /* 16-pointer to next RBD */
+ caddr_t ie_rbd_buffer; /* 24-pointer to buffer for this RBD */
+ u_short ie_rbd_length; /* length of the buffer */
+ u_short mbz; /* must be zero */
+};
+
+#define IE_RBD_LAST SWAP(0x8000) /* last buffer */
+#define IE_RBD_USED SWAP(0x4000) /* this buffer has data */
+/*
+ * All commands share this in common.
+ */
+struct ie_cmd_common {
+ u_short ie_cmd_status; /* status of this command */
+ u_short ie_cmd_cmd; /* command word */
+ u_short ie_cmd_link; /* link to next command */
+};
+
+#define IE_STAT_COMPL SWAP(0x8000) /* command is completed */
+#define IE_STAT_BUSY SWAP(0x4000) /* command is running now */
+#define IE_STAT_OK SWAP(0x2000) /* command completed successfully */
+#define IE_STAT_ABORT SWAP(0x1000) /* command was aborted */
+
+
+#define IE_CMD_NOP SWAP(0x0000) /* NOP */
+#define IE_CMD_IASETUP SWAP(0x0001) /* initial address setup */
+#define IE_CMD_CONFIG SWAP(0x0002) /* configure command */
+#define IE_CMD_MCAST SWAP(0x0003) /* multicast setup command */
+#define IE_CMD_XMIT SWAP(0x0004) /* transmit command */
+#define IE_CMD_TDR SWAP(0x0005) /* time-domain reflectometer command */
+#define IE_CMD_DUMP SWAP(0x0006) /* dump command */
+#define IE_CMD_DIAGNOSE SWAP(0x0007) /* diagnostics command */
+
+#define IE_CMD_LAST SWAP(0x8000) /* this is the last command in the list */
+#define IE_CMD_SUSPEND SWAP(0x4000) /* suspend CU after this command */
+#define IE_CMD_INTR SWAP(0x2000) /* post an interrupt after completion */
+
+/*
+ * This is the command to transmit a frame.
+ */
+struct ie_xmit_cmd {
+ struct ie_cmd_common com; /* common part */
+#define ie_xmit_status com.ie_cmd_status
+
+ u_short ie_xmit_desc; /* 16-pointer to buffer descriptor */
+ struct ie_en_addr ie_xmit_addr; /* destination address */
+
+ u_short ie_xmit_length; /* 802.3 length/Ether type field */
+};
+
+#define IE_XS_MAXCOLL SWAP(0x000f) /* number of collisions during transmit */
+#define IE_XS_EXCMAX SWAP(0x0020) /* exceeded maximum number of collisions */
+#define IE_XS_SQE SWAP(0x0040) /* SQE positive */
+#define IE_XS_DEFERRED SWAP(0x0080) /* transmission deferred */
+#define IE_XS_UNDERRUN SWAP(0x0100) /* DMA underrun */
+#define IE_XS_LOSTCTS SWAP(0x0200) /* Lost CTS */
+#define IE_XS_NOCARRIER SWAP(0x0400) /* No Carrier */
+
+/*
+ * This is a buffer descriptor for a frame to be transmitted.
+ */
+
+struct ie_xmit_buf {
+ u_short ie_xmit_flags; /* see below */
+ u_short ie_xmit_next; /* 16-pointer to next desc. */
+ caddr_t ie_xmit_buf; /* 24-pointer to the actual buffer */
+};
+
+#define IE_XMIT_LAST SWAP(0x8000) /* this TBD is the last one */
+/* The rest of the `flags' word is actually the length. */
+
+/*
+ * Multicast setup command.
+ */
+
+#define MAXMCAST 250 /* must fit in transmit buffer */
+
+struct ie_mcast_cmd {
+ struct ie_cmd_common com; /* common part */
+#define ie_mcast_status com.ie_cmd_status
+
+ u_short ie_mcast_bytes; /* size (in bytes) of multicast addresses */
+ struct ie_en_addr ie_mcast_addrs[MAXMCAST + 1]; /* space for them */
+};
+
+/*
+ * Time Domain Reflectometer command.
+ */
+
+struct ie_tdr_cmd {
+ struct ie_cmd_common com; /* common part */
+#define ie_tdr_status com.ie_cmd_status
+
+ u_short ie_tdr_time; /* error bits and time */
+};
+
+#define IE_TDR_SUCCESS SWAP(0x8000) /* TDR succeeded without error */
+#define IE_TDR_XCVR SWAP(0x4000) /* detected a transceiver problem */
+#define IE_TDR_OPEN SWAP(0x2000) /* detected an open */
+#define IE_TDR_SHORT SWAP(0x1000) /* TDR detected a short */
+#define IE_TDR_TIME SWAP(0x07ff) /* mask for reflection time */
+
+/*
+ * Initial Address Setup command
+ */
+struct ie_iasetup_cmd {
+ struct ie_cmd_common com;
+#define ie_iasetup_status com.ie_cmd_status
+
+ struct ie_en_addr ie_address;
+};
+
+/*
+ * Configuration command
+ */
+struct ie_config_cmd {
+ struct ie_cmd_common com; /* common part */
+#define ie_config_status com.ie_cmd_status
+
+ u_char ie_config_count; /* byte count (0x0c) */
+ u_char ie_fifo; /* fifo (8) */
+ u_char ie_save_bad; /* save bad frames (0x40) */
+ u_char ie_addr_len; /* address length (0x2e) (AL-LOC == 1) */
+ u_char ie_priority; /* priority and backoff (0x0) */
+ u_char ie_ifs; /* inter-frame spacing (0x60) */
+ u_char ie_slot_low; /* slot time, LSB (0x0) */
+ u_char ie_slot_high; /* slot time, MSN, and retries (0xf2) */
+ u_char ie_promisc; /* 1 if promiscuous, else 0 */
+ u_char ie_crs_cdt; /* CSMA/CD parameters (0x0) */
+ u_char ie_min_len; /* min frame length (0x40) */
+ u_char ie_junk; /* stuff for 82596 (0xff) */
+};
--- /dev/null
+/* $Id: if_ie.c,v 1.1.1.1 1997/03/03 19:32:06 rahnds Exp $ */
+
+/*-
+ * Copyright (c) 1995 Theo de Raadt
+ * Copyright (c) 1993, 1994, 1995 Charles Hannum.
+ * Copyright (c) 1992, 1993, University of Vermont and State
+ * Agricultural College.
+ * Copyright (c) 1992, 1993, Garrett A. Wollman.
+ *
+ * Portions:
+ * Copyright (c) 1994, 1995, Rafal K. Boni
+ * Copyright (c) 1990, 1991, William F. Jolitz
+ * Copyright (c) 1990, 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 Charles Hannum, by the
+ * University of Vermont and State Agricultural College and Garrett A.
+ * Wollman, by William F. Jolitz, and by the University of California,
+ * Berkeley, Lawrence Berkeley Laboratory, and its contributors.
+ * and
+ * This product includes software developed under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 4. Neither the names of the Universities nor the names of the authors
+ * 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 UNIVERSITY OR AUTHORS 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.
+ */
+
+/*
+ * Intel 82586 Ethernet chip
+ * Register, bit, and structure definitions.
+ *
+ * Original StarLAN driver written by Garrett Wollman with reference to the
+ * Clarkson Packet Driver code for this chip written by Russ Nelson and others.
+ *
+ * BPF support code taken from hpdev/if_le.c, supplied with tcpdump.
+ *
+ * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni.
+ *
+ * Majorly cleaned up and 3C507 code merged by Charles Hannum.
+ *
+ * Converted to SUN ie driver by Charles D. Cranor,
+ * October 1994, January 1995.
+ * This sun version based on i386 version 1.30.
+ */
+
+extern void *etherbuf;
+extern int etherlen;
+
+/*
+Mode of operation:
+
+ We run the 82586 in a standard Ethernet mode. We keep NFRAMES
+ received frame descriptors around for the receiver to use, and
+ NRXBUF associated receive buffer descriptors, both in a circular
+ list. Whenever a frame is received, we rotate both lists as
+ necessary. (The 586 treats both lists as a simple queue.) We also
+ keep a transmit command around so that packets can be sent off
+ quickly.
+
+ We configure the adapter in AL-LOC = 1 mode, which means that the
+ Ethernet/802.3 MAC header is placed at the beginning of the receive
+ buffer rather than being split off into various fields in the RFD.
+ This also means that we must include this header in the transmit
+ buffer as well.
+
+ By convention, all transmit commands, and only transmit commands,
+ shall have the I (IE_CMD_INTR) bit set in the command. This way,
+ when an interrupt arrives at ieintr(), it is immediately possible
+ to tell what precisely caused it. ANY OTHER command-sending
+ routines should run at splnet(), and should post an acknowledgement
+ to every interrupt they generate.
+
+*/
+
+#include "bpfilter.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/buf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#include <sys/syslog.h>
+#include <sys/device.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/if_dl.h>
+#include <net/netisr.h>
+#include <net/route.h>
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#include <net/bpfdesc.h>
+#endif
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#endif
+
+#include <vm/vm.h>
+
+/*
+ * ugly byte-order hack for SUNs
+ */
+
+#define SWAP(x) (x)
+
+#include <machine/autoconf.h>
+#include <machine/cpu.h>
+#include <machine/pmap.h>
+
+#if !defined(MVME187)
+#include "mc.h"
+#endif
+#include "pcctwo.h"
+
+#if NMC > 0
+#include <mvme68k/dev/mcreg.h>
+#endif
+#if NPCCTWO > 0
+#if defined(MVME187)
+#include <mvme88k/dev/pcctworeg.h>
+#else
+#include <mvme68k/dev/pcctworeg.h>
+#endif
+#endif
+
+#include <mvme88k/dev/if_ie.h>
+#include <mvme88k/dev/i82586.h>
+#include <machine/board.h>
+
+static struct mbuf *last_not_for_us;
+vm_map_t ie_map; /* for obio */
+
+#define IED_RINT 0x01
+#define IED_TINT 0x02
+#define IED_RNR 0x04
+#define IED_CNA 0x08
+#define IED_READFRAME 0x10
+#define IED_ALL 0x1f
+
+#define ETHER_MIN_LEN 64
+#define ETHER_MAX_LEN 1518
+#define ETHER_ADDR_LEN 6
+
+#define B_PER_F 3 /* recv buffers per frame */
+#define MXFRAMES 300 /* max number of recv frames */
+#define MXRXBUF (MXFRAMES*B_PER_F) /* number of buffers to allocate */
+#define IE_RBUF_SIZE 256 /* size of each receive buffer;
+ MUST BE POWER OF TWO */
+#define NTXBUF 2 /* number of transmit commands */
+#define IE_TBUF_SIZE ETHER_MAX_LEN /* length of transmit buffer */
+
+
+/*
+ * Ethernet status, per interface.
+ *
+ * hardware addresses/sizes to know (all KVA):
+ * sc_iobase = base of chip's 24 bit address space
+ * sc_maddr = base address of chip RAM as stored in ie_base of iscp
+ * sc_msize = size of chip's RAM
+ * sc_reg = address of card dependent registers
+ *
+ * the chip uses two types of pointers: 16 bit and 24 bit
+ * 16 bit pointers are offsets from sc_maddr/ie_base
+ * KVA(16 bit offset) = offset + sc_maddr
+ * 24 bit pointers are offset from sc_iobase in KVA
+ * KVA(24 bit address) = address + sc_iobase
+ *
+ * on the vme/multibus we have the page map to control where ram appears
+ * in the address space. we choose to have RAM start at 0 in the
+ * 24 bit address space. this means that sc_iobase == sc_maddr!
+ * to get the phyiscal address of the board's RAM you must take the
+ * top 12 bits of the physical address of the register address
+ * and or in the 4 bits from the status word as bits 17-20 (remember that
+ * the board ignores the chip's top 4 address lines).
+ * For example:
+ * if the register is @ 0xffe88000, then the top 12 bits are 0xffe00000.
+ * to get the 4 bits from the the status word just do status & IEVME_HADDR.
+ * suppose the value is "4". Then just shift it left 16 bits to get
+ * it into bits 17-20 (e.g. 0x40000). Then or it to get the
+ * address of RAM (in our example: 0xffe40000). see the attach routine!
+ *
+ * on the onboard ie interface the 24 bit address space is hardwired
+ * to be 0xff000000 -> 0xffffffff of KVA. this means that sc_iobase
+ * will be 0xff000000. sc_maddr will be where ever we allocate RAM
+ * in KVA. note that since the SCP is at a fixed address it means
+ * that we have to allocate a fixed KVA for the SCP.
+ */
+
+struct ie_softc {
+ struct device sc_dev; /* device structure */
+ struct intrhand sc_ih, sc_failih; /* interrupt info */
+ struct evcnt sc_intrcnt; /* # of interrupts, per ie */
+
+ caddr_t sc_iobase; /* KVA of base of 24 bit addr space */
+ caddr_t sc_maddr; /* KVA of base of chip's RAM (16bit addr sp.)*/
+ u_int sc_msize; /* how much RAM we have/use */
+ caddr_t sc_reg; /* KVA of car's register */
+ int sc_bustype;
+
+ struct arpcom sc_arpcom;/* system arpcom structure */
+
+ void (*reset_586)(); /* card dependent reset function */
+ void (*chan_attn)(); /* card dependent attn function */
+ void (*run_586)(); /* card depenent "go on-line" function */
+ void (*memcopy) __P((const void *, void *, u_int));
+ /* card dependent memory copy function */
+ void (*memzero) __P((void *, u_int));
+ /* card dependent memory zero function */
+
+
+ int want_mcsetup; /* mcsetup flag */
+ int promisc; /* are we in promisc mode? */
+
+ /*
+ * pointers to the 3 major control structures
+ */
+
+ volatile struct ie_sys_conf_ptr *scp;
+ volatile struct ie_int_sys_conf_ptr *iscp;
+ volatile struct ie_sys_ctl_block *scb;
+
+ /*
+ * pointer and size of a block of KVA where the buffers
+ * are to be allocated from
+ */
+
+ caddr_t buf_area;
+ int buf_area_sz;
+
+ /*
+ * the actual buffers (recv and xmit)
+ */
+
+ volatile struct ie_recv_frame_desc *rframes[MXFRAMES];
+ volatile struct ie_recv_buf_desc *rbuffs[MXRXBUF];
+ volatile char *cbuffs[MXRXBUF];
+ int rfhead, rftail, rbhead, rbtail;
+
+ volatile struct ie_xmit_cmd *xmit_cmds[NTXBUF];
+ volatile struct ie_xmit_buf *xmit_buffs[NTXBUF];
+ u_char *xmit_cbuffs[NTXBUF];
+ int xmit_busy;
+ int xmit_free;
+ int xchead, xctail;
+
+ struct ie_en_addr mcast_addrs[MAXMCAST + 1];
+ int mcast_count;
+
+ int nframes; /* number of frames in use */
+ int nrxbuf; /* number of recv buffs in use */
+
+#ifdef IEDEBUG
+ int sc_debug;
+#endif
+#if NMC > 0
+ struct mcreg *sc_mc;
+#endif
+#if NPCCTWO > 0
+ struct pcc2reg *sc_pcc2;
+#endif
+};
+
+static void ie_obreset __P((struct ie_softc *));
+static void ie_obattend __P((struct ie_softc *));
+static void ie_obrun __P((struct ie_softc *));
+
+void iewatchdog __P((struct ifnet *));
+int ieintr __P((void *));
+int iefailintr __P((void *));
+int ieinit __P((struct ie_softc *));
+int ieioctl __P((struct ifnet *, u_long, caddr_t));
+void iestart __P((struct ifnet *));
+void iereset __P((struct ie_softc *));
+static void ie_readframe __P((struct ie_softc *, int));
+static void ie_drop_packet_buffer __P((struct ie_softc *));
+static int command_and_wait __P((struct ie_softc *, int,
+ void volatile *, int));
+/*static*/ void ierint __P((struct ie_softc *));
+/*static*/ void ietint __P((struct ie_softc *));
+static int ieget __P((struct ie_softc *, struct mbuf **,
+ struct ether_header *, int *));
+static void setup_bufs __P((struct ie_softc *));
+static int mc_setup __P((struct ie_softc *, void *));
+static void mc_reset __P((struct ie_softc *));
+
+#ifdef IEDEBUG
+void print_rbd __P((volatile struct ie_recv_buf_desc *));
+
+int in_ierint = 0;
+int in_ietint = 0;
+#endif
+
+int iematch();
+void ieattach();
+
+struct cfattach ie_ca = {
+ sizeof(struct ie_softc), iematch, ieattach
+};
+
+struct cfdriver ie_cd = {
+ NULL, "ie", DV_IFNET, 0
+};
+
+/*
+ * address generation macros
+ * MK_24 = KVA -> 24 bit address in SUN byte order
+ * MK_16 = KVA -> 16 bit address in INTEL byte order
+ * ST_24 = store a 24 bit address in SUN byte order to INTEL byte order
+ */
+
+#define MK_24(base, ptr) ((caddr_t)(((u_long)(ptr)) & 0x00ffffff))
+#define MK_16(base, ptr) SWAP((u_short)( ((u_long)(ptr)) - ((u_long)(base)) ))
+#define ST_24(to, from) { \
+ u_long fval = (u_long)(from); \
+ u_char *t = (u_char *)&(to), *f = (u_char *)&fval; \
+ t[0] = f[2]; t[1] = f[3]; t[2] = 0; t[3] = f[1]; \
+ }
+/*
+ * Here are a few useful functions. We could have done these as macros, but
+ * since we have the inline facility, it makes sense to use that instead.
+ */
+static inline void
+ie_setup_config(cmd, promiscuous, manchester)
+ volatile struct ie_config_cmd *cmd;
+ int promiscuous, manchester;
+{
+
+ cmd->ie_config_count = 0x0c;
+ cmd->ie_fifo = 8;
+ cmd->ie_save_bad = 0x40;
+ cmd->ie_addr_len = 0x2e;
+ cmd->ie_priority = 0;
+ cmd->ie_ifs = 0x60;
+ cmd->ie_slot_low = 0;
+ cmd->ie_slot_high = 0xf2;
+ cmd->ie_promisc = !!promiscuous | manchester << 2;
+ cmd->ie_crs_cdt = 0;
+ cmd->ie_min_len = 64;
+ cmd->ie_junk = 0xff;
+}
+
+static inline void
+ie_ack(sc, mask)
+ struct ie_softc *sc;
+ u_int mask;
+{
+ volatile struct ie_sys_ctl_block *scb = sc->scb;
+
+ command_and_wait(sc, scb->ie_status & mask, 0, 0);
+}
+
+int
+iematch(parent, vcf, args)
+ struct device *parent;
+ void *vcf, *args;
+{
+ struct cfdata *cf = vcf;
+ struct confargs *ca = args;
+
+#if defined(MVME187)
+ caddr_t base;
+ if (cputyp != CPU_187)
+ {
+ return 0;
+ }
+
+ /*
+ * If bus or name do not match, fail.
+ */
+ if (ca->ca_bustype != BUS_PCCTWO ||
+ strcmp(cf->cf_driver->cd_name, "ie")) {
+ return 0;
+ }
+
+ base = (caddr_t)cf->cf_loc[0];
+
+ if (badpaddr(base, 1) == -1) {
+ return 0;
+ }
+
+ /*
+ * tell our parent our requirements
+ */
+ ca->ca_paddr = (caddr_t)LANCE_ADDR;
+ ca->ca_size = 0x1000;
+ ca->ca_ipl = IPL_NET;
+
+ return 1;
+#else
+ return (!badvaddr(ca->ca_vaddr, 4));
+#endif
+}
+
+/*
+ * Deep Magic: reset it, then set SCP address again. Pray.
+ */
+void
+ie_obreset(sc)
+ struct ie_softc *sc;
+{
+ volatile struct ieob *ieo = (struct ieob *) sc->sc_reg;
+ volatile int t;
+ u_long a;
+ u_long b;
+
+ /*
+ * Convert a to the format the chip expects before writing
+ * the high and low (16 bit) words of the CPU port.
+ */
+ a = IE_PORT_RESET;
+ ST_24(b, a);
+ ieo->porthigh = b >> 16;
+ t = 0; t = 1;
+ ieo->portlow = b & 0xffff;
+ delay(1000);
+
+ a = (u_long)pmap_extract(pmap_kernel(), (vm_offset_t)sc->scp)
+ | IE_PORT_NEWSCPADDR;
+ ST_24(b, a);
+ ieo->porthigh = b >> 16;
+ t = 0; t = 1;
+ ieo->portlow = b & 0xffff;
+ delay(1000);
+}
+
+void
+ie_obattend(sc)
+ struct ie_softc *sc;
+{
+ volatile struct ieob *ieo = (struct ieob *) sc->sc_reg;
+
+ ieo->attn = 1;
+}
+
+void
+ie_obrun(sc)
+ struct ie_softc *sc;
+{
+}
+
+/*
+ * Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
+ */
+void
+ieattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct ie_softc *sc = (void *) self;
+ struct confargs *ca = aux;
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ extern void myetheraddr(u_char *); /* should be elsewhere */
+ register struct bootpath *bp;
+ int pri = ca->ca_ipl;
+ volatile struct ieob *ieo;
+ vm_offset_t pa;
+
+ sc->reset_586 = ie_obreset;
+ sc->chan_attn = ie_obattend;
+ sc->run_586 = ie_obrun;
+ sc->memcopy = bcopy;
+ sc->memzero = bzero;
+ sc->sc_msize = etherlen;
+ sc->sc_reg = ca->ca_vaddr;
+ ieo = (volatile struct ieob *) sc->sc_reg;
+
+#if XXXX
+ /* Don't know what this yet XXX nivas */
+ /* Are we the boot device? */
+ if (ca->ca_paddr == bootaddr)
+ bootdv = self;
+#endif
+
+#if 0
+ sc->sc_maddr = etherbuf; /* maddr = vaddr */
+ pa = pmap_extract(pmap_kernel(), (vm_offset_t)sc->sc_maddr);
+ if (pa == 0) panic("ie pmap_extract");
+ sc->sc_iobase = (caddr_t)pa; /* iobase = paddr (24 bit) */
+
+ /*printf("maddrP %x iobaseV %x\n", sc->sc_maddr, sc->sc_iobase);*/
+
+ (sc->memzero)(sc->sc_maddr, sc->sc_msize);
+ sc->iscp = (volatile struct ie_int_sys_conf_ptr *)
+ sc->sc_maddr; /* @ location zero */
+ sc->scb = (volatile struct ie_sys_ctl_block *)
+ roundup((int)sc->iscp + sizeof(struct ie_int_sys_conf_ptr), 16);
+ sc->scp = (struct ie_sys_conf_ptr *)
+ roundup((int)sc->scb + sizeof(struct ie_sys_ctl_block), 16);
+ /*printf("scpV %x iscpV %x scbV %x\n", sc->scp, sc->iscp, sc->scb);*/
+
+ sc->scp->ie_bus_use = 0; /* 16-bit */
+#endif /* 0 */
+ sc->sc_maddr = etherbuf; /* maddr = vaddr */
+ pa = pmap_extract(pmap_kernel(), (vm_offset_t)sc->sc_maddr);
+ if (pa == 0) panic("ie pmap_extract");
+ sc->sc_iobase = (caddr_t)pa; /* iobase = paddr (24 bit) */
+
+ (sc->memzero)(sc->sc_maddr, sc->sc_msize);
+
+ sc->scb = (volatile struct ie_sys_ctl_block *)
+ sc->sc_maddr; /* @ location zero */
+ sc->scp = (struct ie_sys_conf_ptr *)
+ roundup((int)sc->scb + sizeof(struct ie_sys_ctl_block), 16);
+ sc->iscp = (volatile struct ie_int_sys_conf_ptr *)
+ roundup((int)sc->scp + sizeof(struct ie_sys_conf_ptr), 16);
+
+ /*printf("maddrV %x iobaseP %x\n", sc->sc_maddr, sc->sc_iobase);*/
+ /*printf("scpV %x iscpV %x scbV %x\n", sc->scp, sc->iscp, sc->scb);*/
+
+ /*
+ * init scp; iscp will be inited later in ie_setupram().
+ */
+ sc->scp->ie_bus_use = 0; /* 8-bit */
+ ST_24(sc->scp->ie_iscp_ptr,
+ pmap_extract(pmap_kernel(), (vm_offset_t)sc->iscp));
+
+ /*printf("iscpV(%x) = iscpP(%x) -> scp.ptr@%x = val:%x\n",
+ sc->iscp, pmap_extract(pmap_kernel(), (vm_offset_t)sc->iscp),
+ &sc->scp->ie_iscp_ptr, sc->scp->ie_iscp_ptr);*/
+
+ /*
+ * rest of first page is unused (wasted!), rest of ram
+ * for buffers
+ */
+ sc->buf_area = sc->sc_maddr + NBPG;
+ sc->buf_area_sz = sc->sc_msize - NBPG;
+ myetheraddr(sc->sc_arpcom.ac_enaddr);
+
+ if (ie_setupram(sc) == 0) {
+ printf(": RAM CONFIG FAILED!\n");
+ /* XXX should reclaim resources? */
+ return;
+ }
+ bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
+ ifp->if_softc = sc;
+ ifp->if_start = iestart;
+ ifp->if_ioctl = ieioctl;
+ ifp->if_watchdog = iewatchdog;
+ ifp->if_flags =
+ IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
+
+ /* Attach the interface. */
+ if_attach(ifp);
+ ether_ifattach(ifp);
+
+ printf(": address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
+
+#if NBPFILTER > 0
+ bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
+#endif
+
+ sc->sc_bustype = ca->ca_bustype;
+
+ sc->sc_ih.ih_fn = ieintr;
+ sc->sc_ih.ih_arg = sc;
+ sc->sc_ih.ih_ipl = pri;
+ sc->sc_failih.ih_fn = iefailintr;
+ sc->sc_failih.ih_arg = sc;
+ sc->sc_failih.ih_ipl = pri;
+
+ switch (sc->sc_bustype) {
+#if NMC > 0
+ case BUS_MC:
+ mcintr_establish(MCV_IE, &sc->sc_ih);
+ sc->sc_mc = (struct mcreg *)ca->ca_master;
+ sc->sc_mc->mc_ieirq = pri | MC_SC_SNOOP | MC_IRQ_IEN |
+ MC_IRQ_ICLR;
+ mcintr_establish(MCV_IEFAIL, &sc->sc_failih);
+ sc->sc_mc->mc_iefailirq = pri | MC_IRQ_IEN | MC_IRQ_ICLR;
+ break;
+#endif
+#if NPCCTWO > 0
+ case BUS_PCCTWO:
+
+ intr_establish(PCC2_VECT + LANCIRQ, &sc->sc_ih);
+ sc->sc_pcc2 = (struct pcc2reg *)ca->ca_parent;
+ sc->sc_pcc2->pcc2_lancirq = pri |
+ PCC2_IRQ_IEN | PCC2_IRQ_ICLR;
+ intr_establish(PCC2_VECT + LANCERR, &sc->sc_failih);
+ sc->sc_pcc2->pcc2_lancerrirq = pri | PCC2_IRQ_IEN |
+ PCC2_IRQ_ICLR;
+ break;
+#endif
+ }
+
+ evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt);
+}
+
+/*
+ * Device timeout/watchdog routine. Entered if the device neglects to generate
+ * an interrupt after a transmit has been started on it.
+ */
+void
+iewatchdog(ifp)
+ struct ifnet *ifp;
+{
+ struct ie_softc *sc = ifp->if_softc;
+
+ log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
+ ++sc->sc_arpcom.ac_if.if_oerrors;
+
+ iereset(sc);
+}
+
+int
+iefailintr(v)
+void *v;
+{
+ struct ie_softc *sc = v;
+
+ switch (sc->sc_bustype) {
+#if NMC > 0
+ case BUS_MC:
+ sc->sc_mc->mc_ieirq |= MC_IRQ_ICLR; /* safe: clear irq */
+ sc->sc_mc->mc_iefailirq |= MC_IRQ_ICLR; /* clear failure */
+ sc->sc_mc->mc_ieerr = MC_IEERR_SCLR; /* reset error */
+ break;
+#endif
+#if NPCCTWO > 0
+ case BUS_PCCTWO:
+ sc->sc_pcc2->pcc2_lancirq |= PCC2_IRQ_ICLR; /* safe: clear irq */
+ sc->sc_pcc2->pcc2_lancerrirq |= PCC2_IRQ_ICLR; /* clear failure */
+ sc->sc_pcc2->pcc2_lancerrstat = PCC2_IEERR_SCLR; /* reset error */
+ break;
+#endif
+ }
+
+ iereset(sc);
+ return (1);
+}
+
+/*
+ * What to do upon receipt of an interrupt.
+ */
+int
+ieintr(v)
+void *v;
+{
+ struct ie_softc *sc = v;
+ register u_short status;
+
+ status = sc->scb->ie_status;
+/*printf("I");*/
+
+loop:
+ /* Ack interrupts FIRST in case we receive more during the ISR. */
+ ie_ack(sc, IE_ST_WHENCE & status);
+ switch (sc->sc_bustype) {
+#if NMC > 0
+ case BUS_MC:
+ sc->sc_mc->mc_ieirq |= MC_IRQ_ICLR; /* clear irq */
+ break;
+#endif
+#if NPCCTWO > 0
+ case BUS_PCCTWO:
+ sc->sc_pcc2->pcc2_lancirq |= PCC2_IRQ_ICLR; /* clear irq */
+ break;
+#endif
+ }
+
+ if (status & (IE_ST_RECV | IE_ST_RNR)) {
+#ifdef IEDEBUG
+ in_ierint++;
+ if (sc->sc_debug & IED_RINT)
+ printf("%s: rint\n", sc->sc_dev.dv_xname);
+#endif
+ ierint(sc);
+#ifdef IEDEBUG
+ in_ierint--;
+#endif
+ }
+
+ if (status & IE_ST_DONE) {
+#ifdef IEDEBUG
+ in_ietint++;
+ if (sc->sc_debug & IED_TINT)
+ printf("%s: tint\n", sc->sc_dev.dv_xname);
+#endif
+ ietint(sc);
+#ifdef IEDEBUG
+ in_ietint--;
+#endif
+ }
+
+ if (status & IE_ST_RNR) {
+ printf("%s: receiver not ready\n", sc->sc_dev.dv_xname);
+ sc->sc_arpcom.ac_if.if_ierrors++;
+ iereset(sc);
+ }
+
+#ifdef IEDEBUG
+ if ((status & IE_ST_ALLDONE) && (sc->sc_debug & IED_CNA))
+ printf("%s: cna\n", sc->sc_dev.dv_xname);
+#endif
+
+ if ((status = sc->scb->ie_status) & IE_ST_WHENCE)
+ goto loop;
+
+ sc->sc_intrcnt.ev_count++;
+ return 1;
+}
+
+/*
+ * Process a received-frame interrupt.
+ */
+void
+ierint(sc)
+ struct ie_softc *sc;
+{
+ volatile struct ie_sys_ctl_block *scb = sc->scb;
+ int i, status;
+ static int timesthru = 1024;
+
+ i = sc->rfhead;
+ for (;;) {
+ status = sc->rframes[i]->ie_fd_status;
+
+ if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
+ sc->sc_arpcom.ac_if.if_ipackets++;
+ if (!--timesthru) {
+ sc->sc_arpcom.ac_if.if_ierrors +=
+ SWAP(scb->ie_err_crc) +
+ SWAP(scb->ie_err_align) +
+ SWAP(scb->ie_err_resource) +
+ SWAP(scb->ie_err_overrun);
+ scb->ie_err_crc = scb->ie_err_align =
+ scb->ie_err_resource = scb->ie_err_overrun =
+ 0;
+ timesthru = 1024;
+ }
+ ie_readframe(sc, i);
+ } else {
+ if ((status & IE_FD_RNR) != 0 &&
+ (scb->ie_status & IE_RU_READY) == 0) {
+ sc->rframes[0]->ie_fd_buf_desc =
+ MK_16(sc->sc_maddr, sc->rbuffs[0]);
+ scb->ie_recv_list =
+ MK_16(sc->sc_maddr, sc->rframes[0]);
+ command_and_wait(sc, IE_RU_START, 0, 0);
+ }
+ break;
+ }
+ i = (i + 1) % sc->nframes;
+ }
+}
+
+/*
+ * Process a command-complete interrupt. These are only generated by the
+ * transmission of frames. This routine is deceptively simple, since most of
+ * the real work is done by iestart().
+ */
+void
+ietint(sc)
+ struct ie_softc *sc;
+{
+ int status;
+
+ sc->sc_arpcom.ac_if.if_timer = 0;
+ sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
+
+ status = sc->xmit_cmds[sc->xctail]->ie_xmit_status;
+
+ if (!(status & IE_STAT_COMPL) || (status & IE_STAT_BUSY))
+ printf("ietint: command still busy!\n");
+
+ if (status & IE_STAT_OK) {
+ sc->sc_arpcom.ac_if.if_opackets++;
+ sc->sc_arpcom.ac_if.if_collisions +=
+ SWAP(status & IE_XS_MAXCOLL);
+ } else if (status & IE_STAT_ABORT) {
+ printf("%s: send aborted\n", sc->sc_dev.dv_xname);
+ sc->sc_arpcom.ac_if.if_oerrors++;
+ } else if (status & IE_XS_NOCARRIER) {
+ printf("%s: no carrier\n", sc->sc_dev.dv_xname);
+ sc->sc_arpcom.ac_if.if_oerrors++;
+ } else if (status & IE_XS_LOSTCTS) {
+ printf("%s: lost CTS\n", sc->sc_dev.dv_xname);
+ sc->sc_arpcom.ac_if.if_oerrors++;
+ } else if (status & IE_XS_UNDERRUN) {
+ printf("%s: DMA underrun\n", sc->sc_dev.dv_xname);
+ sc->sc_arpcom.ac_if.if_oerrors++;
+ } else if (status & IE_XS_EXCMAX) {
+ printf("%s: too many collisions\n", sc->sc_dev.dv_xname);
+ sc->sc_arpcom.ac_if.if_collisions += 16;
+ sc->sc_arpcom.ac_if.if_oerrors++;
+ }
+
+ /*
+ * If multicast addresses were added or deleted while transmitting,
+ * mc_reset() set the want_mcsetup flag indicating that we should do
+ * it.
+ */
+ if (sc->want_mcsetup) {
+ mc_setup(sc, (caddr_t)sc->xmit_cbuffs[sc->xctail]);
+ sc->want_mcsetup = 0;
+ }
+
+ /* Done with the buffer. */
+ sc->xmit_free++;
+ sc->xmit_busy = 0;
+ sc->xctail = (sc->xctail + 1) % NTXBUF;
+
+ iestart(&sc->sc_arpcom.ac_if);
+}
+
+/*
+ * Compare two Ether/802 addresses for equality, inlined and unrolled for
+ * speed. I'd love to have an inline assembler version of this...
+ */
+static inline int
+ether_equal(one, two)
+ u_char *one, *two;
+{
+
+ if (one[0] != two[0] || one[1] != two[1] || one[2] != two[2] ||
+ one[3] != two[3] || one[4] != two[4] || one[5] != two[5])
+ return 0;
+ return 1;
+}
+
+/*
+ * Check for a valid address. to_bpf is filled in with one of the following:
+ * 0 -> BPF doesn't get this packet
+ * 1 -> BPF does get this packet
+ * 2 -> BPF does get this packet, but we don't
+ * Return value is true if the packet is for us, and false otherwise.
+ *
+ * This routine is a mess, but it's also critical that it be as fast
+ * as possible. It could be made cleaner if we can assume that the
+ * only client which will fiddle with IFF_PROMISC is BPF. This is
+ * probably a good assumption, but we do not make it here. (Yet.)
+ */
+static inline int
+check_eh(sc, eh, to_bpf)
+ struct ie_softc *sc;
+ struct ether_header *eh;
+ int *to_bpf;
+{
+ int i;
+
+ switch(sc->promisc) {
+ case IFF_ALLMULTI:
+ /*
+ * Receiving all multicasts, but no unicasts except those
+ * destined for us.
+ */
+#if NBPFILTER > 0
+ *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0); /* BPF gets this packet if anybody cares */
+#endif
+ if (eh->ether_dhost[0] & 1)
+ return 1;
+ if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr)) return 1;
+ return 0;
+
+ case IFF_PROMISC:
+ /*
+ * Receiving all packets. These need to be passed on to BPF.
+ */
+#if NBPFILTER > 0
+ *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0);
+#endif
+ /* If for us, accept and hand up to BPF */
+ if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr)) return 1;
+
+#if NBPFILTER > 0
+ if (*to_bpf)
+ *to_bpf = 2; /* we don't need to see it */
+#endif
+
+ /*
+ * Not a multicast, so BPF wants to see it but we don't.
+ */
+ if (!(eh->ether_dhost[0] & 1))
+ return 1;
+
+ /*
+ * If it's one of our multicast groups, accept it and pass it
+ * up.
+ */
+ for (i = 0; i < sc->mcast_count; i++) {
+ if (ether_equal(eh->ether_dhost, (u_char *)&sc->mcast_addrs[i])) {
+#if NBPFILTER > 0
+ if (*to_bpf)
+ *to_bpf = 1;
+#endif
+ return 1;
+ }
+ }
+ return 1;
+
+ case IFF_ALLMULTI | IFF_PROMISC:
+ /*
+ * Acting as a multicast router, and BPF running at the same
+ * time. Whew! (Hope this is a fast machine...)
+ */
+#if NBPFILTER > 0
+ *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0);
+#endif
+ /* We want to see multicasts. */
+ if (eh->ether_dhost[0] & 1)
+ return 1;
+
+ /* We want to see our own packets */
+ if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr))
+ return 1;
+
+ /* Anything else goes to BPF but nothing else. */
+#if NBPFILTER > 0
+ if (*to_bpf)
+ *to_bpf = 2;
+#endif
+ return 1;
+
+ default:
+ /*
+ * Only accept unicast packets destined for us, or multicasts
+ * for groups that we belong to. For now, we assume that the
+ * '586 will only return packets that we asked it for. This
+ * isn't strictly true (it uses hashing for the multicast
+ * filter), but it will do in this case, and we want to get out
+ * of here as quickly as possible.
+ */
+#if NBPFILTER > 0
+ *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0);
+#endif
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * We want to isolate the bits that have meaning... This assumes that
+ * IE_RBUF_SIZE is an even power of two. If somehow the act_len exceeds
+ * the size of the buffer, then we are screwed anyway.
+ */
+static inline int
+ie_buflen(sc, head)
+ struct ie_softc *sc;
+ int head;
+{
+
+ return (SWAP(sc->rbuffs[head]->ie_rbd_actual)
+ & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
+}
+
+static inline int
+ie_packet_len(sc)
+ struct ie_softc *sc;
+{
+ int i;
+ int head = sc->rbhead;
+ int acc = 0;
+
+ do {
+ if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
+#ifdef IEDEBUG
+ print_rbd(sc->rbuffs[sc->rbhead]);
+#endif
+ log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
+ sc->sc_dev.dv_xname, sc->rbhead);
+ iereset(sc);
+ return -1;
+ }
+
+ i = sc->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
+
+ acc += ie_buflen(sc, head);
+ head = (head + 1) % sc->nrxbuf;
+ } while (!i);
+
+ return acc;
+}
+
+/*
+ * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
+ * command to the chip to be executed. On the way, if we have a BPF listener
+ * also give him a copy.
+ */
+inline static void
+iexmit(sc)
+ struct ie_softc *sc;
+{
+
+#if NBPFILTER > 0
+ /*
+ * If BPF is listening on this interface, let it see the packet before
+ * we push it on the wire.
+ */
+ if (sc->sc_arpcom.ac_if.if_bpf)
+ bpf_tap(sc->sc_arpcom.ac_if.if_bpf,
+ sc->xmit_cbuffs[sc->xctail],
+ SWAP(sc->xmit_buffs[sc->xctail]->ie_xmit_flags));
+#endif
+
+/*printf("iexmit base %x cmd %x bfd %x to %x\n",
+sc->sc_maddr,
+sc->xmit_cmds[sc->xctail],
+sc->xmit_buffs[sc->xctail],
+sc->xmit_cbuffs[sc->xctail]);*/
+ sc->xmit_buffs[sc->xctail]->ie_xmit_flags |= IE_XMIT_LAST;
+ sc->xmit_buffs[sc->xctail]->ie_xmit_next = SWAP(0xffff);
+ ST_24(sc->xmit_buffs[sc->xctail]->ie_xmit_buf,
+ MK_24(sc->sc_iobase, sc->xmit_cbuffs[sc->xctail]));
+
+ sc->xmit_cmds[sc->xctail]->com.ie_cmd_link = SWAP(0xffff);
+ sc->xmit_cmds[sc->xctail]->com.ie_cmd_cmd =
+ IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST;
+
+ sc->xmit_cmds[sc->xctail]->ie_xmit_status = SWAP(0);
+ sc->xmit_cmds[sc->xctail]->ie_xmit_desc =
+ MK_16(sc->sc_maddr, sc->xmit_buffs[sc->xctail]);
+
+ sc->scb->ie_command_list =
+ MK_16(sc->sc_maddr, sc->xmit_cmds[sc->xctail]);
+ command_and_wait(sc, IE_CU_START, 0, 0);
+
+ sc->xmit_busy = 1;
+ sc->sc_arpcom.ac_if.if_timer = 5;
+}
+
+/*
+ * Read data off the interface, and turn it into an mbuf chain.
+ *
+ * This code is DRAMATICALLY different from the previous version; this
+ * version tries to allocate the entire mbuf chain up front, given the
+ * length of the data available. This enables us to allocate mbuf
+ * clusters in many situations where before we would have had a long
+ * chain of partially-full mbufs. This should help to speed up the
+ * operation considerably. (Provided that it works, of course.)
+ */
+static inline int
+ieget(sc, mp, ehp, to_bpf)
+ struct ie_softc *sc;
+ struct mbuf **mp;
+ struct ether_header *ehp;
+ int *to_bpf;
+{
+ struct mbuf *m, *top, **mymp;
+ int i;
+ int offset;
+ int totlen, resid;
+ int thismboff;
+ int head;
+
+ totlen = ie_packet_len(sc);
+ if (totlen <= 0)
+ return -1;
+
+ i = sc->rbhead;
+
+ /*
+ * Snarf the Ethernet header.
+ */
+ (sc->memcopy)((caddr_t)sc->cbuffs[i], (caddr_t)ehp, sizeof *ehp);
+
+ /*
+ * As quickly as possible, check if this packet is for us.
+ * If not, don't waste a single cycle copying the rest of the
+ * packet in.
+ * This is only a consideration when FILTER is defined; i.e., when
+ * we are either running BPF or doing multicasting.
+ */
+ if (!check_eh(sc, ehp, to_bpf)) {
+ ie_drop_packet_buffer(sc);
+ sc->sc_arpcom.ac_if.if_ierrors--; /* just this case, it's not an error */
+ return -1;
+ }
+ totlen -= (offset = sizeof *ehp);
+
+ MGETHDR(*mp, M_DONTWAIT, MT_DATA);
+ if (!*mp) {
+ ie_drop_packet_buffer(sc);
+ return -1;
+ }
+
+ m = *mp;
+ m->m_pkthdr.rcvif = &sc->sc_arpcom.ac_if;
+ m->m_len = MHLEN;
+ resid = m->m_pkthdr.len = totlen;
+ top = 0;
+ mymp = ⊤
+
+ /*
+ * This loop goes through and allocates mbufs for all the data we will
+ * be copying in. It does not actually do the copying yet.
+ */
+ do { /* while (resid > 0) */
+ /*
+ * Try to allocate an mbuf to hold the data that we have. If
+ * we already allocated one, just get another one and stick it
+ * on the end (eventually). If we don't already have one, try
+ * to allocate an mbuf cluster big enough to hold the whole
+ * packet, if we think it's reasonable, or a single mbuf which
+ * may or may not be big enough.
+ * Got that?
+ */
+ if (top) {
+ MGET(m, M_DONTWAIT, MT_DATA);
+ if (!m) {
+ m_freem(top);
+ ie_drop_packet_buffer(sc);
+ return -1;
+ }
+ m->m_len = MLEN;
+ }
+
+ if (resid >= MINCLSIZE) {
+ MCLGET(m, M_DONTWAIT);
+ if (m->m_flags & M_EXT)
+ m->m_len = min(resid, MCLBYTES);
+ } else {
+ if (resid < m->m_len) {
+ if (!top && resid + max_linkhdr <= m->m_len)
+ m->m_data += max_linkhdr;
+ m->m_len = resid;
+ }
+ }
+ resid -= m->m_len;
+ *mymp = m;
+ mymp = &m->m_next;
+ } while (resid > 0);
+
+ resid = totlen;
+ m = top;
+ thismboff = 0;
+ head = sc->rbhead;
+
+ /*
+ * Now we take the mbuf chain (hopefully only one mbuf most of the
+ * time) and stuff the data into it. There are no possible failures at
+ * or after this point.
+ */
+ while (resid > 0) { /* while there's stuff left */
+ int thislen = ie_buflen(sc, head) - offset;
+
+ /*
+ * If too much data for the current mbuf, then fill the current
+ * one up, go to the next one, and try again.
+ */
+ if (thislen > m->m_len - thismboff) {
+ int newlen = m->m_len - thismboff;
+ (sc->memcopy)((caddr_t)(sc->cbuffs[head] + offset),
+ mtod(m, caddr_t) + thismboff, (u_int)newlen);
+ m = m->m_next;
+ thismboff = 0; /* new mbuf, so no offset */
+ offset += newlen; /* we are now this far
+ into the packet */
+ resid -= newlen; /* so there is this much
+ left to get */
+ continue;
+ }
+
+ /*
+ * If there is more than enough space in the mbuf to hold the
+ * contents of this buffer, copy everything in, advance
+ * pointers and so on.
+ */
+ if (thislen < m->m_len - thismboff) {
+ (sc->memcopy)((caddr_t)(sc->cbuffs[head] + offset),
+ mtod(m, caddr_t) + thismboff, (u_int)thislen);
+ thismboff += thislen; /* we are this far into the mbuf */
+ resid -= thislen; /* and this much is left */
+ goto nextbuf;
+ }
+
+ /*
+ * Otherwise, there is exactly enough space to put this
+ * buffer's contents into the current mbuf. Do the combination
+ * of the above actions.
+ */
+ (sc->memcopy)((caddr_t)(sc->cbuffs[head] + offset),
+ mtod(m, caddr_t) + thismboff, (u_int)thislen);
+ m = m->m_next;
+ thismboff = 0; /* new mbuf, start at the beginning */
+ resid -= thislen; /* and we are this far through */
+
+ /*
+ * Advance all the pointers. We can get here from either of
+ * the last two cases, but never the first.
+ */
+ nextbuf:
+ offset = 0;
+ sc->rbuffs[head]->ie_rbd_actual = SWAP(0);
+ sc->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST;
+ sc->rbhead = head = (head + 1) % sc->nrxbuf;
+ sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
+ sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf;
+ }
+
+ /*
+ * Unless something changed strangely while we were doing the copy, we
+ * have now copied everything in from the shared memory.
+ * This means that we are done.
+ */
+ return 0;
+}
+
+/*
+ * Read frame NUM from unit UNIT (pre-cached as IE).
+ *
+ * This routine reads the RFD at NUM, and copies in the buffers from the list
+ * of RBD, then rotates the RBD and RFD lists so that the receiver doesn't
+ * start complaining. Trailers are DROPPED---there's no point in wasting time
+ * on confusing code to deal with them. Hopefully, this machine will never ARP
+ * for trailers anyway.
+ */
+static void
+ie_readframe(sc, num)
+ struct ie_softc *sc;
+ int num; /* frame number to read */
+{
+ int status;
+ struct mbuf *m = 0;
+ struct ether_header eh;
+#if NBPFILTER > 0
+ int bpf_gets_it = 0;
+#endif
+
+ status = sc->rframes[num]->ie_fd_status;
+
+ /* Immediately advance the RFD list, since we have copied ours now. */
+ sc->rframes[num]->ie_fd_status = SWAP(0);
+ sc->rframes[num]->ie_fd_last |= IE_FD_LAST;
+ sc->rframes[sc->rftail]->ie_fd_last &= ~IE_FD_LAST;
+ sc->rftail = (sc->rftail + 1) % sc->nframes;
+ sc->rfhead = (sc->rfhead + 1) % sc->nframes;
+
+ if (status & IE_FD_OK) {
+#if NBPFILTER > 0
+ if (ieget(sc, &m, &eh, &bpf_gets_it)) {
+#else
+ if (ieget(sc, &m, &eh, 0)) {
+#endif
+ sc->sc_arpcom.ac_if.if_ierrors++;
+ return;
+ }
+ }
+
+#ifdef IEDEBUG
+ if (sc->sc_debug & IED_READFRAME)
+ printf("%s: frame from ether %s type %x\n", sc->sc_dev.dv_xname,
+ ether_sprintf(eh.ether_shost), (u_int)eh.ether_type);
+#endif
+
+ if (!m)
+ return;
+
+ if (last_not_for_us) {
+ m_freem(last_not_for_us);
+ last_not_for_us = 0;
+ }
+
+#if NBPFILTER > 0
+ /*
+ * Check for a BPF filter; if so, hand it up.
+ * Note that we have to stick an extra mbuf up front, because bpf_mtap
+ * expects to have the ether header at the front.
+ * It doesn't matter that this results in an ill-formatted mbuf chain,
+ * since BPF just looks at the data. (It doesn't try to free the mbuf,
+ * tho' it will make a copy for tcpdump.)
+ */
+ if (bpf_gets_it) {
+ struct mbuf m0;
+ m0.m_len = sizeof eh;
+ m0.m_data = (caddr_t)&eh;
+ m0.m_next = m;
+
+ /* Pass it up. */
+ bpf_mtap(sc->sc_arpcom.ac_if.if_bpf, &m0);
+ }
+ /*
+ * A signal passed up from the filtering code indicating that the
+ * packet is intended for BPF but not for the protocol machinery.
+ * We can save a few cycles by not handing it off to them.
+ */
+ if (bpf_gets_it == 2) {
+ last_not_for_us = m;
+ return;
+ }
+#endif /* NBPFILTER > 0 */
+
+ /*
+ * In here there used to be code to check destination addresses upon
+ * receipt of a packet. We have deleted that code, and replaced it
+ * with code to check the address much earlier in the cycle, before
+ * copying the data in; this saves us valuable cycles when operating
+ * as a multicast router or when using BPF.
+ */
+
+ /*
+ * Finally pass this packet up to higher layers.
+ */
+ ether_input(&sc->sc_arpcom.ac_if, &eh, m);
+}
+
+static void
+ie_drop_packet_buffer(sc)
+ struct ie_softc *sc;
+{
+ int i;
+
+ do {
+ /*
+ * This means we are somehow out of sync. So, we reset the
+ * adapter.
+ */
+ if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
+#ifdef IEDEBUG
+ print_rbd(sc->rbuffs[sc->rbhead]);
+#endif
+ log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
+ sc->sc_dev.dv_xname, sc->rbhead);
+ iereset(sc);
+ return;
+ }
+
+ i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST;
+
+ sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST;
+ sc->rbuffs[sc->rbhead]->ie_rbd_actual = SWAP(0);
+ sc->rbhead = (sc->rbhead + 1) % sc->nrxbuf;
+ sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
+ sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf;
+ } while (!i);
+}
+
+
+/*
+ * Start transmission on an interface.
+ */
+void
+iestart(ifp)
+ struct ifnet *ifp;
+{
+ struct ie_softc *sc = ifp->if_softc;
+ struct mbuf *m0, *m;
+ u_char *buffer;
+ u_short len;
+
+/*printf("iestart\n");*/
+ if ((ifp->if_flags & IFF_RUNNING) == 0)
+ return;
+
+ if (sc->xmit_free == 0) {
+ ifp->if_flags |= IFF_OACTIVE;
+ if (!sc->xmit_busy)
+ iexmit(sc);
+ return;
+ }
+
+ do {
+ IF_DEQUEUE(&sc->sc_arpcom.ac_if.if_snd, m);
+ if (!m)
+ break;
+
+ len = 0;
+ buffer = sc->xmit_cbuffs[sc->xchead];
+
+ for (m0 = m; m && (len +m->m_len) < IE_TBUF_SIZE;
+ m = m->m_next) {
+ bcopy(mtod(m, caddr_t), buffer, m->m_len);
+ buffer += m->m_len;
+ len += m->m_len;
+ }
+ if (m)
+ printf("%s: tbuf overflow\n", sc->sc_dev.dv_xname);
+
+ m_freem(m0);
+ len = max(len, ETHER_MIN_LEN);
+ sc->xmit_buffs[sc->xchead]->ie_xmit_flags = SWAP(len);
+
+ sc->xmit_free--;
+ sc->xchead = (sc->xchead + 1) % NTXBUF;
+ } while (sc->xmit_free > 0);
+
+ /* If we stuffed any packets into the card's memory, send now. */
+ if ((sc->xmit_free < NTXBUF) && (!sc->xmit_busy))
+ iexmit(sc);
+
+ return;
+}
+
+/*
+ * set up IE's ram space
+ */
+int
+ie_setupram(sc)
+ struct ie_softc *sc;
+{
+ volatile struct ie_int_sys_conf_ptr *iscp;
+ volatile struct ie_sys_ctl_block *scb;
+ int s;
+
+ s = splnet();
+
+ iscp = sc->iscp;
+ (sc->memzero)((char *) iscp, sizeof *iscp);
+
+ scb = sc->scb;
+ (sc->memzero)((char *) scb, sizeof *scb);
+
+ iscp->ie_busy = 1; /* ie_busy == char */
+ iscp->ie_scb_offset = MK_16(sc->sc_maddr, scb);
+ ST_24(iscp->ie_base, sc->sc_iobase);
+
+ (sc->reset_586) (sc);
+ (sc->chan_attn) (sc);
+
+ delay(100); /* wait a while... */
+
+ if (iscp->ie_busy) {
+ splx(s);
+ return 0;
+ }
+ /*
+ * Acknowledge any interrupts we may have caused...
+ */
+ ie_ack(sc, IE_ST_WHENCE);
+ splx(s);
+
+ return 1;
+}
+
+void
+iereset(sc)
+ struct ie_softc *sc;
+{
+ int s = splnet();
+
+ printf("%s: reset\n", sc->sc_dev.dv_xname);
+
+ /* Clear OACTIVE in case we're called from watchdog (frozen xmit). */
+ sc->sc_arpcom.ac_if.if_flags &= ~(IFF_UP | IFF_OACTIVE);
+ ieioctl(&sc->sc_arpcom.ac_if, SIOCSIFFLAGS, 0);
+
+ /*
+ * Stop i82586 dead in its tracks.
+ */
+ if (command_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
+ printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname);
+
+ if (command_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
+ printf("%s: disable commands timed out\n", sc->sc_dev.dv_xname);
+
+#ifdef notdef
+ if (!check_ie_present(sc, sc->sc_maddr, sc->sc_msize))
+ panic("ie disappeared!\n");
+#endif
+
+ sc->sc_arpcom.ac_if.if_flags |= IFF_UP;
+ ieioctl(&sc->sc_arpcom.ac_if, SIOCSIFFLAGS, 0);
+
+ splx(s);
+}
+
+/*
+ * This is called if we time out.
+ */
+static void
+chan_attn_timeout(rock)
+ caddr_t rock;
+{
+
+ *(int *)rock = 1;
+}
+
+/*
+ * Send a command to the controller and wait for it to either complete
+ * or be accepted, depending on the command. If the command pointer
+ * is null, then pretend that the command is not an action command.
+ * If the command pointer is not null, and the command is an action
+ * command, wait for
+ * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
+ * to become true.
+ */
+static int
+command_and_wait(sc, cmd, pcmd, mask)
+ struct ie_softc *sc;
+ int cmd;
+ volatile void *pcmd;
+ int mask;
+{
+ volatile struct ie_cmd_common *cc = pcmd;
+ volatile struct ie_sys_ctl_block *scb = sc->scb;
+ volatile int timedout = 0;
+ extern int hz;
+
+ scb->ie_command = (u_short)cmd;
+
+ if (IE_ACTION_COMMAND(cmd) && pcmd) {
+ (sc->chan_attn)(sc);
+
+#if 0
+ /*
+ * XXX
+ * I don't think this timeout works on suns.
+ * we are at splnet() in the loop, and the timeout
+ * stuff runs at software spl (so it is masked off?).
+ */
+
+ /*
+ * According to the packet driver, the minimum timeout should
+ * be .369 seconds, which we round up to .4.
+ */
+ timeout(chan_attn_timeout, (caddr_t)&timedout, 2 * hz / 5);
+#endif
+
+ /*
+ * Now spin-lock waiting for status. This is not a very nice
+ * thing to do, but I haven't figured out how, or indeed if, we
+ * can put the process waiting for action to sleep. (We may
+ * be getting called through some other timeout running in the
+ * kernel.)
+ */
+ for (;;)
+ if ((cc->ie_cmd_status & mask) || timedout)
+ break;
+#if 0
+ untimeout(chan_attn_timeout, (caddr_t)&timedout);
+#endif
+
+ return timedout;
+ } else {
+ /*
+ * Otherwise, just wait for the command to be accepted.
+ */
+ (sc->chan_attn)(sc);
+
+ while (scb->ie_command)
+ ; /* XXX spin lock */
+
+ return 0;
+ }
+}
+
+/*
+ * Run the time-domain reflectometer.
+ */
+static void
+run_tdr(sc, cmd)
+ struct ie_softc *sc;
+ struct ie_tdr_cmd *cmd;
+{
+ int result;
+
+ cmd->com.ie_cmd_status = SWAP(0);
+ cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
+ cmd->com.ie_cmd_link = SWAP(0xffff);
+
+ sc->scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
+ cmd->ie_tdr_time = SWAP(0);
+
+ if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
+ !(cmd->com.ie_cmd_status & IE_STAT_OK))
+ result = 0x10000; /* XXX */
+ else
+ result = cmd->ie_tdr_time;
+
+ ie_ack(sc, IE_ST_WHENCE);
+
+ if (result & IE_TDR_SUCCESS)
+ return;
+
+ if (result & 0x10000)
+ printf("%s: TDR command failed\n", sc->sc_dev.dv_xname);
+ else if (result & IE_TDR_XCVR)
+ printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
+ else if (result & IE_TDR_OPEN)
+ printf("%s: TDR detected an open %d clocks away\n",
+ sc->sc_dev.dv_xname, result & IE_TDR_TIME);
+ else if (result & IE_TDR_SHORT)
+ printf("%s: TDR detected a short %d clocks away\n",
+ sc->sc_dev.dv_xname, result & IE_TDR_TIME);
+ else
+ printf("%s: TDR returned unknown status %x\n",
+ sc->sc_dev.dv_xname, result);
+}
+
+#ifdef notdef
+/* ALIGN works on 8 byte boundaries.... but 4 byte boundaries are ok for sun */
+#define _ALLOC(p, n) (bzero(p, n), p += n, p - n)
+#define ALLOC(p, n) _ALLOC(p, ALIGN(n)) /* XXX convert to this? */
+#endif
+
+static inline caddr_t
+Align(ptr)
+ caddr_t ptr;
+{
+ u_long l = (u_long)ptr;
+
+ l = (l + 3) & ~3L;
+ return (caddr_t)l;
+}
+
+/*
+ * setup_bufs: set up the buffers
+ *
+ * we have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
+ * this is to be used for the buffers. the chip indexs its control data
+ * structures with 16 bit offsets, and it indexes actual buffers with
+ * 24 bit addresses. so we should allocate control buffers first so that
+ * we don't overflow the 16 bit offset field. The number of transmit
+ * buffers is fixed at compile time.
+ *
+ * note: this function was written to be easy to understand, rather than
+ * highly efficient (it isn't in the critical path).
+ */
+static void
+setup_bufs(sc)
+ struct ie_softc *sc;
+{
+ caddr_t ptr = sc->buf_area; /* memory pool */
+ volatile struct ie_recv_frame_desc *rfd = (void *) ptr;
+ volatile struct ie_recv_buf_desc *rbd;
+ int n, r;
+
+ /*
+ * step 0: zero memory and figure out how many recv buffers and
+ * frames we can have. XXX CURRENTLY HARDWIRED AT MAX
+ */
+ (sc->memzero)(ptr, sc->buf_area_sz);
+ ptr = Align(ptr); /* set alignment and stick with it */
+
+ n = (int)Align(sizeof(struct ie_xmit_cmd)) +
+ (int)Align(sizeof(struct ie_xmit_buf)) + IE_TBUF_SIZE;
+ n *= NTXBUF; /* n = total size of xmit area */
+
+ n = sc->buf_area_sz - n;/* n = free space for recv stuff */
+
+ r = (int)Align(sizeof(struct ie_recv_frame_desc)) +
+ (((int)Align(sizeof(struct ie_recv_buf_desc)) + IE_RBUF_SIZE) * B_PER_F);
+
+ /* r = size of one R frame */
+
+ sc->nframes = n / r;
+ if (sc->nframes <= 0)
+ panic("ie: bogus buffer calc\n");
+ if (sc->nframes > MXFRAMES)
+ sc->nframes = MXFRAMES;
+
+ sc->nrxbuf = sc->nframes * B_PER_F;
+
+#ifdef IEDEBUG
+ printf("IEDEBUG: %d frames %d bufs\n", sc->nframes, sc->nrxbuf);
+#endif
+
+ /*
+ * step 1a: lay out and zero frame data structures for transmit and recv
+ */
+ for (n = 0; n < NTXBUF; n++) {
+ sc->xmit_cmds[n] = (volatile struct ie_xmit_cmd *) ptr;
+ ptr = Align(ptr + sizeof(struct ie_xmit_cmd));
+ }
+
+ for (n = 0; n < sc->nframes; n++) {
+ sc->rframes[n] = (volatile struct ie_recv_frame_desc *) ptr;
+ ptr = Align(ptr + sizeof(struct ie_recv_frame_desc));
+ }
+
+ /*
+ * step 1b: link together the recv frames and set EOL on last one
+ */
+ for (n = 0; n < sc->nframes; n++) {
+ sc->rframes[n]->ie_fd_next =
+ MK_16(sc->sc_maddr, sc->rframes[(n + 1) % sc->nframes]);
+ }
+ sc->rframes[sc->nframes - 1]->ie_fd_last |= IE_FD_LAST;
+
+ /*
+ * step 2a: lay out and zero frame buffer structures for xmit and recv
+ */
+ for (n = 0; n < NTXBUF; n++) {
+ sc->xmit_buffs[n] = (volatile struct ie_xmit_buf *) ptr;
+ ptr = Align(ptr + sizeof(struct ie_xmit_buf));
+ }
+
+ for (n = 0; n < sc->nrxbuf; n++) {
+ sc->rbuffs[n] = (volatile struct ie_recv_buf_desc *) ptr;
+ ptr = Align(ptr + sizeof(struct ie_recv_buf_desc));
+ }
+
+ /*
+ * step 2b: link together recv bufs and set EOL on last one
+ */
+ for (n = 0; n < sc->nrxbuf; n++) {
+ sc->rbuffs[n]->ie_rbd_next =
+ MK_16(sc->sc_maddr, sc->rbuffs[(n + 1) % sc->nrxbuf]);
+ }
+ sc->rbuffs[sc->nrxbuf - 1]->ie_rbd_length |= IE_RBD_LAST;
+
+ /*
+ * step 3: allocate the actual data buffers for xmit and recv
+ * recv buffer gets linked into recv_buf_desc list here
+ */
+ for (n = 0; n < NTXBUF; n++) {
+ sc->xmit_cbuffs[n] = (u_char *) ptr;
+ ptr = Align(ptr + IE_TBUF_SIZE);
+ }
+
+ /* Pointers to last packet sent and next available transmit buffer. */
+ sc->xchead = sc->xctail = 0;
+
+ /* Clear transmit-busy flag and set number of free transmit buffers. */
+ sc->xmit_busy = 0;
+ sc->xmit_free = NTXBUF;
+
+ for (n = 0; n < sc->nrxbuf; n++) {
+ sc->cbuffs[n] = (char *) ptr; /* XXX why char vs uchar? */
+ sc->rbuffs[n]->ie_rbd_length = SWAP(IE_RBUF_SIZE);
+ ST_24(sc->rbuffs[n]->ie_rbd_buffer, MK_24(sc->sc_iobase, ptr));
+ ptr = Align(ptr + IE_RBUF_SIZE);
+ }
+
+ /*
+ * step 4: set the head and tail pointers on receive to keep track of
+ * the order in which RFDs and RBDs are used. link in recv frames
+ * and buffer into the scb.
+ */
+
+ sc->rfhead = 0;
+ sc->rftail = sc->nframes - 1;
+ sc->rbhead = 0;
+ sc->rbtail = sc->nrxbuf - 1;
+
+ sc->scb->ie_recv_list = MK_16(sc->sc_maddr, sc->rframes[0]);
+ sc->rframes[0]->ie_fd_buf_desc = MK_16(sc->sc_maddr, sc->rbuffs[0]);
+
+#ifdef IEDEBUG
+ printf("IE_DEBUG: reserved %d bytes\n", ptr - sc->buf_area);
+#endif
+}
+
+/*
+ * Run the multicast setup command.
+ * Called at splnet().
+ */
+static int
+mc_setup(sc, ptr)
+ struct ie_softc *sc;
+ void *ptr;
+{
+ volatile struct ie_mcast_cmd *cmd = ptr;
+
+ cmd->com.ie_cmd_status = SWAP(0);
+ cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
+ cmd->com.ie_cmd_link = SWAP(0xffff);
+
+ (sc->memcopy)((caddr_t)sc->mcast_addrs, (caddr_t)cmd->ie_mcast_addrs,
+ sc->mcast_count * sizeof *sc->mcast_addrs);
+
+ cmd->ie_mcast_bytes =
+ SWAP(sc->mcast_count * ETHER_ADDR_LEN); /* grrr... */
+
+ sc->scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
+ if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
+ !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
+ printf("%s: multicast address setup command failed\n",
+ sc->sc_dev.dv_xname);
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * This routine takes the environment generated by check_ie_present() and adds
+ * to it all the other structures we need to operate the adapter. This
+ * includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands, starting
+ * the receiver unit, and clearing interrupts.
+ *
+ * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER.
+ */
+int
+ieinit(sc)
+ struct ie_softc *sc;
+{
+ volatile struct ie_sys_ctl_block *scb = sc->scb;
+ void *ptr;
+ int n;
+
+ ptr = sc->buf_area;
+
+ /*
+ * Send the configure command first.
+ */
+ {
+ volatile struct ie_config_cmd *cmd = ptr;
+
+ scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
+ cmd->com.ie_cmd_status = SWAP(0);
+ cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
+ cmd->com.ie_cmd_link = SWAP(0xffff);
+
+ ie_setup_config(cmd, sc->promisc, 0);
+
+ if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
+ !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
+ printf("%s: configure command failed\n",
+ sc->sc_dev.dv_xname);
+ return 0;
+ }
+ }
+
+ /*
+ * Now send the Individual Address Setup command.
+ */
+ {
+ volatile struct ie_iasetup_cmd *cmd = ptr;
+
+ scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
+ cmd->com.ie_cmd_status = SWAP(0);
+ cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
+ cmd->com.ie_cmd_link = SWAP(0xffff);
+
+ (sc->memcopy)(sc->sc_arpcom.ac_enaddr,
+ (caddr_t)&cmd->ie_address, sizeof cmd->ie_address);
+
+ if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
+ !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
+ printf("%s: individual address setup command failed\n",
+ sc->sc_dev.dv_xname);
+ return 0;
+ }
+ }
+
+ /*
+ * Now run the time-domain reflectometer.
+ */
+ run_tdr(sc, ptr);
+
+ /*
+ * Acknowledge any interrupts we have generated thus far.
+ */
+ ie_ack(sc, IE_ST_WHENCE);
+
+ /*
+ * Set up the transmit and recv buffers.
+ */
+ setup_bufs(sc);
+
+ sc->sc_arpcom.ac_if.if_flags |= IFF_RUNNING; /* tell higher levels that we are here */
+
+ sc->scb->ie_recv_list = MK_16(sc->sc_maddr, sc->rframes[0]);
+ command_and_wait(sc, IE_RU_START, 0, 0);
+
+ ie_ack(sc, IE_ST_WHENCE);
+
+ if (sc->run_586)
+ (sc->run_586)(sc);
+
+ return 0;
+}
+
+static void
+iestop(sc)
+ struct ie_softc *sc;
+{
+
+ command_and_wait(sc, IE_RU_DISABLE, 0, 0);
+}
+
+int
+ieioctl(ifp, cmd, data)
+ register struct ifnet *ifp;
+ u_long cmd;
+ caddr_t data;
+{
+ struct ie_softc *sc = ifp->if_softc;
+ struct ifaddr *ifa = (struct ifaddr *)data;
+ struct ifreq *ifr = (struct ifreq *)data;
+ int s, error = 0;
+
+ s = splnet();
+
+ if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
+ splx(s);
+ return error;
+ }
+
+ switch(cmd) {
+
+ case SIOCSIFADDR:
+ ifp->if_flags |= IFF_UP;
+
+ switch(ifa->ifa_addr->sa_family) {
+#ifdef INET
+ case AF_INET:
+ ieinit(sc);
+ arp_ifinit(&sc->sc_arpcom, ifa);
+ break;
+#endif
+ default:
+ ieinit(sc);
+ break;
+ }
+ break;
+
+ case SIOCSIFFLAGS:
+ sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
+ if ((ifp->if_flags & IFF_UP) == 0 &&
+ (ifp->if_flags & IFF_RUNNING) != 0) {
+ /*
+ * If interface is marked down and it is running, then
+ * stop it.
+ */
+ iestop(sc);
+ ifp->if_flags &= ~IFF_RUNNING;
+ } else if ((ifp->if_flags & IFF_UP) != 0 &&
+ (ifp->if_flags & IFF_RUNNING) == 0) {
+ /*
+ * If interface is marked up and it is stopped, then
+ * start it.
+ */
+ ieinit(sc);
+ } else {
+ /*
+ * Reset the interface to pick up changes in any other
+ * flags that affect hardware registers.
+ */
+ iestop(sc);
+ ieinit(sc);
+ }
+#ifdef IEDEBUG
+ if (ifp->if_flags & IFF_DEBUG)
+ sc->sc_debug = IED_ALL;
+ else
+ sc->sc_debug = 0;
+#endif
+ break;
+
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ error = (cmd == SIOCADDMULTI) ?
+ ether_addmulti(ifr, &sc->sc_arpcom):
+ ether_delmulti(ifr, &sc->sc_arpcom);
+
+ if (error == ENETRESET) {
+ /*
+ * Multicast list has changed; set the hardware filter
+ * accordingly.
+ */
+ mc_reset(sc);
+ error = 0;
+ }
+ break;
+
+ default:
+ error = EINVAL;
+ }
+ splx(s);
+ return error;
+}
+
+static void
+mc_reset(sc)
+ struct ie_softc *sc;
+{
+ struct ether_multi *enm;
+ struct ether_multistep step;
+
+ /*
+ * Step through the list of addresses.
+ */
+ sc->mcast_count = 0;
+ ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
+ while (enm) {
+ if (sc->mcast_count >= MAXMCAST ||
+ bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
+ sc->sc_arpcom.ac_if.if_flags |= IFF_ALLMULTI;
+ ieioctl(&sc->sc_arpcom.ac_if, SIOCSIFFLAGS, (void *)0);
+ goto setflag;
+ }
+
+ bcopy(enm->enm_addrlo, &sc->mcast_addrs[sc->mcast_count], 6);
+ sc->mcast_count++;
+ ETHER_NEXT_MULTI(step, enm);
+ }
+setflag:
+ sc->want_mcsetup = 1;
+}
+
+#ifdef IEDEBUG
+void
+print_rbd(rbd)
+ volatile struct ie_recv_buf_desc *rbd;
+{
+
+ printf("RBD at %08lx:\nactual %04x, next %04x, buffer %08x\n"
+ "length %04x, mbz %04x\n", (u_long)rbd, rbd->ie_rbd_actual,
+ rbd->ie_rbd_next, rbd->ie_rbd_buffer, rbd->ie_rbd_length,
+ rbd->mbz);
+}
+#endif
--- /dev/null
+/* $Id: if_ie.h,v 1.1.1.1 1997/03/03 19:32:05 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ */
+
+/*
+ * XXX where else is this from?
+ * if_sunie.h
+ *
+ * sun's ie interface
+ */
+
+/*
+ * programming notes:
+ *
+ * the ie chip operates in a 24 bit address space.
+ *
+ * most ie interfaces appear to be divided into two parts:
+ * - generic 586 stuff
+ * - board specific
+ *
+ * generic:
+ * the generic stuff of the ie chip is all done with data structures
+ * that live in the chip's memory address space. the chip expects
+ * its main data structure (the sys conf ptr -- SCP) to be at a fixed
+ * address in its 24 bit space: 0xfffff4
+ *
+ * the SCP points to another structure called the ISCP.
+ * the ISCP points to another structure called the SCB.
+ * the SCB has a status field, a linked list of "commands", and
+ * a linked list of "receive buffers". these are data structures that
+ * live in memory, not registers.
+ *
+ * board:
+ * to get the chip to do anything, you first put a command in the
+ * command data structure list. then you have to signal "attention"
+ * to the chip to get it to look at the command. how you
+ * signal attention depends on what board you have... on PC's
+ * there is an i/o port number to do this, on sun's there is a
+ * register bit you toggle.
+ *
+ * to get data from the chip you program it to interrupt...
+ *
+ *
+ * sun issues:
+ *
+ * there are 3 kinds of sun "ie" interfaces:
+ * 1 - a VME/multibus card
+ * 2 - an on-board interface (sun3's, sun-4/100's, and sun-4/200's)
+ * 3 - another VME board called the 3E
+ *
+ * the VME boards lives in vme16 space. only 16 and 8 bit accesses
+ * are allowed, so functions that copy data must be aware of this.
+ *
+ * the chip is an intel chip. this means that the byte order
+ * on all the "short"s in the chip's data structures is wrong.
+ * so, constants described in the intel docs are swapped for the sun.
+ * that means that any buffer pointers you give the chip must be
+ * swapped to intel format. yuck.
+ *
+ * VME/multibus interface:
+ * for the multibus interface the board ignores the top 4 bits
+ * of the chip address. the multibus interface seems to have its
+ * own MMU like page map (without protections or valid bits, etc).
+ * there are 256 pages of physical memory on the board (each page
+ * is 1024 bytes). there are 1024 slots in the page map. so,
+ * a 1024 byte page takes up 10 bits of address for the offset,
+ * and if there are 1024 slots in the page that is another 10 bits
+ * of the address. that makes a 20 bit address, and as stated
+ * earlier the board ignores the top 4 bits, so that accounts
+ * for all 24 bits of address.
+ *
+ * note that the last entry of the page map maps the top of the
+ * 24 bit address space and that the SCP is supposed to be at
+ * 0xfffff4 (taking into account allignment). so,
+ * for multibus, that entry in the page map has to be used for the SCP.
+ *
+ * the page map effects BOTH how the ie chip sees the
+ * memory, and how the host sees it.
+ *
+ * the page map is part of the "register" area of the board
+ *
+ * on-board interface:
+ *
+ * <fill in useful info later>
+ *
+ *
+ * VME3E interface:
+ *
+ * <fill in useful info later>
+ *
+ */
+
+/*
+ * PART 1: VME/multibus defs
+ */
+#define IEVME_PAGESIZE 1024 /* bytes */
+#define IEVME_PAGSHIFT 10 /* bits */
+#define IEVME_NPAGES 256 /* number of pages on chip */
+#define IEVME_MAPSZ 1024 /* number of entries in the map */
+
+/*
+ * PTE for the page map
+ */
+#define IEVME_SBORDR 0x8000 /* sun byte order */
+#define IEVME_IBORDR 0x0000 /* intel byte ordr */
+
+#define IEVME_P2MEM 0x2000 /* memory is on P2 */
+#define IEVME_OBMEM 0x0000 /* memory is on board */
+
+#define IEVME_PGMASK 0x0fff /* gives the physical page frame number */
+
+struct ievme {
+ u_short pgmap[IEVME_MAPSZ];
+ u_short xxx[32]; /* prom */
+ u_short status; /* see below for bits */
+ u_short xxx2; /* filler */
+ u_short pectrl; /* parity control (see below) */
+ u_short peaddr; /* low 16 bits of address */
+};
+
+/*
+ * status bits
+ */
+#define IEVME_RESET 0x8000 /* reset board */
+#define IEVME_ONAIR 0x4000 /* go out of loopback 'on-air' */
+#define IEVME_ATTEN 0x2000 /* attention */
+#define IEVME_IENAB 0x1000 /* interrupt enable */
+#define IEVME_PEINT 0x0800 /* parity error interrupt enable */
+#define IEVME_PERR 0x0200 /* parity error flag */
+#define IEVME_INT 0x0100 /* interrupt flag */
+#define IEVME_P2EN 0x0020 /* enable p2 bus */
+#define IEVME_256K 0x0010 /* 256kb rams */
+#define IEVME_HADDR 0x000f /* mask for bits 17-20 of address */
+
+/*
+ * parity control
+ */
+#define IEVME_PARACK 0x0100 /* parity error ack */
+#define IEVME_PARSRC 0x0080 /* parity error source */
+#define IEVME_PAREND 0x0040 /* which end of the data got the error */
+#define IEVME_PARADR 0x000f /* mask to get bits 17-20 of parity address */
+
+
+/*
+ * PART 2: the on-board interface
+ */
+struct ieob {
+ u_short porthigh;
+ u_short portlow;
+ u_long attn;
+};
+#define IE_PORT_NEWSCPADDR 0x00000002
+#define IE_PORT_RESET 0x00000000
+
+#define IEOB_ADBASE 0xff000000 /* KVA base addr of 24 bit address space */
+
+/*
+ * PART 3: the 3E board
+ */
+
+/*
+ * not supported (yet?)
+ */
--- /dev/null
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/reboot.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/disklabel.h>
+
+#include <machine/cpu.h>
+#include <machine/autoconf.h>
+
+void mbattach __P((struct device *, struct device *, void *));
+int mbprint __P((void *, const char *));
+int mbmatch __P((struct device *, void *, void *));
+int submatch __P((struct device *, void *, void *));
+
+/*
+ * mainbus driver
+ */
+
+struct cfattach mainbus_ca = {
+ sizeof(struct device), mbmatch, mbattach
+};
+
+struct cfdriver mainbus_cd = {
+ NULL, "mainbus", DV_DULL, 0
+};
+
+int
+mbmatch(struct device *pdp, void *self, void *auxp)
+{
+ struct cfdata *cfp = self;
+
+ if (cfp->cf_unit > 0)
+ return(0);
+ /*
+ * We are always here
+ */
+ return(1);
+}
+
+/*
+ * "find" all the things that should be there.
+ */
+void
+mbattach(struct device *pdp, struct device *dp, void *auxp)
+{
+ struct cfdata *cf;
+ extern int cputyp;
+
+ /* nothing to do for this bus */
+ printf (" machine type %x\n", cputyp);
+
+ if ((cf = config_search(submatch, dp, auxp)) != NULL) {
+ return;
+ }
+
+}
+
+int
+mbprint(void *auxp, const char *pnp)
+{
+ if (pnp)
+ printf("%s at %s", (char *)auxp, pnp);
+ return(UNCONF);
+}
+
+int
+submatch(struct device *parent, void *self, void *aux)
+{
+ struct confargs *ca = aux;
+ struct cfdata *cf = self;
+
+ ca->ca_bustype = BUS_MAIN;
+ ca->ca_paddr = (caddr_t)cf->cf_loc[0];
+ ca->ca_size = cf->cf_loc[1];
+
+ if (!(*cf->cf_attach->ca_match)(parent, cf, ca)) {
+ if (!parent)
+ cf->cf_fstate = FSTATE_FOUND;
+
+ return 0;
+ }
+
+ /*
+ * mapin the device memory of the child and call attach.
+ */
+#if 0
+ ca->ca_vaddr = (caddr_t)iomap_mapin(ca->ca_paddr, ca->ca_size, 1);
+#endif /* 0 */
+ ca->ca_vaddr = ca->ca_paddr;
+
+ config_attach(parent, cf, ca, mbprint);
+
+ return 1;
+}
--- /dev/null
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 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.
+ */
+
+/*
+ * MEMC chip
+ * XXX:
+ * the databooks say that you should only ever access the higher-numbered
+ * MEMC chip's control & status registers. this is strange. I disobey the
+ * rules, hopefully there won't be any spanking.
+ */
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/ioctl.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/tty.h>
+#include <sys/uio.h>
+#include <sys/callout.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/syslog.h>
+#include <sys/fcntl.h>
+#include <sys/device.h>
+#include <machine/cpu.h>
+#include <machine/autoconf.h>
+#include <dev/cons.h>
+
+#include <mvme88k/dev/memcreg.h>
+
+struct memcsoftc {
+ struct device sc_dev;
+ caddr_t sc_vaddr;
+ struct memcreg *sc_memc;
+ struct intrhand sc_ih;
+};
+
+void memcattach __P((struct device *, struct device *, void *));
+int memcmatch __P((struct device *, void *, void *));
+
+struct cfdriver memccd = {
+ NULL, "memc", memcmatch, memcattach,
+ DV_DULL, sizeof(struct memcsoftc), 0
+};
+
+int
+memcmatch(parent, vcf, args)
+ struct device *parent;
+ void *vcf, *args;
+{
+ struct cfdata *cf = vcf;
+ struct confargs *ca = args;
+ struct memcreg *memc = (struct memcreg *)ca->ca_vaddr;
+
+ if (badvaddr(memc, 4) || memc->memc_chipid != MEMC_CHIPID)
+ return (0);
+ return (1);
+}
+
+void
+memcattach(parent, self, args)
+ struct device *parent, *self;
+ void *args;
+{
+ struct confargs *ca = args;
+ struct memcsoftc *sc = (struct memcsoftc *)self;
+
+ /*
+ * since we know ourself to land in intiobase land,
+ * we must adjust our address
+ */
+ sc->sc_memc = (struct memcreg *)sc->sc_vaddr;
+
+ printf(": rev %d, unsupported\n", sc->sc_memc->memc_chiprev);
+
+#if 0
+ sc->sc_nmiih.ih_fn = memcabort;
+ sc->sc_nmiih.ih_arg = 0;
+ sc->sc_nmiih.ih_ipl = 7;
+ sc->sc_nmiih.ih_wantframe = 1;
+ mcintr_establish(xxx, &sc->sc_nmiih);
+#endif
+}
--- /dev/null
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 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.
+ */
+
+/*
+ * the MEMC's registers are very similar to the MCECC chip
+ */
+struct memcreg {
+ volatile u_char memc_chipid;
+ volatile u_char xx0[3];
+ volatile u_char memc_chiprev;
+ volatile u_char xx1[3];
+ volatile u_char memc_memconf;
+#define MEMC_MEMCONF_MSIZ 0x07
+/*
+#define MEMC_MEMCONF_RTOB(x) (((x) & MEMC_MEMCONF_MSIZ) * 4*1024*1024)
+*/
+#define MEMC_MEMCONF_RTOB(x) (1 << (((x) & MEMC_MEMCONF_MSIZ) + 22))
+ volatile u_char xx2[3];
+ volatile u_char memc_x0;
+ volatile u_char xx3[3];
+ volatile u_char memc_x1;
+ volatile u_char xx4[3];
+ volatile u_char memc_baseaddr;
+ volatile u_char xx5[3];
+ volatile u_char memc_control;
+ volatile u_char xx6[3];
+ volatile u_char memc_bclk;
+ volatile u_char xx7[3];
+};
+
+#define MEMC_CHIPID 0x81
--- /dev/null
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/buf.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+
+#include <sys/device.h>
+#include <machine/cpu.h>
+#include <machine/autoconf.h>
+
+/*ARGSUSED*/
+int
+memdevrw(base, len, uio, flags)
+ caddr_t base;
+ int len;
+ struct uio *uio;
+ int flags;
+{
+ register vm_offset_t o, v;
+ register int c;
+ register struct iovec *iov;
+ int error = 0;
+
+ while (uio->uio_resid > 0 && error == 0) {
+ iov = uio->uio_iov;
+ if (iov->iov_len == 0) {
+ uio->uio_iov++;
+ uio->uio_iovcnt--;
+ if (uio->uio_iovcnt < 0)
+ panic("memdevrw");
+ continue;
+ }
+
+ v = uio->uio_offset;
+ c = min(iov->iov_len, MAXPHYS);
+ if (v + c > len)
+ c = len - v; /* till end of dev */
+ if (c == 0)
+ return (0);
+ error = uiomove(base + v, c, uio);
+ }
+ return (error);
+}
--- /dev/null
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/ioctl.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/uio.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <machine/cpu.h>
+#include <machine/autoconf.h>
+
+#include <mvme88k/dev/nvramreg.h>
+#include <mvme88k/dev/pcctworeg.h>
+
+struct nvramsoftc {
+ struct device sc_dev;
+ caddr_t sc_paddr;
+ caddr_t sc_vaddr;
+ int sc_size;
+ volatile struct clockreg *sc_clockreg;
+};
+
+int nvrammatch __P((struct device *, void *, void *));
+void nvramattach __P((struct device *, struct device *, void *));
+
+struct cfattach nvram_ca = {
+ sizeof(struct nvramsoftc), nvrammatch, nvramattach
+};
+
+struct cfdriver nvram_cd = {
+ NULL, "nvram", DV_DULL, 0
+};
+
+/* ARGSUSED */
+int
+nvrammatch(struct device *parent, void *self, void *aux)
+{
+ struct confargs *ca = aux;
+ struct cfdata *cf = self;
+ caddr_t base;
+ int ret;
+
+#if 0
+ if (cputyp != CPU_167 && cputyp != CPU_166
+#ifdef CPU_187
+ && cputyp != CPU_187
+#endif
+ )
+ {
+ return 0;
+ }
+#endif /* 0 */
+
+ if (cputyp != CPU_187) {
+ return 0;
+ }
+
+ /*
+ * If bus or name do not match, fail.
+ */
+ if (ca->ca_bustype != BUS_PCCTWO ||
+ strcmp(cf->cf_driver->cd_name, "nvram")) {
+ return 0;
+ }
+
+
+ /* 3 locators base, size, ipl */
+ base = (caddr_t)cf->cf_loc[0];
+
+ if (badpaddr(base, 1) == -1) {
+ return 0;
+ }
+
+ /*
+ * Tell our parent our requirements.
+ */
+ ca->ca_paddr = (caddr_t)cf->cf_loc[0];
+ ca->ca_size = NVRAMSIZE;
+ ca->ca_ipl = 0;
+
+ return 1;
+}
+
+/* ARGSUSED */
+void
+nvramattach(struct device *parent, struct device *self, void *aux)
+{
+ struct nvramsoftc *sc = (struct nvramsoftc *)self;
+ struct confargs *ca = aux;
+
+ sc->sc_clockreg = (struct clockreg *)(ca->ca_vaddr + NVRAM_TOD_OFF);
+
+ printf(": MK48T08\n");
+}
+
+#if 0
+/*
+ * Write en/dis-able clock registers. We coordinate so that several
+ * writers can run simultaneously.
+ */
+void
+clk_wenable(onoff)
+ int onoff;
+{
+ register int s;
+ register vm_prot_t prot;/* nonzero => change prot */
+ static int writers;
+
+ s = splhigh();
+ if (onoff)
+ prot = writers++ == 0 ? VM_PROT_READ|VM_PROT_WRITE : 0;
+ else
+ prot = --writers == 0 ? VM_PROT_READ : 0;
+ splx(s);
+ if (prot)
+ pmap_changeprot(pmap_kernel(), (vm_offset_t)clockreg, prot, 1);
+}
+#endif /* 0 */
+
+/*
+ * BCD to hex and hex 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) % 4 == 0) && ((y) % 100) != 0 || ((y) % 400) == 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 };
+
+chiptotime(int sec, int min, int hour, int day, int mon, int year)
+{
+ register int days, yr;
+
+ sec = FROMBCD(sec);
+ min = FROMBCD(min);
+ hour = FROMBCD(hour);
+ day = FROMBCD(day);
+ mon = FROMBCD(mon);
+ year = FROMBCD(year) + YEAR0;
+
+ /* 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);
+}
+
+struct chiptime {
+ int sec;
+ int min;
+ int hour;
+ int wday;
+ int day;
+ int mon;
+ int year;
+};
+
+timetochip(struct chiptime *c)
+{
+ register int t, t2, t3, now = time.tv_sec;
+
+ /* compute the year */
+ t2 = now / SECDAY;
+ t3 = (t2 + 2) % 7; /* day of week */
+ c->wday = TOBCD(t3 + 1);
+
+ t = 69;
+ while (t2 >= 0) { /* whittle off years */
+ t3 = t2;
+ t++;
+ t2 -= LEAPYEAR(t) ? 366 : 365;
+ }
+ c->year = t;
+
+ /* t3 = month + day; separate */
+ t = LEAPYEAR(t);
+ for (t2 = 1; t2 < 12; t2++)
+ if (t3 < dayyr[t2] + (t && t2 > 1))
+ break;
+
+ /* t2 is month */
+ c->mon = t2;
+ c->day = t3 - dayyr[t2 - 1] + 1;
+ if (t && t2 > 2)
+ c->day--;
+
+ /* the rest is easy */
+ t = now % SECDAY;
+ c->hour = t / 3600;
+ t %= 3600;
+ c->min = t / 60;
+ c->sec = t % 60;
+
+ c->sec = TOBCD(c->sec);
+ c->min = TOBCD(c->min);
+ c->hour = TOBCD(c->hour);
+ c->day = TOBCD(c->day);
+ c->mon = TOBCD(c->mon);
+ c->year = TOBCD(c->year - YEAR0);
+}
+
+/*
+ * Set up the system's time, given a `reasonable' time value.
+ */
+void
+inittodr(time_t base)
+{
+ register struct nvramsoftc *sc;
+ register volatile struct clockreg *cl;
+ int sec, min, hour, day, mon, year;
+ int badbase = 0, waszero = base == 0;
+
+ sc = (struct nvramsoftc *)nvram_cd.cd_devs[0];
+ cl = sc->sc_clockreg;
+
+ if (base < 5 * SECYR) {
+ /*
+ * If base is 0, assume filesystem time is just unknown
+ * in stead of preposterous. Don't bark.
+ */
+ if (base != 0)
+ printf("WARNING: preposterous time in file system\n");
+ /* not going to use it anyway, if the chip is readable */
+ base = 21*SECYR + 186*SECDAY + SECDAY/2;
+ badbase = 1;
+ }
+
+ 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 */
+
+ time.tv_sec = chiptotime(sec, min, hour, day, mon, year);
+
+ if (time.tv_sec == 0) {
+ printf("WARNING: bad date in battery clock");
+ /*
+ * Believe the time in the file system for lack of
+ * anything better, resetting the clock.
+ */
+ time.tv_sec = base;
+ if (!badbase)
+ resettodr();
+ } else {
+ int deltat = time.tv_sec - base;
+
+ if (deltat < 0)
+ deltat = -deltat;
+ if (waszero || deltat < 2 * SECDAY)
+ return;
+ printf("WARNING: clock %s %d days",
+ time.tv_sec < base ? "lost" : "gained", deltat / SECDAY);
+ }
+ printf(" -- CHECK AND RESET THE DATE!\n");
+}
+
+/*
+ * Reset the clock based on the current time.
+ * Used when the current clock is preposterous, when the time is changed,
+ * and when rebooting. Do nothing if the time is not yet known, e.g.,
+ * when crashing during autoconfig.
+ */
+void
+resettodr()
+{
+ register struct nvramsoftc *sc;
+ register volatile struct clockreg *cl;
+ struct chiptime c;
+
+ sc = (struct nvramsoftc *)nvram_cd.cd_devs[0];
+
+ if (!time.tv_sec || (cl = sc->sc_clockreg) == NULL)
+ return;
+ timetochip(&c);
+
+ cl->cl_csr |= CLK_WRITE; /* enable write */
+ cl->cl_sec = c.sec;
+ cl->cl_min = c.min;
+ cl->cl_hour = c.hour;
+ cl->cl_wday = c.wday;
+ cl->cl_mday = c.day;
+ cl->cl_month = c.mon;
+ cl->cl_year = c.year;
+ cl->cl_csr &= ~CLK_WRITE; /* load them up */
+}
--- /dev/null
+/*
+ * 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
+ */
+
+/*
+ * mvme1x7 Mostek TOD clock/NVRAM
+ */
+
+/*
+ * Mostek MK48T08 clock.
+ *
+ * This chip is 8k in size.
+ * The first TOD clock starts at offset 0x1FF8. The following structure
+ * describes last 2K of it's 8K address space. The first 6K of the NVRAM
+ * space is used for various things as follows:
+ * 0000-0fff User Area
+ * 1000-10ff Networking Area
+ * 1100-16f7 Operating System Area
+ * 16f8-1ef7 ROM Debugger Area
+ * 1ef8-1ff7 Configuration Area (Ethernet address etc)
+ * 1ff8-1fff TOD 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) */
+
+struct clockreg *clockreg;
+
+/*
+ * Motorola chose the year `00' as their base count, so that
+ * cl_year == 0 means 1900.
+ */
+#define YEAR0 00
+
+#define NVRAMSIZE 0x8000
+#define NVRAM_TOD_OFF 0x1ff8 /* offset of tod in NVRAM space */
--- /dev/null
+/*
+ * Memory map for PCC2 chip found in mvme1x7 boards.
+ *
+ * PCCchip2 control and status register can be accessed as bytes (8 bits),
+ * two-bytes (16 bits), or four-bytes (32 bits).
+ */
+
+struct pcc2reg {
+ volatile u_char pcc2_chipid;
+ volatile u_char pcc2_chiprev;
+ volatile u_char pcc2_gcr;
+ volatile u_char pcc2_vbr; /* vector base reg. */
+ volatile u_long pcc2_t1cmp; /* timer1 compare reg */
+ volatile u_long pcc2_t1cntr; /* timer1 counter reg */
+ volatile u_long pcc2_t2cmp; /* timer2 compare reg */
+ volatile u_long pcc2_t2cntr; /* timer2 counter reg */
+ volatile u_char pcc2_pscntreg; /* prescalar count reg */
+ volatile u_char pcc2_psclkadj; /* clock adjust reg */
+ volatile u_char pcc2_t2ctl; /* timer2 control */
+ volatile u_char pcc2_t1ctl; /* timer1 control */
+ volatile u_char pcc2_gpiirq; /* GPIO intr ctl */
+ volatile u_char pcc2_gpiopctl; /* GPIO pin control */
+ volatile u_char pcc2_t2irq; /* Timer2 intr ctl */
+ volatile u_char pcc2_t1irq; /* Timer1 intr ctl */
+ volatile u_char pcc2_sccerrstat; /* SCC error status */
+ volatile u_char pcc2_sccmoirq; /* Modem intr control */
+ volatile u_char pcc2_scctxirq; /* Tx intr control */
+ volatile u_char pcc2_sccrxirq; /* Rx intr control */
+ volatile u_int :24;
+ volatile u_char pcc2_sccmopiack; /* modem PIACK */
+ volatile u_char :8;
+ volatile u_char pcc2_scctxpiack; /* Tx PIACK */
+ volatile u_char :8;
+ volatile u_char pcc2_sccrxpiack; /* Rx PIACK */
+ volatile u_char pcc2_lancerrstat; /* LANC error status */
+ volatile u_char :8;
+ volatile u_char pcc2_lancirq; /* LANC intr control */
+ volatile u_char pcc2_lancerrirq; /* LANC err intr ctl */
+ volatile u_char pcc2_scsierrstat; /* SCSI err status */
+ volatile u_char :8;
+ volatile u_char :8;
+ volatile u_char pcc2_scsiirq; /* SCSI intr control */
+ volatile u_char pcc2_packirq; /* printer ACK intr */
+ volatile u_char pcc2_pfltirq; /* printer FAULT intr */
+ volatile u_char pcc2_pselirq; /* printer SEL intr */
+ volatile u_char pcc2_ppeirq; /* printer PE intr */
+ volatile u_char pcc2_pbusyirq; /* printer BUSY intr */
+ volatile u_char :8;
+ volatile u_char pcc2_pstat; /* printer status reg */
+ volatile u_char pcc2_pctl; /* printer port ctl */
+ volatile u_short pcc2_chipspeed; /* chip speed (factory testing only) */
+ volatile u_short pcc2_pdata; /* printer data */
+ volatile u_int :16;
+ volatile u_char pcc2_ipl; /* interrupt IPL */
+ volatile u_char pcc2_imask; /* intr mask level */
+};
+
+/*
+ * Vaddrs for interrupt mask and pri registers
+ */
+extern volatile u_char *pcc2intr_mask;
+extern volatile u_char *pcc2intr_ipl;
+
+extern volatile struct pcc2reg *pcc2addr;
+
+#define PCC2_BASE_ADDR 0xFFF42000 /* base address */
+#define PCC2_SIZE 0x1000 /* size */
+
+#define PCC2_CHIP_ID 0x20
+#define PCC2_CHIP_REV 0x00
+
+/* General Control Register */
+
+#define PCC2_DR0 0x80
+#define PCC2_C040 0x04
+#define PCC2_MIEN 0x02
+#define PCC2_FAST 0x01
+
+/* Top 4 bits of the PCC2 VBR. Will be the top 4 bits of the vector */
+
+#define PCC2_VECT 0x50
+
+/* Bottom 4 bits of the vector returned during IACK cycle */
+#define PPBSY 0x00 /* lowest */
+#define PPSE 0x01
+#define PPSEL 0x02
+#define PPFLT 0x03
+#define PPACK 0x04
+#define SCSIIRQ 0x05
+#define LANCERR 0x06
+#define LANCIRQ 0x07
+#define TIMER1IRQ 0x08
+#define TIMER2IRQ 0x09
+#define GPIOIRQ 0x0a
+#define SRXEIRQ 0x0c
+#define SMOIRQ 0x0d
+#define STxIRQ 0x0e
+#define SRxIRQ 0x0f
+
+/*
+ * Timer control regs
+ */
+
+#define PCC2_TICTL_CEN 0x01
+#define PCC2_TICTL_COC 0x02
+#define PCC2_TICTL_COVF 0x04
+#define PCC2_TTCTL_OVF_MASK (1 << 4) /* overflow bits mask */
+
+/* GPIO interrupt control */
+
+#define PCC2_GPIIRQ_PLTY 0x80
+#define PCC2_GPIIRQ_EL 0x40
+#define PCC2_GPIIRQ_INT 0x20
+#define PCC2_GPIIRQ_IEN 0x10
+#define PCC2_GPIIRQ_ICLR 0x08
+#define PCC2_GPIIRQ_IL 0x07 /* IL2-IL0 */
+
+/* GPIO Pin Control Register */
+
+#define PCC2_GPIOPCTL_GPI 0x04
+#define PCC2_GPIOPCTL_GPOE 0x02
+#define PCC2_GPIOPCTL_GPO 0x01
+
+/* Tick Timer Interrupt Control Register */
+
+#define PCC2_TTIRQ_INT 0x20
+#define PCC2_TTIRQ_IEN 0x10
+#define PCC2_TTIRQ_ICLR 0x08
+#define PCC2_TTIRQ_IL 0x07 /* mask for IL2-IL0 */
+
+/* SCC Error Status Register */
+
+#define PCC2_SCCERRSTAT_RTRY 0x10
+#define PCC2_SCCERRSTAT_PRTY 0x08
+#define PCC2_SCCERRSTAT_EXT 0x04
+#define PCC2_SCCERRSTAT_LTO 0x02
+#define PCC2_SCCERRSTAT_SCLR 0x01
+
+/* SCC Modem Interrupt Control Register */
+
+#define PCC2_SCCMOIRQ_IRQ 0x20
+#define PCC2_SCCMOIRQ_IEN 0x10
+#define PCC2_SCCMOIRQ_AVEC 0x08
+#define PCC2_SCCMOIRQ_IL 0x07 /* int level mask */
+
+/* SCC Tx Interrupt Control Register */
+
+#define PCC2_SCCTXIRQ_IRQ 0x20
+#define PCC2_SCCTXIRQ_IEN 0x10
+#define PCC2_SCCTXIRQ_AVEC 0x08
+#define PCC2_SCCTXIRQ_IL 0x07
+
+/* SCC Tx Interrupt Control Register */
+
+#define PCC2_SCCRXIRQ_SNOOP (1 << 6)
+#define PCC2_SCCRXIRQ_IRQ 0x20
+#define PCC2_SCCRXIRQ_IEN 0x10
+#define PCC2_SCCRXIRQ_AVEC 0x08
+#define PCC2_SCCRXIRQ_IL 0x07
+
+/* SCSI Interrupt Control Register */
+
+#define PCC2_SCSIIRQ_IEN 0x10
+
+/* Interrupt Priority Level Register */
+
+#define PCC2_IPL_IPL 0x07
+
+/* Interrupt Mask Level Register */
+
+#define PCC2_IMASK_MSK 0x07
+
+#define PCC2_IRQ_IPL 0x07
+#define PCC2_IRQ_ICLR 0x08
+#define PCC2_IRQ_IEN 0x10
+#define PCC2_IRQ_INT 0x20
+
+#define PCC2_IEERR_SCLR 0x01
--- /dev/null
+/* $NetBSD: siop.c,v 1.23 1995/08/18 15:28:08 chopps Exp $ */
+
+/*
+ * Copyright (c) 1994 Michael L. Hitch
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Van Jacobson of Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)siop.c 7.5 (Berkeley) 5/4/91
+ */
+
+/*
+ * 53C710 scsi adaptor driver
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/disklabel.h>
+#include <sys/dkstat.h>
+#include <sys/buf.h>
+#include <sys/malloc.h>
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+#include <machine/autoconf.h>
+#if defined(MVME187)
+#include <mvme88k/dev/siopreg.h>
+#include <mvme88k/dev/siopvar.h>
+#else
+#include <mvme68k/dev/siopreg.h>
+#include <mvme68k/dev/siopvar.h>
+#endif /* MVME187 */
+
+#if defined(MVME187)
+#include "machine/mmu.h"
+#endif /* defined(MVME187) */
+
+
+extern u_int kvtop();
+
+/*
+ * SCSI delays
+ * In u-seconds, primarily for state changes on the SPC.
+ */
+#define SCSI_CMD_WAIT 500000 /* wait per step of 'immediate' cmds */
+#define SCSI_DATA_WAIT 500000 /* wait per data in/out step */
+#define SCSI_INIT_WAIT 500000 /* wait per step (both) during init */
+
+void siop_select __P((struct siop_softc *));
+void siopabort __P((struct siop_softc *, siop_regmap_p, char *));
+void sioperror __P((struct siop_softc *, siop_regmap_p, u_char));
+void siopstart __P((struct siop_softc *));
+int siop_checkintr __P((struct siop_softc *, u_char, u_char, u_char, int *));
+void siopreset __P((struct siop_softc *));
+void siopsetdelay __P((int));
+void siop_scsidone __P((struct siop_acb *, int));
+void siop_sched __P((struct siop_softc *));
+int siop_poll __P((struct siop_softc *, struct siop_acb *));
+void siopintr __P((struct siop_softc *));
+void scsi_period_to_siop __P((struct siop_softc *, int));
+void siop_start __P((struct siop_softc *, int, int, u_char *, int, u_char *, int));
+void siop_dump_acb __P((struct siop_acb *));
+
+/* 53C710 script */
+const
+#if defined(MVME187)
+#include <mvme88k/dev/siop_script.out>
+#else
+#include <mvme68k/dev/siop_script.out>
+#endif /* MVME187 */
+
+u_long scsi_nosync = 0;
+int shift_nosync;
+
+/* default to not inhibit sync negotiation on any drive */
+u_char siop_inhibit_sync[8] = { 0, 0, 0, 0, 0, 0, 0 }; /* initialize, so patchable */
+u_char siop_allow_disc[8] = {3, 3, 3, 3, 3, 3, 3, 3};
+int siop_no_dma = 0;
+
+int siop_reset_delay = 250; /* delay after reset, in milleseconds */
+
+int siop_cmd_wait = SCSI_CMD_WAIT;
+int siop_data_wait = SCSI_DATA_WAIT;
+int siop_init_wait = SCSI_INIT_WAIT;
+
+#ifdef DEBUG_SYNC
+/*
+ * sync period transfer lookup - only valid for 66Mhz clock
+ */
+static struct {
+ unsigned char p; /* period from sync request message */
+ unsigned char r; /* siop_period << 4 | sbcl */
+} sync_tab[] = {
+ { 60/4, 0<<4 | 1},
+ { 76/4, 1<<4 | 1},
+ { 92/4, 2<<4 | 1},
+ { 92/4, 0<<4 | 2},
+ {108/4, 3<<4 | 1},
+ {116/4, 1<<4 | 2},
+ {120/4, 4<<4 | 1},
+ {120/4, 0<<4 | 3},
+ {136/4, 5<<4 | 1},
+ {140/4, 2<<4 | 2},
+ {152/4, 6<<4 | 1},
+ {152/4, 1<<4 | 3},
+ {164/4, 3<<4 | 2},
+ {168/4, 7<<4 | 1},
+ {180/4, 2<<4 | 3},
+ {184/4, 4<<4 | 2},
+ {208/4, 5<<4 | 2},
+ {212/4, 3<<4 | 3},
+ {232/4, 6<<4 | 2},
+ {240/4, 4<<4 | 3},
+ {256/4, 7<<4 | 2},
+ {272/4, 5<<4 | 3},
+ {300/4, 6<<4 | 3},
+ {332/4, 7<<4 | 3}
+};
+#endif
+
+#ifdef DEBUG
+/*
+ * 0x01 - full debug
+ * 0x02 - DMA chaining
+ * 0x04 - siopintr
+ * 0x08 - phase mismatch
+ * 0x10 - <not used>
+ * 0x20 - panic on unhandled exceptions
+ * 0x100 - disconnect/reselect
+ */
+int siop_debug = 0;
+int siopsync_debug = 0;
+int siopdma_hits = 0;
+int siopdma_misses = 0;
+int siopchain_ints = 0;
+int siopstarts = 0;
+int siopints = 0;
+int siopphmm = 0;
+#define SIOP_TRACE_SIZE 128
+#define SIOP_TRACE(a,b,c,d) \
+ siop_trbuf[siop_trix] = (a); \
+ siop_trbuf[siop_trix+1] = (b); \
+ siop_trbuf[siop_trix+2] = (c); \
+ siop_trbuf[siop_trix+3] = (d); \
+ siop_trix = (siop_trix + 4) & (SIOP_TRACE_SIZE - 1);
+u_char siop_trbuf[SIOP_TRACE_SIZE];
+int siop_trix;
+void siop_dump __P((struct siop_softc *));
+void siop_dump_trace __P((void));
+#else
+#define SIOP_TRACE(a,b,c,d)
+#endif
+
+int kludge_city = 1;
+
+/*
+ * default minphys routine for siop based controllers
+ */
+void
+siop_minphys(bp)
+ struct buf *bp;
+{
+
+ /*
+ * No max transfer at this level.
+ */
+ minphys(bp);
+}
+
+/*
+ * used by specific siop controller
+ *
+ */
+int
+siop_scsicmd(xs)
+ struct scsi_xfer *xs;
+{
+ struct siop_acb *acb;
+ struct siop_softc *sc;
+ struct scsi_link *slp;
+ int flags, s;
+
+ slp = xs->sc_link;
+ sc = slp->adapter_softc;
+ flags = xs->flags;
+
+ /* XXXX ?? */
+ if (flags & SCSI_DATA_UIO)
+ panic("siop: scsi data uio requested");
+
+ /* XXXX ?? */
+ if (sc->sc_nexus && flags & SCSI_POLL)
+/* panic("siop_scsicmd: busy");*/
+ printf("siop_scsicmd: busy\n");
+
+ s = splbio();
+ acb = sc->free_list.tqh_first;
+ if (acb) {
+ TAILQ_REMOVE(&sc->free_list, acb, chain);
+ }
+ splx(s);
+
+ if (acb == NULL) {
+ xs->error = XS_DRIVER_STUFFUP;
+ return(TRY_AGAIN_LATER);
+ }
+
+ acb->flags = ACB_ACTIVE;
+ acb->xs = xs;
+ bcopy(xs->cmd, &acb->cmd, xs->cmdlen);
+ acb->clen = xs->cmdlen;
+ acb->daddr = xs->data;
+ acb->dleft = xs->datalen;
+
+#if defined(MVME187)
+ /*
+ * Since the 187 doesn't support cache snooping, we have
+ * to flush the cache for a write and flush with inval for
+ * a read, prior to starting the IO.
+ * We should move this siop_sched() XXX
+ */
+ if (xs->flags & SCSI_DATA_IN) { /* read */
+ dma_cachectl((vm_offset_t)xs->data, xs->datalen,
+ DMA_CACHE_SYNC_INVAL);
+ } else { /* write */
+ dma_cachectl((vm_offset_t)xs->data, xs->datalen,
+ DMA_CACHE_SYNC);
+ }
+#endif
+ s = splbio();
+ TAILQ_INSERT_TAIL(&sc->ready_list, acb, chain);
+
+ if (sc->sc_nexus == NULL)
+ siop_sched(sc);
+
+ splx(s);
+
+ if (flags & SCSI_POLL || siop_no_dma)
+ return(siop_poll(sc, acb));
+ return(SUCCESSFULLY_QUEUED);
+}
+
+int
+siop_poll(sc, acb)
+ struct siop_softc *sc;
+ struct siop_acb *acb;
+{
+ siop_regmap_p rp = sc->sc_siopp;
+ struct scsi_xfer *xs = acb->xs;
+ int i;
+ int status;
+ u_char istat;
+ u_char dstat;
+ u_char sstat0;
+ int s;
+ int to;
+
+ s = splbio();
+ to = xs->timeout / 1000;
+ if (sc->nexus_list.tqh_first)
+ printf("%s: siop_poll called with disconnected device\n",
+ sc->sc_dev.dv_xname);
+ for (;;) {
+ /* use cmd_wait values? */
+ i = 50000;
+ spl0();
+ while (((istat = rp->siop_istat) &
+ (SIOP_ISTAT_SIP | SIOP_ISTAT_DIP)) == 0) {
+ if (--i <= 0) {
+#ifdef DEBUG
+ printf ("waiting: tgt %d cmd %02x sbcl %02x dsp %lx (+%lx) dcmd %lx ds %p timeout %d\n",
+ xs->sc_link->target, acb->cmd.opcode,
+ rp->siop_sbcl, rp->siop_dsp,
+ rp->siop_dsp - sc->sc_scriptspa,
+ *((long *)&rp->siop_dcmd), &acb->ds, acb->xs->timeout);
+#endif
+ i = 50000;
+ --to;
+ if (to <= 0) {
+ siopreset(sc);
+ return(COMPLETE);
+ }
+ }
+ delay(10);
+ }
+ sstat0 = rp->siop_sstat0;
+ delay(10);
+ dstat = rp->siop_dstat;
+ if (siop_checkintr(sc, istat, dstat, sstat0, &status)) {
+ if (acb != sc->sc_nexus)
+ printf("%s: siop_poll disconnected device completed\n",
+ sc->sc_dev.dv_xname);
+ else if ((sc->sc_flags & SIOP_INTDEFER) == 0) {
+ sc->sc_flags &= ~SIOP_INTSOFF;
+ rp->siop_sien = sc->sc_sien;
+ rp->siop_dien = sc->sc_dien;
+ }
+ siop_scsidone(sc->sc_nexus, status);
+ }
+ if (xs->flags & ITSDONE)
+ break;
+ }
+ splx(s);
+ return (COMPLETE);
+}
+
+/*
+ * start next command that's ready
+ */
+void
+siop_sched(sc)
+ struct siop_softc *sc;
+{
+ struct scsi_link *slp;
+ struct siop_acb *acb;
+ int i;
+
+#ifdef DEBUG
+ if (sc->sc_nexus) {
+ printf("%s: siop_sched- nexus %p/%d ready %p/%d\n",
+ sc->sc_dev.dv_xname, sc->sc_nexus,
+ sc->sc_nexus->xs->sc_link->target,
+ sc->ready_list.tqh_first,
+ sc->ready_list.tqh_first->xs->sc_link->target);
+ return;
+ }
+#endif
+ for (acb = sc->ready_list.tqh_first; acb; acb = acb->chain.tqe_next) {
+ slp = acb->xs->sc_link;
+ i = slp->target;
+ if(!(sc->sc_tinfo[i].lubusy & (1 << slp->lun))) {
+ struct siop_tinfo *ti = &sc->sc_tinfo[i];
+
+ TAILQ_REMOVE(&sc->ready_list, acb, chain);
+ sc->sc_nexus = acb;
+ slp = acb->xs->sc_link;
+ ti = &sc->sc_tinfo[slp->target];
+ ti->lubusy |= (1 << slp->lun);
+ break;
+ }
+ }
+
+ if (acb == NULL) {
+#ifdef DEBUGXXX
+ printf("%s: siop_sched didn't find ready command\n",
+ sc->sc_dev.dv_xname);
+#endif
+ return;
+ }
+
+ if (acb->xs->flags & SCSI_RESET)
+ siopreset(sc);
+
+#if 0
+ acb->cmd.bytes[0] |= slp->lun << 5; /* XXXX */
+#endif
+ ++sc->sc_active;
+ siop_select(sc);
+}
+
+void
+siop_scsidone(acb, stat)
+ struct siop_acb *acb;
+ int stat;
+{
+ struct scsi_xfer *xs;
+ struct scsi_link *slp;
+ struct siop_softc *sc;
+ int dosched = 0;
+
+ if (acb == NULL || (xs = acb->xs) == NULL) {
+#ifdef DIAGNOSTIC
+ printf("siop_scsidone: NULL acb or scsi_xfer\n");
+#if defined(DEBUG) && defined(DDB)
+ Debugger();
+#endif
+#endif
+ return;
+ }
+ slp = xs->sc_link;
+ sc = slp->adapter_softc;
+ /*
+ * is this right?
+ */
+ xs->status = stat;
+
+ if (xs->error == XS_NOERROR && !(acb->flags & ACB_CHKSENSE)) {
+ if (stat == SCSI_CHECK) {
+ struct scsi_sense *ss = (void *)&acb->cmd;
+ bzero(ss, sizeof(*ss));
+ ss->opcode = REQUEST_SENSE;
+ ss->byte2 = slp->lun << 5;
+ ss->length = sizeof(struct scsi_sense_data);
+ acb->clen = sizeof(*ss);
+ acb->daddr = (char *)&xs->sense;
+ acb->dleft = sizeof(struct scsi_sense_data);
+ acb->flags = ACB_ACTIVE | ACB_CHKSENSE;
+ TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
+ --sc->sc_active;
+ sc->sc_tinfo[slp->target].lubusy &=
+ ~(1 << slp->lun);
+ sc->sc_tinfo[slp->target].senses++;
+ if (sc->sc_nexus == acb) {
+ sc->sc_nexus = NULL;
+ siop_sched(sc);
+ }
+ SIOP_TRACE('d','s',0,0)
+ return;
+ }
+ }
+ if (xs->error == XS_NOERROR && (acb->flags & ACB_CHKSENSE)) {
+ xs->error = XS_SENSE;
+ } else {
+ xs->resid = 0; /* XXXX */
+ }
+#if whataboutthisone
+ case SCSI_BUSY:
+ xs->error = XS_BUSY;
+ break;
+#endif
+ xs->flags |= ITSDONE;
+
+ /*
+ * Remove the ACB from whatever queue it's on. We have to do a bit of
+ * a hack to figure out which queue it's on. Note that it is *not*
+ * necessary to cdr down the ready queue, but we must cdr down the
+ * nexus queue and see if it's there, so we can mark the unit as no
+ * longer busy. This code is sickening, but it works.
+ */
+ if (acb == sc->sc_nexus) {
+ sc->sc_nexus = NULL;
+ sc->sc_tinfo[slp->target].lubusy &= ~(1<<slp->lun);
+ if (sc->ready_list.tqh_first)
+ dosched = 1; /* start next command */
+ --sc->sc_active;
+ SIOP_TRACE('d','a',stat,0)
+ } else if (sc->ready_list.tqh_last == &acb->chain.tqe_next) {
+ TAILQ_REMOVE(&sc->ready_list, acb, chain);
+ SIOP_TRACE('d','r',stat,0)
+ } else {
+ register struct siop_acb *acb2;
+ for (acb2 = sc->nexus_list.tqh_first; acb2;
+ acb2 = acb2->chain.tqe_next)
+ if (acb2 == acb) {
+ TAILQ_REMOVE(&sc->nexus_list, acb, chain);
+ sc->sc_tinfo[slp->target].lubusy
+ &= ~(1<<slp->lun);
+ --sc->sc_active;
+ break;
+ }
+ if (acb2)
+ ;
+ else if (acb->chain.tqe_next) {
+ TAILQ_REMOVE(&sc->ready_list, acb, chain);
+ --sc->sc_active;
+ } else {
+ printf("%s: can't find matching acb\n",
+ sc->sc_dev.dv_xname);
+#ifdef DDB
+/* Debugger(); */
+#endif
+ }
+ SIOP_TRACE('d','n',stat,0);
+ }
+ /* Put it on the free list. */
+ acb->flags = ACB_FREE;
+ TAILQ_INSERT_HEAD(&sc->free_list, acb, chain);
+
+ sc->sc_tinfo[slp->target].cmds++;
+
+ scsi_done(xs);
+
+ if (dosched && sc->sc_nexus == NULL)
+ siop_sched(sc);
+}
+
+void
+siopabort(sc, rp, where)
+ register struct siop_softc *sc;
+ siop_regmap_p rp;
+ char *where;
+{
+#ifdef fix_this
+ int i;
+#endif
+
+ printf ("%s: abort %s: dstat %02x, sstat0 %02x sbcl %02x\n",
+ sc->sc_dev.dv_xname,
+ where, rp->siop_dstat, rp->siop_sstat0, rp->siop_sbcl);
+
+ if (sc->sc_active > 0) {
+#ifdef TODO
+ SET_SBIC_cmd (rp, SBIC_CMD_ABORT);
+ WAIT_CIP (rp);
+
+ GET_SBIC_asr (rp, asr);
+ if (asr & (SBIC_ASR_BSY|SBIC_ASR_LCI))
+ {
+ /* ok, get more drastic.. */
+
+ SET_SBIC_cmd (rp, SBIC_CMD_RESET);
+ delay(25);
+ SBIC_WAIT(rp, SBIC_ASR_INT, 0);
+ GET_SBIC_csr (rp, csr); /* clears interrupt also */
+
+ return;
+ }
+
+ do
+ {
+ SBIC_WAIT (rp, SBIC_ASR_INT, 0);
+ GET_SBIC_csr (rp, csr);
+ }
+ while ((csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1)
+ && (csr != SBIC_CSR_CMD_INVALID));
+#endif
+
+ /* lets just hope it worked.. */
+#ifdef fix_this
+ for (i = 0; i < 2; ++i) {
+ if (sc->sc_iob[i].sc_xs && &sc->sc_iob[i] !=
+ sc->sc_cur) {
+ printf ("siopabort: cleanup!\n");
+ sc->sc_iob[i].sc_xs = NULL;
+ }
+ }
+#endif /* fix_this */
+/* sc->sc_active = 0; */
+ }
+}
+
+void
+siopinitialize(sc)
+ struct siop_softc *sc;
+{
+ int i;
+ u_int inhibit_sync;
+ extern u_long scsi_nosync;
+ extern int shift_nosync;
+
+ /*
+ * Need to check that scripts is on a long word boundary.
+ * Also should verify that dev doesn't span non-contiguous
+ * physical pages.
+ */
+
+ dma_cachectl((vm_offset_t)scripts, sizeof(scripts), DMA_CACHE_SYNC);
+
+ sc->sc_scriptspa = kvtop(scripts);
+
+ /*
+ * malloc sc_acb to ensure that DS is on a long word boundary.
+ */
+
+ MALLOC(sc->sc_acb, struct siop_acb *,
+ sizeof(struct siop_acb) * SIOP_NACB, M_DEVBUF, M_NOWAIT);
+ if (sc->sc_acb == NULL)
+ panic("siopinitialize: ACB malloc failed!");
+
+ sc->sc_tcp[1] = 1000 / sc->sc_clock_freq;
+ sc->sc_tcp[2] = 1500 / sc->sc_clock_freq;
+ sc->sc_tcp[3] = 2000 / sc->sc_clock_freq;
+ sc->sc_minsync = sc->sc_tcp[1]; /* in 4ns units */
+ if (sc->sc_minsync < 25)
+ sc->sc_minsync = 25;
+ if (sc->sc_clock_freq <= 25) {
+ sc->sc_dcntl |= 0x80; /* SCLK/1 */
+ sc->sc_tcp[0] = sc->sc_tcp[1];
+ } else if (sc->sc_clock_freq <= 37) {
+ sc->sc_dcntl |= 0x40; /* SCLK/1.5 */
+ sc->sc_tcp[0] = sc->sc_tcp[2];
+ } else if (sc->sc_clock_freq <= 50) {
+ sc->sc_dcntl |= 0x00; /* SCLK/2 */
+ sc->sc_tcp[0] = sc->sc_tcp[3];
+ } else {
+ sc->sc_dcntl |= 0xc0; /* SCLK/3 */
+ sc->sc_tcp[0] = 3000 / sc->sc_clock_freq;
+ }
+
+ if (scsi_nosync) {
+ inhibit_sync = (scsi_nosync >> shift_nosync) & 0xff;
+ shift_nosync += 8;
+#ifdef DEBUG
+ if (inhibit_sync)
+ printf("%s: Inhibiting synchronous transfer %02x\n",
+ sc->sc_dev.dv_xname, inhibit_sync);
+#endif
+ for (i = 0; i < 8; ++i)
+ if (inhibit_sync & (1 << i))
+ siop_inhibit_sync[i] = 1;
+ }
+
+ siopreset (sc);
+}
+
+void
+siopreset(sc)
+ struct siop_softc *sc;
+{
+ siop_regmap_p rp;
+ u_int i, s;
+ u_char dummy;
+ struct siop_acb *acb;
+
+ rp = sc->sc_siopp;
+
+ if (sc->sc_flags & SIOP_ALIVE)
+ siopabort(sc, rp, "reset");
+
+ printf("%s: ", sc->sc_dev.dv_xname); /* XXXX */
+
+ s = splbio();
+
+ /*
+ * Reset the chip
+ * XXX - is this really needed?
+ */
+ rp->siop_istat |= SIOP_ISTAT_ABRT; /* abort current script */
+ rp->siop_istat |= SIOP_ISTAT_RST; /* reset chip */
+ rp->siop_istat &= ~SIOP_ISTAT_RST;
+ /*
+ * Reset SCSI bus (do we really want this?)
+ */
+ rp->siop_sien = 0;
+ rp->siop_scntl1 |= SIOP_SCNTL1_RST;
+ delay(25);
+ rp->siop_scntl1 &= ~SIOP_SCNTL1_RST;
+
+ /*
+ * Set up various chip parameters
+ */
+ rp->siop_scntl0 = SIOP_ARB_FULL | SIOP_SCNTL0_EPC | SIOP_SCNTL0_EPG;
+ rp->siop_scntl1 = SIOP_SCNTL1_ESR;
+ rp->siop_dcntl = sc->sc_dcntl;
+ rp->siop_dmode = 0x80; /* burst length = 4 */
+ rp->siop_sien = 0x00; /* don't enable interrupts yet */
+ rp->siop_dien = 0x00; /* don't enable interrupts yet */
+ rp->siop_scid = 1 << sc->sc_link.adapter_target;
+ rp->siop_dwt = 0x00;
+ rp->siop_ctest0 = (SIOP_CTEST0_EAN|SIOP_CTEST0_BTD);
+ rp->siop_ctest7 = sc->sc_ctest7;
+
+ /* will need to re-negotiate sync xfers */
+ bzero(&sc->sc_sync, sizeof (sc->sc_sync));
+
+ i = rp->siop_istat;
+ if (i & SIOP_ISTAT_SIP)
+ dummy = rp->siop_sstat0;
+ delay(1);
+ if (i & SIOP_ISTAT_DIP)
+ dummy = rp->siop_dstat;
+
+ splx (s);
+
+ delay (siop_reset_delay * 1000);
+ printf("siop id %d reset V%d\n", sc->sc_link.adapter_target,
+ rp->siop_ctest8 >> 4);
+
+ if ((sc->sc_flags & SIOP_ALIVE) == 0) {
+ TAILQ_INIT(&sc->ready_list);
+ TAILQ_INIT(&sc->nexus_list);
+ TAILQ_INIT(&sc->free_list);
+ sc->sc_nexus = NULL;
+ acb = sc->sc_acb;
+ bzero(acb, sizeof(struct siop_acb) * SIOP_NACB);
+ for (i = 0; i < SIOP_NACB; i++) {
+
+ pmap_cache_ctrl(pmap_kernel(),
+ M88K_TRUNC_PAGE((vm_offset_t)acb),
+ M88K_ROUND_PAGE((vm_offset_t)acb+sizeof(*acb)),
+ CACHE_INH);
+
+ TAILQ_INSERT_TAIL(&sc->free_list, acb, chain);
+ acb++;
+ }
+ bzero(sc->sc_tinfo, sizeof(sc->sc_tinfo));
+ } else {
+ if (sc->sc_nexus != NULL) {
+ sc->sc_nexus->xs->error = XS_DRIVER_STUFFUP;
+ siop_scsidone(sc->sc_nexus, sc->sc_nexus->stat[0]);
+ }
+ while ((acb = sc->nexus_list.tqh_first) != 0) {
+ acb->xs->error = XS_DRIVER_STUFFUP;
+ siop_scsidone(acb, acb->stat[0]);
+ }
+ }
+
+ sc->sc_flags |= SIOP_ALIVE;
+ sc->sc_flags &= ~(SIOP_INTDEFER|SIOP_INTSOFF);
+ /* enable SCSI and DMA interrupts */
+ /* XXX turn on SEL interrupt? nivas */
+ sc->sc_sien = SIOP_SIEN_M_A | SIOP_SIEN_STO | /*SIOP_SIEN_SEL |*/ SIOP_SIEN_SGE |
+ SIOP_SIEN_UDC | SIOP_SIEN_RST | SIOP_SIEN_PAR;
+ sc->sc_dien = SIOP_DIEN_BF | SIOP_DIEN_ABRT | SIOP_DIEN_SIR |
+ /*SIOP_DIEN_WTD |*/ SIOP_DIEN_IID;
+ rp->siop_sien = sc->sc_sien;
+ rp->siop_dien = sc->sc_dien;
+}
+
+/*
+ * Setup Data Storage for 53C710 and start SCRIPTS processing
+ */
+
+void
+siop_start (sc, target, lun, cbuf, clen, buf, len)
+ struct siop_softc *sc;
+ int target;
+ int lun;
+ u_char *cbuf;
+ int clen;
+ u_char *buf;
+ int len;
+{
+ siop_regmap_p rp = sc->sc_siopp;
+ int nchain;
+ int count, tcount;
+ char *addr, *dmaend;
+ struct siop_acb *acb = sc->sc_nexus;
+#ifdef DEBUG
+ int i;
+#endif
+
+#ifdef DEBUG
+ if (siop_debug & 0x100 && rp->siop_sbcl & SIOP_BSY) {
+ printf ("ACK! siop was busy: rp %p script %p dsa %p active %ld\n",
+ rp, &scripts, &acb->ds, sc->sc_active);
+ printf ("istat %02x sfbr %02x lcrc %02x sien %02x dien %02x\n",
+ rp->siop_istat, rp->siop_sfbr, rp->siop_lcrc,
+ rp->siop_sien, rp->siop_dien);
+#ifdef DDB
+ /*Debugger();*/
+#endif
+ }
+#endif
+ acb->msgout[0] = MSG_IDENTIFY | lun;
+ if (siop_allow_disc[target] & 2 ||
+ (siop_allow_disc[target] && len == 0))
+ acb->msgout[0] = MSG_IDENTIFY_DR | lun;
+ acb->status = 0;
+ acb->stat[0] = -1;
+ acb->msg[0] = -1;
+ acb->ds.scsi_addr = (0x10000 << target) | (sc->sc_sync[target].sxfer << 8);
+ acb->ds.idlen = 1;
+ acb->ds.idbuf = (char *) kvtop(&acb->msgout[0]);
+ acb->ds.cmdlen = clen;
+ acb->ds.cmdbuf = (char *) kvtop(cbuf);
+ acb->ds.stslen = 1;
+ acb->ds.stsbuf = (char *) kvtop(&acb->stat[0]);
+ acb->ds.msglen = 1;
+ acb->ds.msgbuf = (char *) kvtop(&acb->msg[0]);
+ acb->msg[1] = -1;
+ acb->ds.msginlen = 1;
+ acb->ds.extmsglen = 1;
+ acb->ds.synmsglen = 3;
+ acb->ds.msginbuf = (char *) kvtop(&acb->msg[1]);
+ acb->ds.extmsgbuf = (char *) kvtop(&acb->msg[2]);
+ acb->ds.synmsgbuf = (char *) kvtop(&acb->msg[3]);
+ bzero(&acb->ds.chain, sizeof (acb->ds.chain));
+
+ if (sc->sc_sync[target].state == SYNC_START) {
+ if (siop_inhibit_sync[target]) {
+ sc->sc_sync[target].state = SYNC_DONE;
+ sc->sc_sync[target].sbcl = 0;
+ sc->sc_sync[target].sxfer = 0;
+#ifdef DEBUG
+ if (siopsync_debug)
+ printf ("Forcing target %d asynchronous\n", target);
+#endif
+ }
+ else {
+ acb->msg[2] = -1;
+ acb->msgout[1] = MSG_EXT_MESSAGE;
+ acb->msgout[2] = 3;
+ acb->msgout[3] = MSG_SYNC_REQ;
+#ifdef MAXTOR_SYNC_KLUDGE
+ acb->msgout[4] = 50 / 4; /* ask for ridiculous period */
+#else
+ acb->msgout[4] = sc->sc_minsync;
+#endif
+ acb->msgout[5] = SIOP_MAX_OFFSET;
+ acb->ds.idlen = 6;
+ sc->sc_sync[target].state = SYNC_SENT;
+#ifdef DEBUG
+ if (siopsync_debug)
+ printf ("Sending sync request to target %d\n", target);
+#endif
+ }
+ }
+
+/*
+ * Build physical DMA addresses for scatter/gather I/O
+ */
+ acb->iob_buf = buf;
+ acb->iob_len = len;
+ acb->iob_curbuf = acb->iob_curlen = 0;
+ nchain = 0;
+ count = len;
+ addr = buf;
+ dmaend = NULL;
+ while (count > 0) {
+ acb->ds.chain[nchain].databuf = (char *) kvtop (addr);
+ if (count < (tcount = NBPG - ((int) addr & PGOFSET)))
+ tcount = count;
+ acb->ds.chain[nchain].datalen = tcount;
+ addr += tcount;
+ count -= tcount;
+ if (acb->ds.chain[nchain].databuf == dmaend) {
+ dmaend += acb->ds.chain[nchain].datalen;
+ acb->ds.chain[nchain].datalen = 0;
+ acb->ds.chain[--nchain].datalen += tcount;
+#ifdef DEBUG
+ ++siopdma_hits;
+#endif
+ }
+ else {
+ dmaend = acb->ds.chain[nchain].databuf +
+ acb->ds.chain[nchain].datalen;
+ acb->ds.chain[nchain].datalen = tcount;
+#ifdef DEBUG
+ if (nchain) /* Don't count miss on first one */
+ ++siopdma_misses;
+#endif
+ }
+ ++nchain;
+ }
+#ifdef DEBUG
+ if (nchain != 1 && len != 0 && siop_debug & 3) {
+ printf ("DMA chaining set: %d\n", nchain);
+ for (i = 0; i < nchain; ++i) {
+ printf (" [%d] %8p %lx\n", i, acb->ds.chain[i].databuf,
+ acb->ds.chain[i].datalen);
+ }
+ }
+#endif
+
+#if CACHECTL
+ /* push data cache for all data the 53c710 needs to access */
+ dma_cachectl(sc, sizeof (struct siop_softc), DMA_CACHE_SYNC);
+ dma_cachectl(acb, sizeof (*acb), DMA_CACHE_SYNC);
+#endif
+ dma_cachectl((vm_offset_t)cbuf, clen, DMA_CACHE_SYNC);
+
+#if defined(MVME187)
+ /*
+ * Flushing the buf from data cache is very important for MVME187
+ * since the board does not snoop the local bus.
+ * We have to flush the cache for a write and flush with inval for
+ * a read.
+ */
+ if (buf != NULL && len != 0) {
+ if (acb->xs->flags & SCSI_DATA_IN) { /* read */
+ dma_cachectl((vm_offset_t)buf, len,
+ DMA_CACHE_SYNC_INVAL);
+ } else { /* write */
+ dma_cachectl((vm_offset_t)buf, len, DMA_CACHE_SYNC);
+ }
+ }
+#endif
+
+#ifdef DEBUG
+ if (siop_debug & 0x100 && rp->siop_sbcl & SIOP_BSY) {
+ printf ("ACK! siop was busy at start: rp %p script %p dsa %p active %ld\n",
+ rp, &scripts, &acb->ds, sc->sc_active);
+#ifdef DDB
+ /*Debugger();*/
+#endif
+ }
+#endif
+ if (sc->nexus_list.tqh_first == NULL) {
+ if (rp->siop_istat & SIOP_ISTAT_CON) {
+ printf("%s: siop_select while connected:RABSAMCI %x scntl_con %x\n",
+ sc->sc_dev.dv_xname,
+ rp->siop_sbcl, rp->siop_scntl1 & SIOP_SCNTL1_CON);
+ }
+
+ rp->siop_temp = 0;
+ rp->siop_sbcl = sc->sc_sync[target].sbcl;
+ rp->siop_dsa = kvtop(&acb->ds);
+ rp->siop_dsp = sc->sc_scriptspa;
+ SIOP_TRACE('s',1,0,0)
+ } else {
+ /*
+ * SIOP is waiting for a reselect. If it is not
+ * yet connected to the BUS, signal to change state.
+ * Else, leave it alone - later on, the reselect interrupt
+ * will take care of this request.
+ */
+ if ((rp->siop_istat & SIOP_ISTAT_CON) == 0) {
+ rp->siop_istat = SIOP_ISTAT_SIGP;
+ SIOP_TRACE('s',2,0,0);
+ }
+ else {
+ SIOP_TRACE('s',3,rp->siop_istat,0);
+ }
+ }
+#ifdef DEBUG
+ ++siopstarts;
+#endif
+}
+
+/*
+ * Process a DMA or SCSI interrupt from the 53C710 SIOP
+ */
+
+int
+siop_checkintr(sc, istat, dstat, sstat0, status)
+ struct siop_softc *sc;
+ u_char istat;
+ u_char dstat;
+ u_char sstat0;
+ int *status;
+{
+ siop_regmap_p rp = sc->sc_siopp;
+ struct siop_acb *acb = sc->sc_nexus;
+ int target = 0;
+ int dfifo, dbc, sstat1;
+ int dummy;
+
+ dfifo = rp->siop_dfifo;
+ dbc = rp->siop_dbc0;
+ sstat1 = rp->siop_sstat1;
+
+ /*
+ * Flush DMA and SCSI FIFOs.
+ */
+ rp->siop_ctest8 |= SIOP_CTEST8_CLF;
+ while ((rp->siop_ctest1 & SIOP_CTEST1_FMT) != SIOP_CTEST1_FMT)
+ ;
+
+#ifdef DEBUG
+ ++siopints;
+#if 0
+ if (siop_debug & 0x100) {
+ cmmu_inval_cache(kvtop(&acb->stat[0]), 1); /* XXX */
+ printf ("siopchkintr: istat %x dstat %x sstat0 %x dsps %x sbcl %x sts %x msg %x\n",
+ istat, dstat, sstat0, rp->siop_dsps, rp->siop_sbcl, acb->stat[0], acb->msg[0]);
+ printf ("sync msg in: %02x %02x %02x %02x %02x %02x\n",
+ acb->msg[0], acb->msg[1], acb->msg[2],
+ acb->msg[3], acb->msg[4], acb->msg[5]);
+ }
+#endif
+ if (rp->siop_dsp && (rp->siop_dsp < sc->sc_scriptspa ||
+ rp->siop_dsp >= sc->sc_scriptspa + sizeof(scripts))) {
+ printf ("%s: dsp not within script dsp %lx scripts %lx:%lx",
+ sc->sc_dev.dv_xname, rp->siop_dsp, sc->sc_scriptspa,
+ sc->sc_scriptspa + sizeof(scripts));
+ printf(" istat %x dstat %x sstat0 %x\n",
+ istat, dstat, sstat0);
+#ifdef DDB
+ Debugger();
+#endif
+ }
+#endif
+ SIOP_TRACE('i',dstat,istat,(istat&SIOP_ISTAT_DIP)?rp->siop_dsps&0xff:sstat0);
+ if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff00) {
+ /* Normal completion status, or check condition */
+#ifdef DEBUG
+ if (rp->siop_dsa != kvtop(&acb->ds)) {
+ printf ("siop: invalid dsa: %lx %x\n", rp->siop_dsa,
+ kvtop((caddr_t)&acb->ds));
+ panic("*** siop DSA invalid ***");
+ }
+#endif
+ if (acb == NULL) {
+ printf("%s: Command complete with no active command?\n",
+ sc->sc_dev.dv_xname);
+ return (0);
+ }
+
+ target = acb->xs->sc_link->target;
+ if (sc->sc_sync[target].state == SYNC_SENT) {
+#ifdef DEBUG
+ if (siopsync_debug)
+ printf ("sync msg in: %02x %02x %02x %02x %02x %02x\n",
+ acb->msg[0], acb->msg[1], acb->msg[2],
+ acb->msg[3], acb->msg[4], acb->msg[5]);
+#endif
+ if (acb->msg[1] == 0xff)
+ printf ("%s: target %d ignored sync request\n",
+ sc->sc_dev.dv_xname, target);
+ else if (acb->msg[1] == MSG_REJECT)
+ printf ("%s: target %d rejected sync request\n",
+ sc->sc_dev.dv_xname, target);
+ sc->sc_sync[target].state = SYNC_DONE;
+ sc->sc_sync[target].sxfer = 0;
+ sc->sc_sync[target].sbcl = 0;
+ if (acb->msg[2] == 3 &&
+ acb->msg[3] == MSG_SYNC_REQ &&
+ acb->msg[5] != 0) {
+#ifdef MAXTOR_KLUDGE
+ /*
+ * Kludge for my Maxtor XT8580S
+ * It accepts whatever we request, even
+ * though it won't work. So we ask for
+ * a short period than we can handle. If
+ * the device says it can do it, use 208ns.
+ * If the device says it can do less than
+ * 100ns, then we limit it to 100ns.
+ */
+ if (acb->msg[4] && acb->msg[4] < 100 / 4) {
+#ifdef DEBUG
+ printf ("%d: target %d wanted %dns period\n",
+ sc->sc_dev.dv_xname, target,
+ acb->msg[4] * 4);
+#endif
+ if (acb->msg[4] == 50 / 4)
+ acb->msg[4] = 208 / 4;
+ else
+ acb->msg[4] = 100 / 4;
+ }
+#endif /* MAXTOR_KLUDGE */
+ printf ("%s: target %d now synchronous, period=%dns, offset=%d\n",
+ sc->sc_dev.dv_xname, target,
+ acb->msg[4] * 4, acb->msg[5]);
+ scsi_period_to_siop (sc, target);
+ }
+ }
+#if CACHECTL
+ /*cmmu_inval_cache(kvtop(&acb->stat[0]), 1);*/
+ dma_cachectl(&acb->stat[0], 1);
+#endif
+ *status = acb->stat[0];
+#ifdef DEBUG
+ if (rp->siop_sbcl & SIOP_BSY) {
+ /*printf ("ACK! siop was busy at end: rp %x script %x dsa %x\n",
+ rp, &scripts, &acb->ds);*/
+#ifdef DDB
+ /*Debugger();*/
+#endif
+ }
+ if (acb->msg[0] != 0x00)
+ printf("%s: message was not COMMAND COMPLETE: %x\n",
+ sc->sc_dev.dv_xname, acb->msg[0]);
+#endif
+ if (sc->nexus_list.tqh_first)
+ rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect;
+ return 1;
+ }
+
+ if (dstat & SIOP_DSTAT_SIR && (rp->siop_dsps == 0xff01 ||
+ rp->siop_dsps == 0xff02)) {
+
+ if (acb == NULL) {
+ printf("%s: Disconnect with no active command?\n",
+ sc->sc_dev.dv_xname);
+ return (0);
+ }
+#ifdef DEBUG
+ if (siop_debug & 0x100)
+ printf ("%s: ID %02x disconnected TEMP %lx (+%lx) curbuf %lx curlen %lx buf %p len %lx dfifo %x dbc %x sstat1 %x starts %d acb %p\n",
+ sc->sc_dev.dv_xname, 1 << target, rp->siop_temp,
+ rp->siop_temp ? rp->siop_temp - sc->sc_scriptspa : 0,
+ acb->iob_curbuf, acb->iob_curlen,
+ acb->ds.chain[0].databuf, acb->ds.chain[0].datalen, dfifo, dbc, sstat1, siopstarts, acb);
+#endif
+ /*
+ * XXXX need to update iob_curbuf/iob_curlen to reflect
+ * current data transferred. If device disconnected in
+ * the middle of a DMA block, they should already be set
+ * by the phase change interrupt. If the disconnect
+ * occurs on a DMA block boundary, we have to figure out
+ * which DMA block it was.
+ */
+ if (acb->iob_len && rp->siop_temp) {
+ int n = rp->siop_temp - sc->sc_scriptspa;
+
+ if (acb->iob_curlen && acb->iob_curlen != acb->ds.chain[0].datalen)
+ printf("%s: iob_curbuf/len already set? n %x iob %lx/%lx chain[0] %p/%lx\n",
+ sc->sc_dev.dv_xname, n, acb->iob_curbuf, acb->iob_curlen,
+ acb->ds.chain[0].databuf, acb->ds.chain[0].datalen);
+ if (n < Ent_datain)
+ n = (n - Ent_dataout) / 16;
+ else
+ n = (n - Ent_datain) / 16;
+ if (n <= 0 && n > DMAMAXIO)
+ printf("TEMP invalid %d\n", n);
+ else {
+ acb->iob_curbuf = (u_long)acb->ds.chain[n].databuf;
+ acb->iob_curlen = acb->ds.chain[n].datalen;
+ }
+#ifdef DEBUG
+ if (siop_debug & 0x100) {
+ printf("%s: TEMP offset %d", sc->sc_dev.dv_xname, n);
+ printf(" curbuf %lx curlen %lx\n", acb->iob_curbuf,
+ acb->iob_curlen);
+ }
+#endif
+ }
+ /*
+ * If data transfer was interrupted by disconnect, iob_curbuf
+ * and iob_curlen should reflect the point of interruption.
+ * Adjust the DMA chain so that the data transfer begins
+ * at the appropriate place upon reselection.
+ * XXX This should only be done on save data pointer message?
+ */
+ if (acb->iob_curlen) {
+ int i, j;
+
+#ifdef DEBUG
+ if (siop_debug & 0x100)
+ printf ("%s: adjusting DMA chain\n",
+ sc->sc_dev.dv_xname);
+ if (rp->siop_dsps == 0xff02)
+ printf ("%s: ID %02x disconnected without Save Data Pointers\n",
+ sc->sc_dev.dv_xname, 1 << target);
+#endif
+ for (i = 0; i < DMAMAXIO; ++i) {
+ if (acb->ds.chain[i].datalen == 0)
+ break;
+ if (acb->iob_curbuf >= (long)acb->ds.chain[i].databuf &&
+ acb->iob_curbuf < (long)(acb->ds.chain[i].databuf +
+ acb->ds.chain[i].datalen))
+ break;
+ }
+ if (i >= DMAMAXIO || acb->ds.chain[i].datalen == 0) {
+ printf("couldn't find saved data pointer: ");
+ printf("curbuf %lx curlen %lx i %d\n",
+ acb->iob_curbuf, acb->iob_curlen, i);
+#ifdef DDB
+ Debugger();
+#endif
+ }
+#ifdef DEBUG
+ if (siop_debug & 0x100)
+ printf(" chain[0]: %p/%lx -> %lx/%lx\n",
+ acb->ds.chain[0].databuf,
+ acb->ds.chain[0].datalen,
+ acb->iob_curbuf,
+ acb->iob_curlen);
+#endif
+ acb->ds.chain[0].databuf = (char *)acb->iob_curbuf;
+ acb->ds.chain[0].datalen = acb->iob_curlen;
+ for (j = 1, ++i; i < DMAMAXIO && acb->ds.chain[i].datalen; ++i, ++j) {
+#ifdef DEBUG
+ if (siop_debug & 0x100)
+ printf(" chain[%d]: %p/%lx -> %p/%lx\n", j,
+ acb->ds.chain[j].databuf,
+ acb->ds.chain[j].datalen,
+ acb->ds.chain[i].databuf,
+ acb->ds.chain[i].datalen);
+#endif
+ acb->ds.chain[j].databuf = acb->ds.chain[i].databuf;
+ acb->ds.chain[j].datalen = acb->ds.chain[i].datalen;
+ }
+ if (j < DMAMAXIO)
+ acb->ds.chain[j].datalen = 0;
+#if CACHECTL
+ dma_cachectl(acb->ds.chain,
+ sizeof(acb->ds.chain));
+#endif
+ }
+ ++sc->sc_tinfo[target].dconns;
+ /*
+ * add nexus to waiting list
+ * clear nexus
+ * try to start another command for another target/lun
+ */
+ acb->status = sc->sc_flags & SIOP_INTSOFF;
+ sc->sc_nexus = NULL;
+ TAILQ_INSERT_HEAD(&sc->nexus_list, acb, chain);
+ /* start script to wait for reselect */
+ rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect;
+ if (sc->ready_list.tqh_first)
+ siop_sched(sc);
+ return (0);
+ }
+
+ if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff03) {
+
+ int reselid = rp->siop_scratch & 0x7f;
+ int reselun = rp->siop_sfbr & 0x07;
+
+ sc->sc_sstat1 = rp->siop_sbcl; /* XXXX save current SBCL */
+
+#ifdef DEBUG
+ if (siop_debug & 0x100)
+ printf ("%s: target ID %02x reselected dsps %lx\n",
+ sc->sc_dev.dv_xname, reselid,
+ rp->siop_dsps);
+ if ((rp->siop_sfbr & 0x80) == 0)
+ printf("%s: Reselect message in was not identify: %x\n",
+ sc->sc_dev.dv_xname, rp->siop_sfbr);
+#endif
+ /*
+ * If we were trying to start a command when the reselect
+ * occured, need to put it at the head of the ready list,
+ * mark target/lun unbusy and decrement sc_active count.
+ */
+ if (sc->sc_nexus) {
+#ifdef DEBUG
+ if (siop_debug & 0x100)
+ printf ("%s: reselect ID %02x w/active\n",
+ sc->sc_dev.dv_xname, reselid);
+#endif
+ TAILQ_INSERT_HEAD(&sc->ready_list, sc->sc_nexus, chain);
+ sc->sc_tinfo[sc->sc_nexus->xs->sc_link->target].lubusy
+ &= ~(1 << sc->sc_nexus->xs->sc_link->lun);
+ --sc->sc_active;
+ }
+ /*
+ * locate acb of reselecting device
+ * set sc->sc_nexus to acb
+ */
+ for (acb = sc->nexus_list.tqh_first; acb;
+ acb = acb->chain.tqe_next) {
+ if (reselid != (acb->ds.scsi_addr >> 16) ||
+ reselun != (acb->msgout[0] & 0x07))
+ continue;
+ TAILQ_REMOVE(&sc->nexus_list, acb, chain);
+ sc->sc_nexus = acb;
+ sc->sc_flags |= acb->status;
+ acb->status = 0;
+#if CACHECTL
+ dma_cachectl(&acb->stat[0], sizeof(acb->stat[0]));
+#endif
+ rp->siop_dsa = kvtop(&acb->ds);
+ rp->siop_sxfer = sc->sc_sync[acb->xs->sc_link->target].sxfer;
+ rp->siop_sbcl = sc->sc_sync[acb->xs->sc_link->target].sbcl;
+ break;
+ }
+ if (acb == NULL) {
+ printf("%s: target ID %02x reselect nexus_list %p\n",
+ sc->sc_dev.dv_xname, reselid,
+ sc->nexus_list.tqh_first);
+ panic("unable to find reselecting device");
+ }
+#if CACHECTL
+ dma_cachectl (acb, sizeof(*acb));
+#endif
+ rp->siop_temp = 0;
+ rp->siop_dsp = sc->sc_scriptspa + Ent_switch;
+ return (0);
+ }
+
+ if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff04) {
+
+ target = sc->sc_nexus->xs->sc_link->target;
+ rp->siop_temp = 0;
+ rp->siop_dsa = kvtop(&sc->sc_nexus->ds);
+ rp->siop_sxfer = sc->sc_sync[target].sxfer;
+ rp->siop_sbcl = sc->sc_sync[target].sbcl;
+ rp->siop_dsp = sc->sc_scriptspa;
+ return (0);
+ }
+
+ if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff06) {
+
+ if (acb == NULL)
+ printf("%s: Bad message-in with no active command?\n",
+ sc->sc_dev.dv_xname);
+ /* Unrecognized message in byte */
+#if CACHECTL
+ /*cmmu_inval_cache(kvtop(&acb->msg[1]), 1);*/
+ dma_cachectl (&acb->msg[1],1);
+#endif
+ printf ("%s: Unrecognized message in data sfbr %x msg %x sbcl %x\n",
+ sc->sc_dev.dv_xname, rp->siop_sfbr, acb->msg[1], rp->siop_sbcl);
+ siopreset (sc);
+ *status = -1;
+ return 0; /* siopreset has cleaned up */
+ }
+
+ if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff0a) {
+ /* Status phase wasn't followed by message in phase? */
+ printf ("%s: Status phase not followed by message in phase? sbcl %x sbdl %x\n",
+ sc->sc_dev.dv_xname, rp->siop_sbcl, rp->siop_sbdl);
+ if (rp->siop_sbcl == 0xa7) {
+ /* It is now, just continue the script? */
+ rp->siop_dcntl |= SIOP_DCNTL_STD;
+ return (0);
+ }
+
+ siopreset (sc);
+ *status = -1;
+ return 0; /* siopreset has cleaned up */
+ }
+
+ if (sstat0 & SIOP_SSTAT0_M_A) { /* Phase mismatch */
+
+#ifdef DEBUG
+ printf("%s: Phase mismatch - expecting %x got %x\n",
+ sc->sc_dev.dv_xname, rp->siop_dcmd & 0x07,
+ rp->siop_sstat2 & 0x07);
+ ++siopphmm;
+#endif
+ if (acb == NULL) {
+ printf("%s: Phase mismatch with no active command- expecting %x got %x\n",
+ sc->sc_dev.dv_xname,
+ *((long *)&rp->siop_dcmd) & 0x07000000,
+ rp->siop_sstat2 & 0x07);
+ goto bad_phase;
+ }
+
+ if (acb->iob_len) {
+ int adjust;
+ adjust = ((dfifo - (dbc & 0x7f)) & 0x7f);
+ if (sstat1 & SIOP_SSTAT1_ORF)
+ ++adjust;
+ if (sstat1 & SIOP_SSTAT1_OLF)
+ ++adjust;
+ /* XXX what's with this siop_dcmd here? nivas */
+ acb->iob_curlen = *((long *)&rp->siop_dcmd) & 0xffffff;
+ acb->iob_curlen += adjust;
+ acb->iob_curbuf = *((long *)&rp->siop_dnad) - adjust;
+#ifdef DEBUG
+ if (siop_debug & 0x100) {
+ int i;
+ printf ("Phase mismatch: curbuf %lx curlen %lx dfifo %x dbc %x sstat1 %x adjust %x sbcl %x starts %d acb %p\n",
+ acb->iob_curbuf, acb->iob_curlen, dfifo,
+ dbc, sstat1, adjust, rp->siop_sbcl, siopstarts, acb);
+ if (acb->ds.chain[1].datalen) {
+ for (i = 0; acb->ds.chain[i].datalen; ++i)
+ printf("chain[%d] addr %p len %lx\n",
+ i, acb->ds.chain[i].databuf,
+ acb->ds.chain[i].datalen);
+ }
+ }
+#endif
+#if 0
+ dma_cachectl(acb, sizeof(*acb), DMA_CACHE_SYNC);
+#endif
+ }
+#ifdef DEBUG
+ SIOP_TRACE('m',rp->siop_sbcl,(rp->siop_dsp>>8),rp->siop_dsp);
+ if (siop_debug & 9)
+ printf ("Phase mismatch: %x dsp +%lx dcmd %lx\n",
+ rp->siop_sbcl,
+ rp->siop_dsp - sc->sc_scriptspa,
+ *((long *)&rp->siop_dcmd));
+#endif
+ if ((rp->siop_sbcl & SIOP_REQ) == 0) {
+ printf ("Phase mismatch: REQ not asserted! %02x dsp %lx\n",
+ rp->siop_sbcl, rp->siop_dsp);
+#if defined(DEBUG) && defined(DDB)
+ Debugger();
+#endif
+ goto bad_phase;
+ }
+#if XXX
+ switch (rp->siop_sbcl & 7)
+#endif
+ switch (rp->siop_sstat2 & 7) {
+ case 0: /* data out */
+ case 1: /* data in */
+ case 2: /* command */
+ case 3: /* status */
+ case 6: /* message out */
+ case 7: /* message in */
+ rp->siop_dsp = sc->sc_scriptspa + Ent_switch;
+ break;
+ default:
+ goto bad_phase;
+ }
+ return 0;
+ }
+
+ if (sstat0 & SIOP_SSTAT0_STO) { /* SCSI bus time out */
+
+ if (acb == NULL) {
+ printf("%s: SCSI bus timeout with no active command?\n",
+ sc->sc_dev.dv_xname);
+ /*Debugger();*/
+ }
+
+ printf ("STO: scripts %x dsp %x dcmd %x dsps %x\n", sc->sc_scriptspa,
+ rp->siop_dsp, *((long *)&rp->siop_dcmd), rp->siop_dsps);
+
+ if ((istat & SIOP_ISTAT_CON) == 0) {
+ printf("selection of %x timeout\n", rp->siop_sdid);
+ } else if ((rp->siop_ctest0 & SIOP_CTEST0_BTD) == 0) {
+ printf("No SCSI activity for 250ms(ctest0 %x %x dsps %x)\n",
+ rp->siop_ctest0,
+ rp->siop_ctest0,
+ rp->siop_dsps);
+ } else {
+ printf("Waited > 250ms for disconnect\n");
+ }
+
+#ifdef DEBUG
+ printf ("scripts %x dsp %x dcmd %x\n", sc->sc_scriptspa,
+ rp->siop_dsp, *((long *)&rp->siop_dcmd));
+
+ printf("msg %x status %x\n", acb->msg[0], acb->stat[0]);
+
+ if (rp->siop_sbcl & SIOP_BSY) {
+ printf ("ACK! siop was busy at timeout: rp %p script %p dsa %p\n",
+ rp, &scripts, &acb->ds);
+ printf(" sbcl %x sdid %x istat %x dstat %x sstat0 %x\n",
+ rp->siop_sbcl, rp->siop_sdid, istat, dstat, sstat0);
+ if (!(rp->siop_sbcl & SIOP_BSY)) {
+ printf ("Yikes, it's not busy now!\n");
+#if 0
+ *status = -1;
+ if (sc->nexus_list.tqh_first)
+ rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect;
+ return 1;
+#endif
+ }
+
+ /*
+ * I am not sure if DCNTL_STD can be used to restart.
+ * The manual discusses this bit only for manual start
+ * mode and single step mode, which we are not using.
+ * I will give it a shot... nivas
+ */
+
+ if (kludge_city) {
+ dummy = rp->siop_dsp;
+ rp->siop_dsp = dummy;
+ } else {
+ rp->siop_dcntl |= SIOP_DCNTL_STD;
+ }
+ return (0);
+#ifdef DDB
+ Debugger();
+#endif
+ }
+#endif
+ if (rp->siop_sbcl & SIOP_BSY) {
+ if (!(rp->siop_sbcl & SIOP_BSY)) {
+ printf ("Yikes, it's not busy now!\n");
+ *status = -1;
+ if (sc->nexus_list.tqh_first)
+ rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect;
+ return 1;
+ }
+
+ rp->siop_dcntl |= SIOP_DCNTL_STD;
+
+ return 0;
+ }
+
+ *status = -1;
+ if (acb)
+ acb->xs->error = XS_SELTIMEOUT;
+ if (sc->nexus_list.tqh_first)
+ rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect;
+ return 1;
+ }
+
+ if (acb)
+ target = acb->xs->sc_link->target;
+ else
+ target = 7;
+
+ if (sstat0 & SIOP_SSTAT0_UDC) {
+#ifdef DEBUG
+ if (acb == NULL)
+ printf("%s: Unexpected disconnect with no active command?\n",
+ sc->sc_dev.dv_xname);
+ printf ("%s: target %d disconnected unexpectedly\n",
+ sc->sc_dev.dv_xname, target);
+#endif
+#if 0
+ siopabort (sc, rp, "siopchkintr");
+#endif
+ *status = STS_BUSY;
+ if (sc->nexus_list.tqh_first)
+ rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect;
+ return (acb != NULL);
+ }
+
+ if (sstat0 == 0 && dstat & SIOP_DSTAT_SIR) {
+#if CACHECTL
+ /*cmmu_inval_cache(kvtop(&acb->stat[0]), 1); */
+ /*cmmu_inval_cache(kvtop(&acb->msg[0]), 1); */
+ dma_cachectl (&acb->stat[0], 1);
+ dma_cachectl (&acb->msg[0], 1);
+#endif
+ printf ("SIOP interrupt: %lx sts %x msg %x %x sbcl %x\n",
+ rp->siop_dsps, acb->stat[0], acb->msg[0], acb->msg[1],
+ rp->siop_sbcl);
+ siopreset (sc);
+ *status = -1;
+ return 0; /* siopreset has cleaned up */
+ }
+
+ if (sstat0 & SIOP_SSTAT0_SGE)
+ printf ("SIOP: SCSI Gross Error\n");
+
+ if (sstat0 & SIOP_SSTAT0_PAR)
+ printf ("SIOP: Parity Error\n");
+
+ if (dstat & SIOP_DSTAT_IID) {
+ printf ("SIOP: Illegal instruction detected (dsp %x dcmd %x dsps %x)\n",
+ rp->siop_dsp, *((long *)&rp->siop_dcmd),
+ rp->siop_dsps);
+
+ if (*((long *)&rp->siop_dcmd) & 0xf8000000 == 0x48000000) { /* wait disconnect */
+ printf("SIOP was executing wait disconnect\n");
+ }
+ }
+
+bad_phase:
+#if XXX
+ /*
+ * temporary panic for unhandled conditions
+ * displays various things about the 53C710 status and registers
+ * then panics.
+ * XXXX need to clean this up to print out the info, reset, and continue
+ */
+ printf ("siopchkintr: target %x ds %p\n", target, &acb->ds);
+ printf ("scripts %lx ds %x rp %x dsp %lx dcmd %lx\n", sc->sc_scriptspa,
+ kvtop(&acb->ds), kvtop(rp), rp->siop_dsp,
+ *((long *)&rp->siop_dcmd));
+ printf ("siopchkintr: istat %x dstat %x sstat0 %x dsps %lx dsa %lx sbcl %x sts %x msg %x %x sfbr %x\n",
+ istat, dstat, sstat0, rp->siop_dsps, rp->siop_dsa,
+ rp->siop_sbcl, acb->stat[0], acb->msg[0], acb->msg[1], rp->siop_sfbr);
+#ifdef DEBUG
+ if (siop_debug & 0x20)
+ panic("siopchkintr: **** temp ****");
+#endif
+#ifdef DDB
+ Debugger ();
+#endif
+#endif /* XXX */
+
+ *status = -1;
+ siopreset (sc); /* hard reset */
+ return 0; /* siopreset cleaned up */
+}
+
+void
+siop_select(sc)
+ struct siop_softc *sc;
+{
+ siop_regmap_p rp;
+ struct siop_acb *acb = sc->sc_nexus;
+
+#ifdef DEBUG
+ if (siop_debug & 1)
+ printf ("%s: select ", sc->sc_dev.dv_xname);
+#endif
+
+ rp = sc->sc_siopp;
+ if (acb->xs->flags & SCSI_POLL || siop_no_dma) {
+ sc->sc_flags |= SIOP_INTSOFF;
+ sc->sc_flags &= ~SIOP_INTDEFER;
+ if ((rp->siop_istat & 0x08) == 0) {
+ rp->siop_sien = 0;
+ rp->siop_dien = 0;
+ }
+#if 0
+ } else if ((sc->sc_flags & SIOP_INTDEFER) == 0) {
+ sc->sc_flags &= ~SIOP_INTSOFF;
+ if ((rp->siop_istat & 0x08) == 0) {
+ rp->siop_sien = sc->sc_sien;
+ rp->siop_dien = sc->sc_dien;
+ }
+#endif
+ }
+#ifdef DEBUG
+ if (siop_debug & 1)
+ printf ("siop_select: target %x cmd %02x ds %p\n",
+ acb->xs->sc_link->target, acb->cmd.opcode,
+ &sc->sc_nexus->ds);
+#endif
+
+ siop_start(sc, acb->xs->sc_link->target, acb->xs->sc_link->lun,
+ (u_char *)&acb->cmd, acb->clen, acb->daddr, acb->dleft);
+
+ return;
+}
+
+/*
+ * 53C710 interrupt handler
+ */
+
+void
+siopintr (sc)
+ register struct siop_softc *sc;
+{
+ siop_regmap_p rp;
+ register u_char istat, dstat, sstat0;
+ int status;
+ int s = splbio();
+
+ istat = sc->sc_istat;
+ if ((istat & (SIOP_ISTAT_SIP | SIOP_ISTAT_DIP)) == 0) {
+ /* is this possible? we won't come here if there is not int!!! XXX */
+ splx(s);
+ return;
+ }
+
+ /* Got a valid interrupt on this device */
+ rp = sc->sc_siopp;
+ dstat = sc->sc_dstat;
+ sstat0 = sc->sc_sstat0;
+ if (dstat & SIOP_DSTAT_SIR)
+ sc->sc_intcode = rp->siop_dsps; /* XXX use sc_intcode instead of dsps */
+
+ /* Clear the copies in sc */
+ sc->sc_istat = 0;
+ sc->sc_dstat = 0;
+ sc->sc_sstat0 = 0;
+
+#ifdef DEBUG
+ if (siop_debug & 1)
+ printf ("%s: intr istat %x dstat %x sstat0 %x\n",
+ sc->sc_dev.dv_xname, istat, dstat, sstat0);
+ if (!sc->sc_active) {
+ printf ("%s: spurious interrupt? istat %x dstat %x sstat0 %x nexus %p status %x\n",
+ sc->sc_dev.dv_xname, istat, dstat, sstat0,
+ sc->sc_nexus, sc->sc_nexus ? sc->sc_nexus->stat[0] : 0);
+ }
+#endif
+
+#ifdef DEBUG
+ if (siop_debug & 5) {
+#if CACHECTL
+ /*cmmu_inval_cache(kvtop(&sc->sc_nexus->stat[0]),
+ sizeof(sc->sc_nexus->stat[0])); */
+ dma_cachectl(&sc->sc_nexus->stat[0],
+ sizeof(sc->sc_nexus->stat[0]));
+#endif
+ printf ("%s: intr istat %x dstat %x sstat0 %x dsps %x sbcl %x sts %x msg %x\n",
+ sc->sc_dev.dv_xname, istat, dstat, sstat0,
+ rp->siop_dsps, rp->siop_sbcl,
+ sc->sc_nexus->stat[0], sc->sc_nexus->msg[0]);
+ }
+#endif
+ if (sc->sc_flags & SIOP_INTDEFER) {
+ sc->sc_flags &= ~(SIOP_INTDEFER | SIOP_INTSOFF);
+ rp->siop_sien = sc->sc_sien;
+ rp->siop_dien = sc->sc_dien;
+ }
+ if (siop_checkintr (sc, istat, dstat, sstat0, &status)) {
+ if (status == 0xff)
+ printf ("siopintr: status == 0xff\n");
+ if ((sc->sc_flags & (SIOP_INTSOFF | SIOP_INTDEFER)) != SIOP_INTSOFF) {
+#if 0
+ if (rp->siop_sbcl & SIOP_BSY) {
+ printf ("%s: SCSI bus busy at completion",
+ sc->sc_dev.dv_xname);
+ printf(" targ %d sbcl %02x sfbr %x lcrc %02x dsp +%x\n",
+ sc->sc_nexus->xs->sc_link->target,
+ rp->siop_sbcl, rp->siop_sfbr, rp->siop_lcrc,
+ rp->siop_dsp - sc->sc_scriptspa);
+ }
+#endif
+ siop_scsidone(sc->sc_nexus, sc->sc_nexus ?
+ sc->sc_nexus->stat[0] : -1);
+ }
+ }
+ splx(s);
+}
+
+/*
+ * This is based on the Progressive Peripherals 33Mhz Zeus driver and will
+ * not be correct for other 53c710 boards.
+ * XXX fix this - nivas
+ */
+void
+scsi_period_to_siop (sc, target)
+ struct siop_softc *sc;
+ int target;
+{
+ int period, offset, sxfer, sbcl = 0;
+#ifdef DEBUG_SYNC
+ int i;
+#endif
+
+ period = sc->sc_nexus->msg[4];
+ offset = sc->sc_nexus->msg[5];
+#ifdef DEBUG_SYNC
+ sxfer = 0;
+ if (offset <= SIOP_MAX_OFFSET)
+ sxfer = offset;
+ for (i = 0; i < sizeof (sync_tab) / 2; ++i) {
+ if (period <= sync_tab[i].p) {
+ sxfer |= sync_tab[i].r & 0x70;
+ sbcl = sync_tab[i].r & 0x03;
+ break;
+ }
+ }
+ printf ("siop sync old: siop_sxfr %02x, siop_sbcl %02x\n", sxfer, sbcl);
+#endif
+ for (sbcl = 1; sbcl < 4; ++sbcl) {
+ sxfer = (period * 4 - 1) / sc->sc_tcp[sbcl] - 3;
+ if (sxfer >= 0 && sxfer <= 7)
+ break;
+ }
+ if (sbcl > 3) {
+ printf("siop sync: unable to compute sync params for period %dns\n",
+ period * 4);
+ /*
+ * XXX need to pick a value we can do and renegotiate
+ */
+ sxfer = sbcl = 0;
+ } else {
+ sxfer = (sxfer << 4) | ((offset <= SIOP_MAX_OFFSET) ?
+ offset : SIOP_MAX_OFFSET);
+#ifdef DEBUG_SYNC
+ printf("siop sync: params for period %dns: sxfer %x sbcl %x",
+ period * 4, sxfer, sbcl);
+ printf(" actual period %dns\n",
+ sc->sc_tcp[sbcl] * ((sxfer >> 4) + 4));
+#endif
+ }
+ sc->sc_sync[target].sxfer = sxfer;
+ sc->sc_sync[target].sbcl = sbcl;
+#ifdef DEBUG_SYNC
+ printf ("siop sync: siop_sxfr %02x, siop_sbcl %02x\n", sxfer, sbcl);
+#endif
+}
+
+#ifdef DEBUG
+
+#if SIOP_TRACE_SIZE
+void
+siop_dump_trace()
+{
+ int i;
+
+ printf("siop trace: next index %d\n", siop_trix);
+ i = siop_trix;
+ do {
+ printf("%3d: '%c' %02x %02x %02x\n", i, siop_trbuf[i],
+ siop_trbuf[i + 1], siop_trbuf[i + 2], siop_trbuf[i + 3]);
+ i = (i + 4) & (SIOP_TRACE_SIZE - 1);
+ } while (i != siop_trix);
+}
+#endif
+
+void
+siop_dump_acb(acb)
+ struct siop_acb *acb;
+{
+ u_char *b = (u_char *) &acb->cmd;
+ int i;
+
+ printf("acb@%p ", acb);
+ if (acb->xs == NULL) {
+ printf("<unused>\n");
+ return;
+ }
+ printf("(%d:%d) flags %2x clen %2d cmd ", acb->xs->sc_link->target,
+ acb->xs->sc_link->lun, acb->flags, acb->clen);
+ for (i = acb->clen; i; --i)
+ printf(" %02x", *b++);
+ printf("\n");
+ printf(" xs: %p data %p:%04x ", acb->xs, acb->xs->data,
+ acb->xs->datalen);
+ printf("va %p:%lx ", acb->iob_buf, acb->iob_len);
+ printf("cur %lx:%lx\n", acb->iob_curbuf, acb->iob_curlen);
+}
+
+void
+siop_dump(sc)
+ struct siop_softc *sc;
+{
+ struct siop_acb *acb;
+ siop_regmap_p rp = sc->sc_siopp;
+ int s;
+ int i;
+
+ s = splbio();
+#if SIOP_TRACE_SIZE
+ siop_dump_trace();
+#endif
+ printf("%s@%p regs %p istat %x\n",
+ sc->sc_dev.dv_xname, sc, rp, rp->siop_istat);
+ if ((acb = sc->free_list.tqh_first) != 0) {
+ printf("Free list:\n");
+ while (acb) {
+ siop_dump_acb(acb);
+ acb = acb->chain.tqe_next;
+ }
+ }
+ if ((acb = sc->ready_list.tqh_first) != 0) {
+ printf("Ready list:\n");
+ while (acb) {
+ siop_dump_acb(acb);
+ acb = acb->chain.tqe_next;
+ }
+ }
+ if ((acb = sc->nexus_list.tqh_first) != 0) {
+ printf("Nexus list:\n");
+ while (acb) {
+ siop_dump_acb(acb);
+ acb = acb->chain.tqe_next;
+ }
+ }
+ if (sc->sc_nexus) {
+ printf("Nexus:\n");
+ siop_dump_acb(sc->sc_nexus);
+ }
+ for (i = 0; i < 8; ++i) {
+ if (sc->sc_tinfo[i].cmds > 2) {
+ printf("tgt %d: cmds %d disc %d senses %d lubusy %x\n",
+ i, sc->sc_tinfo[i].cmds,
+ sc->sc_tinfo[i].dconns,
+ sc->sc_tinfo[i].senses,
+ sc->sc_tinfo[i].lubusy);
+ }
+ }
+ splx(s);
+}
+#endif
--- /dev/null
+unsigned long scripts[] = {
+ 0x47000000, 0x00000118,
+ 0x878B0000, 0x00000030,
+ 0x868A0000, 0x00000160,
+ 0x828A0000, 0x00000168,
+ 0x808A0000, 0x00000178,
+ 0x818A0000, 0x00000200,
+ 0x838A0000, 0x00000288,
+ 0x98080000, 0x0000FF05,
+ 0x1F000024, 0x00000024,
+ 0x808C0001, 0x00000040,
+ 0x808C0004, 0x00000078,
+ 0x808C0002, 0x00000088,
+ 0x808C0007, 0x00000010,
+ 0x808C0003, 0x00000008,
+ 0x98080000, 0x0000FF06,
+ 0x60000040, 0x00000000,
+ 0x60000008, 0x00000000,
+ 0x80880000, 0xFFFFFF78,
+ 0x60000040, 0x00000000,
+ 0x1F00002C, 0x0000002C,
+ 0x808C0003, 0x00000008,
+ 0x98080000, 0x0000FF07,
+ 0x60000040, 0x00000000,
+ 0x1F000034, 0x00000034,
+ 0x60000040, 0x00000000,
+ 0x80880000, 0xFFFFFF38,
+ 0x60000040, 0x00000000,
+ 0x48000000, 0x00000000,
+ 0x98080000, 0x0000FF02,
+ 0x60000040, 0x00000000,
+ 0x87830000, 0xFFFFFF10,
+ 0x1F00002C, 0x0000002C,
+ 0x98040004, 0x0000FF08,
+ 0x60000040, 0x00000000,
+ 0x48000000, 0x00000000,
+ 0x98080000, 0x0000FF01,
+ 0x54000000, 0x00000030,
+ 0x72230000, 0x00000000,
+ 0x6A340000, 0x00000000,
+ 0x9F030000, 0x0000FF09,
+ 0x1F00001C, 0x0000001C,
+ 0x60000040, 0x00000000,
+ 0x98080000, 0x0000FF03,
+ 0x74212800, 0x00000000,
+ 0x78160000, 0x00000000,
+ 0x980C0020, 0x0000FF04,
+ 0x80880000, 0xFFFFFFA8,
+ 0x1E000004, 0x00000004,
+ 0x80880000, 0xFFFFFE80,
+ 0x60000008, 0x00000000,
+ 0x1A00000C, 0x0000000C,
+ 0x80880000, 0xFFFFFE68,
+ 0x1800003C, 0x0000003C,
+ 0x88830000, 0xFFFFFE58,
+ 0x18000044, 0x00000044,
+ 0x88830000, 0xFFFFFE48,
+ 0x1800004C, 0x0000004C,
+ 0x88830000, 0xFFFFFE38,
+ 0x18000054, 0x00000054,
+ 0x88830000, 0xFFFFFE28,
+ 0x1800005C, 0x0000005C,
+ 0x88830000, 0xFFFFFE18,
+ 0x18000064, 0x00000064,
+ 0x88830000, 0xFFFFFE08,
+ 0x1800006C, 0x0000006C,
+ 0x88830000, 0xFFFFFDF8,
+ 0x18000074, 0x00000074,
+ 0x88830000, 0xFFFFFDE8,
+ 0x1800007C, 0x0000007C,
+ 0x88880000, 0xFFFFFDD8,
+ 0x1900003C, 0x0000003C,
+ 0x89830000, 0xFFFFFDC8,
+ 0x19000044, 0x00000044,
+ 0x89830000, 0xFFFFFDB8,
+ 0x1900004C, 0x0000004C,
+ 0x89830000, 0xFFFFFDA8,
+ 0x19000054, 0x00000054,
+ 0x89830000, 0xFFFFFD98,
+ 0x1900005C, 0x0000005C,
+ 0x89830000, 0xFFFFFD88,
+ 0x19000064, 0x00000064,
+ 0x89830000, 0xFFFFFD78,
+ 0x1900006C, 0x0000006C,
+ 0x89830000, 0xFFFFFD68,
+ 0x19000074, 0x00000074,
+ 0x89830000, 0xFFFFFD58,
+ 0x1900007C, 0x0000007C,
+ 0x88880000, 0xFFFFFD48,
+ 0x1B000014, 0x00000014,
+ 0x9F030000, 0x0000FF0A,
+ 0x1F00001C, 0x0000001C,
+ 0x60000040, 0x00000000,
+ 0x48000000, 0x00000000,
+ 0x98080000, 0x0000FF00
+
+};
+
+#define Ent_scripts 0x00000000
+#define Ent_switch 0x00000008
+#define Ent_wait_reselect 0x00000120
+#define Ent_dataout 0x000001a0
+#define Ent_datain 0x00000230
+
+unsigned long INSTRUCTIONS = 0x0000005e;
+unsigned long PATCHES = 0x00000000;
--- /dev/null
+; $NetBSD: siop_script.ss,v 1.3 1995/08/18 15:28:11 chopps Exp $
+
+;
+; Copyright (c) 1995 Michael L. Hitch
+; 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 Michael L. Hitch.
+; 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.
+;
+
+; NCR 53c710 script
+;
+ABSOLUTE ds_Device = 0
+ABSOLUTE ds_MsgOut = ds_Device + 4
+ABSOLUTE ds_Cmd = ds_MsgOut + 8
+ABSOLUTE ds_Status = ds_Cmd + 8
+ABSOLUTE ds_Msg = ds_Status + 8
+ABSOLUTE ds_MsgIn = ds_Msg + 8
+ABSOLUTE ds_ExtMsg = ds_MsgIn + 8
+ABSOLUTE ds_SyncMsg = ds_ExtMsg + 8
+ABSOLUTE ds_Data1 = ds_SyncMsg + 8
+ABSOLUTE ds_Data2 = ds_Data1 + 8
+ABSOLUTE ds_Data3 = ds_Data2 + 8
+ABSOLUTE ds_Data4 = ds_Data3 + 8
+ABSOLUTE ds_Data5 = ds_Data4 + 8
+ABSOLUTE ds_Data6 = ds_Data5 + 8
+ABSOLUTE ds_Data7 = ds_Data6 + 8
+ABSOLUTE ds_Data8 = ds_Data7 + 8
+ABSOLUTE ds_Data9 = ds_Data8 + 8
+
+ABSOLUTE ok = 0xff00
+ABSOLUTE err1 = 0xff01
+ABSOLUTE err2 = 0xff02
+ABSOLUTE err3 = 0xff03
+ABSOLUTE err4 = 0xff04
+ABSOLUTE err5 = 0xff05
+ABSOLUTE err6 = 0xff06
+ABSOLUTE err7 = 0xff07
+ABSOLUTE err8 = 0xff08
+ABSOLUTE err9 = 0xff09
+ABSOLUTE err10 = 0xff0a
+
+ENTRY scripts
+ENTRY switch
+ENTRY wait_reselect
+ENTRY dataout
+ENTRY datain
+
+PROC scripts:
+
+scripts:
+
+ SELECT ATN FROM ds_Device, REL(reselect)
+;
+switch:
+ JUMP REL(msgin), WHEN MSG_IN
+ JUMP REL(msgout), IF MSG_OUT
+ JUMP REL(command_phase), IF CMD
+ JUMP REL(dataout), IF DATA_OUT
+ JUMP REL(datain), IF DATA_IN
+ JUMP REL(end), IF STATUS
+
+ INT err5 ; Unrecognized phase
+
+msgin:
+ MOVE FROM ds_MsgIn, WHEN MSG_IN
+ JUMP REL(ext_msg), IF 0x01 ; extended message
+ JUMP REL(disc), IF 0x04 ; disconnect message
+ JUMP REL(msg_sdp), IF 0x02 ; save data pointers
+ JUMP REL(msg_rej), IF 0x07 ; message reject
+ JUMP REL(msg_rdp), IF 0x03 ; restore data pointers
+
+ INT err6 ; unrecognized message
+
+msg_rdp:
+msg_rej:
+ CLEAR ACK
+ CLEAR ATN
+ JUMP REL(switch)
+
+ext_msg:
+ CLEAR ACK
+ MOVE FROM ds_ExtMsg, WHEN MSG_IN
+ JUMP REL(sync_msg), IF 0x03
+ int err7 ; extended message not SDTR
+
+sync_msg:
+ CLEAR ACK
+ MOVE FROM ds_SyncMsg, WHEN MSG_IN
+ CLEAR ACK
+ JUMP REL(switch)
+
+disc:
+ CLEAR ACK
+ WAIT DISCONNECT
+
+ int err2 ; signal disconnect w/o save DP
+
+msg_sdp:
+ CLEAR ACK ; acknowledge message
+ JUMP REL(switch), WHEN NOT MSG_IN
+ MOVE FROM ds_ExtMsg, WHEN MSG_IN
+ INT err8, IF NOT 0x04 ; interrupt if not disconnect
+ CLEAR ACK
+ WAIT DISCONNECT
+
+ INT err1 ; signal disconnect
+
+reselect:
+wait_reselect:
+ WAIT RESELECT REL(select_adr)
+ MOVE LCRC to SFBR ; Save reselect ID
+ MOVE SFBR to SCRATCH0
+
+ INT err9, WHEN NOT MSG_IN ; didn't get IDENTIFY
+ MOVE FROM ds_Msg, WHEN MSG_IN
+ CLEAR ACK ; acknowlege the message
+ INT err3 ; let host know about reconnect
+
+select_adr:
+ MOVE ISTAT & 0x28 to SFBR ; get connected status
+ MOVE CTEST2 to CTEST2 ; clear Sig_P
+ INT err4, IF 0x20 ; tell host of interrupted reselect
+ JUMP REL(wait_reselect) ; try reselect again
+
+msgout:
+ MOVE FROM ds_MsgOut, WHEN MSG_OUT
+ JUMP REL(switch)
+
+command_phase:
+ CLEAR ATN
+ MOVE FROM ds_Cmd, WHEN CMD
+ JUMP REL(switch)
+
+dataout:
+ MOVE FROM ds_Data1, WHEN DATA_OUT
+ CALL REL(switch), WHEN NOT DATA_OUT
+ MOVE FROM ds_Data2, WHEN DATA_OUT
+ CALL REL(switch), WHEN NOT DATA_OUT
+ MOVE FROM ds_Data3, WHEN DATA_OUT
+ CALL REL(switch), WHEN NOT DATA_OUT
+ MOVE FROM ds_Data4, WHEN DATA_OUT
+ CALL REL(switch), WHEN NOT DATA_OUT
+ MOVE FROM ds_Data5, WHEN DATA_OUT
+ CALL REL(switch), WHEN NOT DATA_OUT
+ MOVE FROM ds_Data6, WHEN DATA_OUT
+ CALL REL(switch), WHEN NOT DATA_OUT
+ MOVE FROM ds_Data7, WHEN DATA_OUT
+ CALL REL(switch), WHEN NOT DATA_OUT
+ MOVE FROM ds_Data8, WHEN DATA_OUT
+ CALL REL(switch), WHEN NOT DATA_OUT
+ MOVE FROM ds_Data9, WHEN DATA_OUT
+ CALL REL(switch)
+
+datain:
+ MOVE FROM ds_Data1, WHEN DATA_IN
+ CALL REL(switch), WHEN NOT DATA_IN
+ MOVE FROM ds_Data2, WHEN DATA_IN
+ CALL REL(switch), WHEN NOT DATA_IN
+ MOVE FROM ds_Data3, WHEN DATA_IN
+ CALL REL(switch), WHEN NOT DATA_IN
+ MOVE FROM ds_Data4, WHEN DATA_IN
+ CALL REL(switch), WHEN NOT DATA_IN
+ MOVE FROM ds_Data5, WHEN DATA_IN
+ CALL REL(switch), WHEN NOT DATA_IN
+ MOVE FROM ds_Data6, WHEN DATA_IN
+ CALL REL(switch), WHEN NOT DATA_IN
+ MOVE FROM ds_Data7, WHEN DATA_IN
+ CALL REL(switch), WHEN NOT DATA_IN
+ MOVE FROM ds_Data8, WHEN DATA_IN
+ CALL REL(switch), WHEN NOT DATA_IN
+ MOVE FROM ds_Data9, WHEN DATA_IN
+ CALL REL(switch)
+
+end:
+ MOVE FROM ds_Status, WHEN STATUS
+ int err10, WHEN NOT MSG_IN ; status not followed by msg
+ MOVE FROM ds_Msg, WHEN MSG_IN
+ CLEAR ACK
+ WAIT DISCONNECT
+ INT ok ; signal completion
--- /dev/null
+/* $NetBSD: afsc.c,v 1.6 1995/02/12 19:19:00 chopps Exp $ */
+
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * Copyright (c) 1995 Theo de Raadt
+ * Copyright (c) 1994 Michael L. Hitch
+ * Copyright (c) 1982, 1990 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.
+ *
+ * @(#)dma.c
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+#include <machine/autoconf.h>
+#if defined(MVME187)
+#include <machine/board.h>
+#endif /* MVME187 */
+
+#if defined(MVME187)
+#include <mvme88k/dev/siopreg.h>
+#include <mvme88k/dev/siopvar.h>
+#else
+#include <mvme68k/dev/siopreg.h>
+#include <mvme68k/dev/siopvar.h>
+#endif /* defined(MVME187) */
+
+#if !defined(MVME187)
+#include "mc.h"
+#endif /* MVME187 */
+#include "pcctwo.h"
+
+#if NMC > 0
+#include <mvme68k/dev/mcreg.h>
+#endif
+#if NPCCTWO > 0
+#if defined(MVME187)
+#include <mvme88k/dev/pcctworeg.h>
+#else
+#include <mvme68k/dev/pcctworeg.h>
+#endif /* defined(MVME187) */
+#endif
+
+#if defined(MVME187)
+#include "machine/mmu.h"
+#endif /* defined(MVME187) */
+
+int afscmatch __P((struct device *, void *, void *));
+void afscattach __P((struct device *, struct device *, void *));
+
+int afscprint __P((void *auxp, char *));
+int siopintr __P((struct siop_softc *));
+int afsc_dmaintr __P((struct siop_softc *));
+
+struct scsi_adapter afsc_scsiswitch = {
+ siop_scsicmd,
+ siop_minphys,
+ 0, /* no lun support */
+ 0, /* no lun support */
+};
+
+struct scsi_device afsc_scsidev = {
+ NULL, /* use default error handler */
+ NULL, /* do not have a start function */
+ NULL, /* have no async handler */
+ NULL, /* Use default done routine */
+};
+
+struct cfattach siop_ca = {
+ sizeof(struct siop_softc), afscmatch, afscattach,
+};
+
+struct cfdriver siop_cd = {
+ NULL, "siop", DV_DULL, 0
+};
+
+int
+afscmatch(pdp, vcf, args)
+ struct device *pdp;
+ void *vcf, *args;
+{
+ struct cfdata *cf = vcf;
+ struct confargs *ca = args;
+
+#if defined(MVME187)
+ caddr_t base;
+ if (cputyp != CPU_187)
+ {
+ return 0;
+ }
+
+ /*
+ * If bus or name do not match, fail.
+ */
+ if (ca->ca_bustype != BUS_PCCTWO ||
+ strcmp(cf->cf_driver->cd_name, "siop")) {
+ return 0;
+ }
+
+ base = (caddr_t)cf->cf_loc[0];
+
+ if (badpaddr(base, 1) == -1) {
+ return 0;
+ }
+
+ /*
+ * tell our parent our requirements
+ */
+ ca->ca_paddr = (caddr_t)SCSI_ADDR;
+ ca->ca_size = NCR710_SIZE;
+ ca->ca_ipl = IPL_BIO;
+
+ return 1;
+#else
+ return (!badvaddr(ca->ca_vaddr, 4));
+#endif /* defined(MVME187) */
+}
+
+void
+afscattach(parent, self, auxp)
+ struct device *parent, *self;
+ void *auxp;
+{
+ struct siop_softc *sc = (struct siop_softc *)self;
+ struct confargs *ca = auxp;
+ siop_regmap_p rp;
+ extern int cpuspeed;
+
+ sc->sc_siopp = rp = (siop_regmap_p)ca->ca_vaddr;
+
+ /*
+ * siop uses sc_clock_freq to define the dcntl & ctest7 reg values
+ * (was 0x0221, but i added SIOP_CTEST7_SC0 for snooping control)
+ */
+ sc->sc_clock_freq = cpuspeed * 2;
+
+#ifdef MVME177
+ /* XXX this is a guess! */
+ if (cputyp == CPU_177)
+ sc->sc_clock_freq = cpuspeed;
+#endif
+ sc->sc_dcntl = SIOP_DCNTL_EA;
+/*X*/ if (sc->sc_clock_freq <= 25)
+/*X*/ sc->sc_dcntl |= (2 << 6);
+/*X*/ else if (sc->sc_clock_freq <= 37)
+/*X*/ sc->sc_dcntl |= (1 << 6);
+/*X*/ else if (sc->sc_clock_freq <= 50)
+/*X*/ sc->sc_dcntl |= (0 << 6);
+/*X*/ else
+/*X*/ sc->sc_dcntl |= (3 << 6);
+
+ sc->sc_ctest0 = SIOP_CTEST0_BTD | SIOP_CTEST0_EAN;
+
+#ifdef MVME187
+ /*
+ * MVME187 doesn't implement snooping...
+ */
+ sc->sc_ctest7 = SIOP_CTEST7_TT1;
+#else
+ sc->sc_ctest7 = SIOP_CTEST7_SNOOP | SIOP_CTEST7_TT1 | SIOP_CTEST7_STD;
+#endif /* MVME187 */
+
+ sc->sc_link.adapter_softc = sc;
+ sc->sc_link.adapter_target = 7; /* XXXX should ask ROM */
+ sc->sc_link.adapter = &afsc_scsiswitch;
+ sc->sc_link.device = &afsc_scsidev;
+ sc->sc_link.openings = 1;
+
+ sc->sc_ih.ih_fn = afsc_dmaintr;
+ sc->sc_ih.ih_arg = sc;
+ sc->sc_ih.ih_ipl = ca->ca_ipl;
+
+ siopinitialize(sc);
+
+ switch (ca->ca_bustype) {
+#if NMC > 0
+ case BUS_MC:
+ {
+ struct mcreg *mc = (struct mcreg *)ca->ca_master;
+
+ mcintr_establish(MCV_NCR, &sc->sc_ih);
+ mc->mc_ncrirq = ca->ca_ipl | MC_IRQ_IEN;
+ break;
+ }
+#endif
+#if NPCCTWO > 0
+ case BUS_PCCTWO:
+ {
+#if defined(MVME187)
+ /*
+ * Disable caching for the softc. Actually, I want
+ * to disable cache for acb structures, but they are
+ * part of softc, and I am disabling the entire softc
+ * just in case.
+ */
+
+ struct pcc2reg *pcc2 = (struct pcc2reg *)ca->ca_parent;
+
+ pmap_cache_ctrl(pmap_kernel(), M88K_TRUNC_PAGE((vm_offset_t)sc),
+ M88K_ROUND_PAGE((vm_offset_t)sc + sizeof(*sc)),
+ CACHE_INH);
+#endif
+ intr_establish(PCC2_VECT + SCSIIRQ, &sc->sc_ih);
+ /* enable interrupts at ca_ipl */
+ pcc2->pcc2_scsiirq = ca->ca_ipl | PCC2_SCSIIRQ_IEN;
+
+ break;
+ }
+#endif
+ }
+
+ evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt);
+
+ /*
+ * attach all scsi units on us
+ */
+ config_found(self, &sc->sc_link, afscprint);
+}
+
+/*
+ * print diag if pnp is NULL else just extra
+ */
+int
+afscprint(auxp, pnp)
+ void *auxp;
+ char *pnp;
+{
+ if (pnp == NULL)
+ return (UNCONF);
+ return (QUIET);
+}
+
+int
+afsc_dmaintr(sc)
+ struct siop_softc *sc;
+{
+ siop_regmap_p rp;
+ u_char istat;
+
+ rp = sc->sc_siopp;
+ istat = rp->siop_istat;
+ if ((istat & (SIOP_ISTAT_SIP | SIOP_ISTAT_DIP)) == 0)
+ return (0);
+ if ((rp->siop_sien | rp->siop_dien) == 0)
+ return (0); /* no interrupts enabled */
+
+ /*
+ * 53c710 manual recommends reading dstat and sstat0 at least
+ * 12 clk cycles apart if reading as bytes (which is what
+ * pcc2 permits). Stick in a 1us delay between accessing dstat and
+ * sstat0 below.
+ *
+ * save interrupt status, DMA status, and SCSI status 0
+ * (may need to deal with stacked interrupts?)
+ */
+ sc->sc_istat = istat;
+ if (istat & SIOP_ISTAT_SIP) {
+ sc->sc_sstat0 = rp->siop_sstat0;
+ }
+ if (istat & SIOP_ISTAT_DIP) {
+ delay(3);
+ sc->sc_dstat = rp->siop_dstat;
+ }
+ siopintr(sc);
+ sc->sc_intrcnt.ev_count++;
+ return (1);
+}
+
+#ifdef DEBUG
+void
+afsc_dump()
+{
+ int i;
+
+ for (i = 0; i < siop_cd.cd_ndevs; ++i)
+ if (siop_cd.cd_devs[i])
+ siop_dump(siop_cd.cd_devs[i]);
+}
+#endif
--- /dev/null
+/* $NetBSD: siopreg.h,v 1.7 1995/08/18 15:28:13 chopps Exp $ */
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Van Jacobson of Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)siopreg.h 7.3 (Berkeley) 2/5/91
+ */
+
+/*
+ * NCR 53C710 SCSI interface hardware description.
+ *
+ * From the Mach scsi driver for the 53C700
+ */
+
+typedef struct {
+/*00*/ volatile unsigned char siop_sien; /* rw: SCSI Interrupt Enable */
+/*01*/ volatile unsigned char siop_sdid; /* rw: SCSI Destination ID */
+/*02*/ volatile unsigned char siop_scntl1; /* rw: SCSI control reg 1 */
+/*03*/ volatile unsigned char siop_scntl0; /* rw: SCSI control reg 0 */
+/*04*/ volatile unsigned char siop_socl; /* rw: SCSI Output Control Latch */
+/*05*/ volatile unsigned char siop_sodl; /* rw: SCSI Output Data Latch */
+/*06*/ volatile unsigned char siop_sxfer; /* rw: SCSI Transfer reg */
+/*07*/ volatile unsigned char siop_scid; /* rw: SCSI Chip ID reg */
+/*08*/ volatile unsigned char siop_sbcl; /* ro: SCSI Bus Control Lines */
+/*09*/ volatile unsigned char siop_sbdl; /* ro: SCSI Bus Data Lines */
+/*0a*/ volatile unsigned char siop_sidl; /* ro: SCSI Input Data Latch */
+/*0b*/ volatile unsigned char siop_sfbr; /* ro: SCSI First Byte Received */
+/*0c*/ volatile unsigned char siop_sstat2; /* ro: SCSI status reg 2 */
+/*0d*/ volatile unsigned char siop_sstat1; /* ro: SCSI status reg 1 */
+/*0e*/ volatile unsigned char siop_sstat0; /* ro: SCSI status reg 0 */
+/*0f*/ volatile unsigned char siop_dstat; /* ro: DMA status */
+/*10*/ volatile unsigned long siop_dsa; /* rw: Data Structure Address */
+/*14*/ volatile unsigned char siop_ctest3; /* ro: Chip test register 3 */
+/*15*/ volatile unsigned char siop_ctest2; /* ro: Chip test register 2 */
+/*16*/ volatile unsigned char siop_ctest1; /* ro: Chip test register 1 */
+/*17*/ volatile unsigned char siop_ctest0; /* ro: Chip test register 0 */
+/*18*/ volatile unsigned char siop_ctest7; /* rw: Chip test register 7 */
+/*19*/ volatile unsigned char siop_ctest6; /* rw: Chip test register 6 */
+/*1a*/ volatile unsigned char siop_ctest5; /* rw: Chip test register 5 */
+/*1b*/ volatile unsigned char siop_ctest4; /* rw: Chip test register 4 */
+/*1c*/ volatile unsigned long siop_temp; /* rw: Temporary Stack reg */
+/*20*/ volatile unsigned char siop_lcrc; /* rw: LCRC value */
+/*21*/ volatile unsigned char siop_ctest8; /* rw: Chip test register 8 */
+/*22*/ volatile unsigned char siop_istat; /* rw: Interrupt Status reg */
+/*23*/ volatile unsigned char siop_dfifo; /* rw: DMA FIFO */
+/*24*/ volatile unsigned char siop_dcmd; /* rw: DMA Command Register */
+/*25*/ volatile unsigned char siop_dbc2; /* rw: DMA Byte Counter reg */
+/*26*/ volatile unsigned char siop_dbc1;
+/*27*/ volatile unsigned char siop_dbc0;
+/*28*/ volatile unsigned long siop_dnad; /* rw: DMA Next Address */
+/*2c*/ volatile unsigned long siop_dsp; /* rw: DMA SCRIPTS Pointer reg */
+/*30*/ volatile unsigned long siop_dsps; /* rw: DMA SCRIPTS Pointer Save reg */
+/*34*/ volatile unsigned long siop_scratch; /* rw: Scratch Register */
+/*38*/ volatile unsigned char siop_dcntl; /* rw: DMA Control reg */
+/*39*/ volatile unsigned char siop_dwt; /* rw: DMA Watchdog Timer */
+/*3a*/ volatile unsigned char siop_dien; /* rw: DMA Interrupt Enable */
+/*3b*/ volatile unsigned char siop_dmode; /* rw: DMA Mode reg */
+/*3c*/ volatile unsigned long siop_adder;
+
+} siop_regmap_t;
+typedef volatile siop_regmap_t *siop_regmap_p;
+
+/*
+ * Register defines
+ */
+
+/* Scsi control register 0 (scntl0) */
+
+#define SIOP_SCNTL0_ARB 0xc0 /* Arbitration mode */
+# define SIOP_ARB_SIMPLE 0x00
+# define SIOP_ARB_FULL 0xc0
+#define SIOP_SCNTL0_START 0x20 /* Start Sequence */
+#define SIOP_SCNTL0_WATN 0x10 /* (Select) With ATN */
+#define SIOP_SCNTL0_EPC 0x08 /* Enable Parity Checking */
+#define SIOP_SCNTL0_EPG 0x04 /* Enable Parity Generation */
+#define SIOP_SCNTL0_AAP 0x02 /* Assert ATN on Parity Error */
+#define SIOP_SCNTL0_TRG 0x01 /* Target Mode */
+
+/* Scsi control register 1 (scntl1) */
+
+#define SIOP_SCNTL1_EXC 0x80 /* Extra Clock Cycle of data setup */
+#define SIOP_SCNTL1_ADB 0x40 /* Assert Data Bus */
+#define SIOP_SCNTL1_ESR 0x20 /* Enable Selection/Reselection */
+#define SIOP_SCNTL1_CON 0x10 /* Connected */
+#define SIOP_SCNTL1_RST 0x08 /* Assert RST */
+#define SIOP_SCNTL1_AESP 0x04 /* Assert even SCSI parity */
+#define SIOP_SCNTL1_RES0 0x02 /* Reserved */
+#define SIOP_SCNTL1_RES1 0x01 /* Reserved */
+
+/* Scsi interrupt enable register (sien) */
+
+#define SIOP_SIEN_M_A 0x80 /* Phase Mismatch or ATN active */
+#define SIOP_SIEN_FCMP 0x40 /* Function Complete */
+#define SIOP_SIEN_STO 0x20 /* (Re)Selection timeout */
+#define SIOP_SIEN_SEL 0x10 /* (Re)Selected */
+#define SIOP_SIEN_SGE 0x08 /* SCSI Gross Error */
+#define SIOP_SIEN_UDC 0x04 /* Unexpected Disconnect */
+#define SIOP_SIEN_RST 0x02 /* RST asserted */
+#define SIOP_SIEN_PAR 0x01 /* Parity Error */
+
+/* Scsi chip ID (scid) */
+
+#define SIOP_SCID_VALUE(i) (1<<i)
+
+/* Scsi transfer register (sxfer) */
+
+#define SIOP_SXFER_DHP 0x80 /* Disable Halt on Parity error/ ATN asserted */
+#define SIOP_SXFER_TP 0x70 /* Synch Transfer Period */
+ /* see specs for formulas:
+ Period = TCP * (4 + XFERP )
+ TCP = 1 + CLK + 1..2;
+ */
+#define SIOP_SXFER_MO 0x0f /* Synch Max Offset */
+# define SIOP_MAX_OFFSET 8
+
+/* Scsi output data latch register (sodl) */
+
+/* Scsi output control latch register (socl) */
+
+#define SIOP_REQ 0x80 /* SCSI signal <x> asserted */
+#define SIOP_ACK 0x40
+#define SIOP_BSY 0x20
+#define SIOP_SEL 0x10
+#define SIOP_ATN 0x08
+#define SIOP_MSG 0x04
+#define SIOP_CD 0x02
+#define SIOP_IO 0x01
+
+#define SIOP_PHASE(socl) SCSI_PHASE(socl)
+
+/* Scsi first byte received register (sfbr) */
+
+/* Scsi input data latch register (sidl) */
+
+/* Scsi bus data lines register (sbdl) */
+
+/* Scsi bus control lines register (sbcl). Same as socl */
+
+/* DMA status register (dstat) */
+
+#define SIOP_DSTAT_DFE 0x80 /* DMA FIFO empty */
+#define SIOP_DSTAT_RES 0x40
+#define SIOP_DSTAT_BF 0x20 /* Bus fault */
+#define SIOP_DSTAT_ABRT 0x10 /* Aborted */
+#define SIOP_DSTAT_SSI 0x08 /* SCRIPT Single Step */
+#define SIOP_DSTAT_SIR 0x04 /* SCRIPT Interrupt Instruction */
+#define SIOP_DSTAT_WTD 0x02 /* Watchdog Timeout Detected */
+#define SIOP_DSTAT_IID 0x01 /* Invalid Instruction Detected */
+
+/* Scsi status register 0 (sstat0) */
+
+#define SIOP_SSTAT0_M_A 0x80 /* Phase Mismatch or ATN active */
+#define SIOP_SSTAT0_FCMP 0x40 /* Function Complete */
+#define SIOP_SSTAT0_STO 0x20 /* (Re)Selection timeout */
+#define SIOP_SSTAT0_SEL 0x10 /* (Re)Selected */
+#define SIOP_SSTAT0_SGE 0x08 /* SCSI Gross Error */
+#define SIOP_SSTAT0_UDC 0x04 /* Unexpected Disconnect */
+#define SIOP_SSTAT0_RST 0x02 /* RST asserted */
+#define SIOP_SSTAT0_PAR 0x01 /* Parity Error */
+
+/* Scsi status register 1 (sstat1) */
+
+#define SIOP_SSTAT1_ILF 0x80 /* Input latch (sidl) full */
+#define SIOP_SSTAT1_ORF 0x40 /* output reg (sodr) full */
+#define SIOP_SSTAT1_OLF 0x20 /* output latch (sodl) full */
+#define SIOP_SSTAT1_AIP 0x10 /* Arbitration in progress */
+#define SIOP_SSTAT1_LOA 0x08 /* Lost arbitration */
+#define SIOP_SSTAT1_WOA 0x04 /* Won arbitration */
+#define SIOP_SSTAT1_RST 0x02 /* SCSI RST current value */
+#define SIOP_SSTAT1_SDP 0x01 /* SCSI SDP current value */
+
+/* Scsi status register 2 (sstat2) */
+
+#define SIOP_SSTAT2_FF 0xf0 /* SCSI FIFO flags (bytecount) */
+# define SIOP_SCSI_FIFO_DEEP 8
+#define SIOP_SSTAT2_SDP 0x08 /* Latched (on REQ) SCSI SDP */
+#define SIOP_SSTAT2_MSG 0x04 /* Latched SCSI phase */
+#define SIOP_SSTAT2_CD 0x02
+#define SIOP_SSTAT2_IO 0x01
+
+/* Chip test register 0 (ctest0) */
+
+#define SIOP_CTEST0_RES0 0x80
+#define SIOP_CTEST0_BTD 0x40 /* Byte-to-byte Timer Disable */
+#define SIOP_CTEST0_GRP 0x20 /* Generate Receive Parity for Passthrough */
+#define SIOP_CTEST0_EAN 0x10 /* Enable Active Negation */
+#define SIOP_CTEST0_HSC 0x08 /* Halt SCSI clock */
+#define SIOP_CTEST0_ERF 0x04 /* Extend REQ/ACK Filtering */
+#define SIOP_CTEST0_RES1 0x02
+#define SIOP_CTEST0_DDIR 0x01 /* Xfer direction (1-> from SCSI bus) */
+
+/* Chip test register 1 (ctest1) */
+
+#define SIOP_CTEST1_FMT 0xf0 /* Byte empty in DMA FIFO bottom (high->byte3) */
+#define SIOP_CTEST1_FFL 0x0f /* Byte full in DMA FIFO top, same */
+
+/* Chip test register 2 (ctest2) */
+
+#define SIOP_CTEST2_RES 0x80
+#define SIOP_CTEST2_SIGP 0x40 /* Signal process */
+#define SIOP_CTEST2_SOFF 0x20 /* Synch Offset compare (1-> zero Init, max Tgt */
+#define SIOP_CTEST2_SFP 0x10 /* SCSI FIFO Parity */
+#define SIOP_CTEST2_DFP 0x08 /* DMA FIFO Parity */
+#define SIOP_CTEST2_TEOP 0x04 /* True EOP (a-la 5380) */
+#define SIOP_CTEST2_DREQ 0x02 /* DREQ status */
+#define SIOP_CTEST2_DACK 0x01 /* DACK status */
+
+/* Chip test register 3 (ctest3) read-only, top of SCSI FIFO */
+
+/* Chip test register 4 (ctest4) */
+
+#define SIOP_CTEST4_MUX 0x80 /* Host bus multiplex mode */
+#define SIOP_CTEST4_ZMOD 0x40 /* High-impedance outputs */
+#define SIOP_CTEST4_SZM 0x20 /* ditto, SCSI "outputs" */
+#define SIOP_CTEST4_SLBE 0x10 /* SCSI loobpack enable */
+#define SIOP_CTEST4_SFWR 0x08 /* SCSI FIFO write enable (from sodl) */
+#define SIOP_CTEST4_FBL 0x07 /* DMA FIFO Byte Lane select (from ctest6)
+ 4->0, .. 7->3 */
+
+/* Chip test register 5 (ctest5) */
+
+#define SIOP_CTEST5_ADCK 0x80 /* Clock Address Incrementor */
+#define SIOP_CTEST5_BBCK 0x40 /* Clock Byte counter */
+#define SIOP_CTEST5_ROFF 0x20 /* Reset SCSI offset */
+#define SIOP_CTEST5_MASR 0x10 /* Master set/reset pulses (of bits 3-0) */
+#define SIOP_CTEST5_DDIR 0x08 /* (re)set internal DMA direction */
+#define SIOP_CTEST5_EOP 0x04 /* (re)set internal EOP */
+#define SIOP_CTEST5_DREQ 0x02 /* (re)set internal REQ */
+#define SIOP_CTEST5_DACK 0x01 /* (re)set internal ACK */
+
+/* Chip test register 6 (ctest6) DMA FIFO access */
+
+/* Chip test register 7 (ctest7) */
+
+#define SIOP_CTEST7_CDIS 0x80 /* Cache burst disable */
+#define SIOP_CTEST7_SC1 0x40 /* Snoop control 1 */
+#define SIOP_CTEST7_SC0 0x20 /* Snoop contorl 0 */
+#define SIOP_CTEST7_INHIBIT (0 << 5)
+#define SIOP_CTEST7_SNOOP (1 << 5)
+#define SIOP_CTEST7_INVAL (2 << 5)
+#define SIOP_CTEST7_RESV (3 << 5)
+#define SIOP_CTEST7_STD 0x10 /* Selection timeout disable */
+#define SIOP_CTEST7_DFP 0x08 /* DMA FIFO parity bit */
+#define SIOP_CTEST7_EVP 0x04 /* Even parity (to host bus) */
+#define SIOP_CTEST7_TT1 0x02 /* Transfer type bit */
+#define SIOP_CTEST7_DIFF 0x01 /* Differential mode */
+
+/* DMA FIFO register (dfifo) */
+
+#define SIOP_DFIFO_RES 0x80
+#define SIOP_DFIFO_BO 0x7f /* FIFO byte offset counter */
+
+/* Interrupt status register (istat) */
+
+#define SIOP_ISTAT_ABRT 0x80 /* Abort operation */
+#define SIOP_ISTAT_RST 0x40 /* Software reset */
+#define SIOP_ISTAT_SIGP 0x20 /* Signal process */
+#define SIOP_ISTAT_RES 0x10
+#define SIOP_ISTAT_CON 0x08 /* Connected */
+#define SIOP_ISTAT_RES1 0x04
+#define SIOP_ISTAT_SIP 0x02 /* SCSI Interrupt pending */
+#define SIOP_ISTAT_DIP 0x01 /* DMA Interrupt pending */
+
+/* Chip test register 8 (ctest8)
+
+#define SIOP_CTEST8_V 0xf0 /* Chip revision level */
+#define SIOP_CTEST8_FLF 0x08 /* Flush DMA FIFO */
+#define SIOP_CTEST8_CLF 0x04 /* Clear DMA and SCSI FIFOs */
+#define SIOP_CTEST8_FM 0x02 /* Fetch pin mode */
+#define SIOP_CTEST8_SM 0x01 /* Snoop pins mode */
+
+/* DMA Mode register (dmode) */
+
+#define SIOP_DMODE_BL_MASK 0xc0 /* 0->1 1->2 2->4 3->8 */
+#define SIOP_DMODE_FC 0x30 /* Function code */
+#define SIOP_DMODE_PD 0x08 /* Program/data */
+#define SIOP_DMODE_FAM 0x04 /* Fixed address mode */
+#define SIOP_DMODE_U0 0x02 /* User programmable transfer type */
+#define SIOP_DMODE_MAN 0x01 /* Manual start mode */
+
+/* DMA interrupt enable register (dien) */
+
+#define SIOP_DIEN_RES 0xc0
+#define SIOP_DIEN_BF 0x20 /* On Bus Fault */
+#define SIOP_DIEN_ABRT 0x10 /* On Abort */
+#define SIOP_DIEN_SSI 0x08 /* On SCRIPTS sstep */
+#define SIOP_DIEN_SIR 0x04 /* On SCRIPTS intr instruction */
+#define SIOP_DIEN_WTD 0x02 /* On watchdog timeout */
+#define SIOP_DIEN_IID 0x01 /* On illegal instruction detected */
+
+/* DMA control register (dcntl) */
+
+#define SIOP_DCNTL_CF_MASK 0xc0 /* Clock frequency dividers:
+ 0 --> 37.51..50.00 Mhz, div=2
+ 1 --> 25.01..37.50 Mhz, div=1.5
+ 2 --> 16.67..25.00 Mhz, div=1
+ 3 --> 50.01..66.67 Mhz, div=3
+ */
+#define SIOP_DCNTL_EA 0x20 /* Enable ack */
+#define SIOP_DCNTL_SSM 0x10 /* Single step mode */
+#define SIOP_DCNTL_LLM 0x08 /* Enable SCSI Low-level mode */
+#define SIOP_DCNTL_STD 0x04 /* Start DMA operation */
+#define SIOP_DCNTL_FA 0x02 /* Fast arbitration */
+#define SIOP_DCNTL_COM 0x01 /* 53C700 compatibility */
--- /dev/null
+/* $Id: siopvar.h,v 1.1.1.1 1997/03/03 19:32:05 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Van Jacobson of Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)siopvar.h 7.1 (Berkeley) 5/8/90
+ */
+#ifndef _SIOPVAR_H_
+#define _SIOPVAR_H_
+
+/*
+ * The largest single request will be MAXPHYS bytes which will require
+ * at most MAXPHYS/NBPG+1 chain elements to describe, i.e. if none of
+ * the buffer pages are physically contiguous (MAXPHYS/NBPG) and the
+ * buffer is not page aligned (+1).
+ */
+#define DMAMAXIO (MAXPHYS/NBPG+1)
+
+/*
+ * Data Structure for SCRIPTS program
+ */
+struct siop_ds {
+/*00*/ long scsi_addr; /* SCSI ID & sync */
+/*04*/ long idlen; /* Identify message */
+/*08*/ char *idbuf;
+/*0c*/ long cmdlen; /* SCSI command */
+/*10*/ char *cmdbuf;
+/*14*/ long stslen; /* Status */
+/*18*/ char *stsbuf;
+/*1c*/ long msglen; /* Message */
+/*20*/ char *msgbuf;
+/*24*/ long msginlen; /* Message in */
+/*28*/ char *msginbuf;
+/*2c*/ long extmsglen; /* Extended message in */
+/*30*/ char *extmsgbuf;
+/*34*/ long synmsglen; /* Sync transfer request */
+/*38*/ char *synmsgbuf;
+ struct {
+/*3c*/ long datalen;
+/*40*/ char *databuf;
+ } chain[DMAMAXIO];
+};
+
+/*
+ * ACB. Holds additional information for each SCSI command Comments: We
+ * need a separate scsi command block because we may need to overwrite it
+ * with a request sense command. Basicly, we refrain from fiddling with
+ * the scsi_xfer struct (except do the expected updating of return values).
+ * We'll generally update: xs->{flags,resid,error,sense,status} and
+ * occasionally xs->retries.
+ */
+struct siop_acb {
+/*00*/ TAILQ_ENTRY(siop_acb) chain;
+/*08*/ struct scsi_xfer *xs; /* SCSI xfer ctrl block from above */
+/*0c*/ int flags; /* Status */
+#define ACB_FREE 0x00
+#define ACB_ACTIVE 0x01
+#define ACB_DONE 0x04
+#define ACB_CHKSENSE 0x08
+/*10*/ struct scsi_generic cmd; /* SCSI command block */
+/*1c*/ struct siop_ds ds;
+/*a0*/ void *iob_buf;
+/*a4*/ u_long iob_curbuf;
+/*a8*/ u_long iob_len, iob_curlen;
+/*b0*/ u_char msgout[6];
+/*b6*/ u_char msg[6];
+/*bc*/ u_char stat[1];
+/*bd*/ u_char status;
+/*be*/ u_char dummy[2];
+/*c0*/ int clen;
+/*c4*/ char *daddr; /* Saved data pointer */
+/*c8*/ int dleft; /* Residue */
+};
+
+/*
+ * Some info about each (possible) target on the SCSI bus. This should
+ * probably have been a "per target+lunit" structure, but we'll leave it at
+ * this for now. Is there a way to reliably hook it up to sc->fordriver??
+ */
+struct siop_tinfo {
+ int cmds; /* #commands processed */
+ int dconns; /* #disconnects */
+ int touts; /* #timeouts */
+ int perrs; /* #parity errors */
+ int senses; /* #request sense commands sent */
+ ushort lubusy; /* What local units/subr. are busy? */
+ u_char flags;
+ u_char period; /* Period suggestion */
+ u_char offset; /* Offset suggestion */
+} tinfo_t;
+
+struct siop_softc {
+ struct device sc_dev;
+ struct intrhand sc_ih;
+ struct evcnt sc_intrcnt;
+
+ u_char sc_istat;
+ u_char sc_dstat;
+ u_char sc_sstat0;
+ u_char sc_sstat1;
+ u_long sc_intcode;
+ struct scsi_link sc_link; /* proto for sub devices */
+ u_long sc_scriptspa; /* physical address of scripts */
+ siop_regmap_p sc_siopp; /* the SIOP */
+ u_long sc_active; /* number of active I/O's */
+
+ /* Lists of command blocks */
+ TAILQ_HEAD(acb_list, siop_acb) free_list,
+ ready_list,
+ nexus_list;
+
+ struct siop_acb *sc_nexus; /* current command */
+#define SIOP_NACB 8
+ struct siop_acb *sc_acb; /* the real command blocks */
+ struct siop_tinfo sc_tinfo[8];
+
+ u_short sc_clock_freq;
+ u_char sc_dcntl;
+ u_char sc_ctest0;
+ u_char sc_ctest7;
+ u_short sc_tcp[4];
+ u_char sc_flags;
+ u_char sc_sien;
+ u_char sc_dien;
+ u_char sc_minsync;
+ /* one for each target */
+ struct syncpar {
+ u_char state;
+ u_char sxfer;
+ u_char sbcl;
+ } sc_sync[8];
+};
+
+/* sc_flags */
+#define SIOP_INTSOFF 0x80 /* Interrupts turned off */
+#define SIOP_INTDEFER 0x40 /* Level 6 interrupt has been deferred */
+#define SIOP_ALIVE 0x01 /* controller initialized */
+#define SIOP_SELECTED 0x04 /* bus is in selected state. Needed for
+ correct abort procedure. */
+
+/* sync states */
+#define SYNC_START 0 /* no sync handshake started */
+#define SYNC_SENT 1 /* we sent sync request, no answer yet */
+#define SYNC_DONE 2 /* target accepted our (or inferior) settings,
+ or it rejected the request and we stay async */
+
+#define MSG_CMD_COMPLETE 0x00
+#define MSG_EXT_MESSAGE 0x01
+#define MSG_SAVE_DATA_PTR 0x02
+#define MSG_RESTORE_PTR 0x03
+#define MSG_DISCONNECT 0x04
+#define MSG_INIT_DETECT_ERROR 0x05
+#define MSG_ABORT 0x06
+#define MSG_REJECT 0x07
+#define MSG_NOOP 0x08
+#define MSG_PARITY_ERROR 0x09
+#define MSG_BUS_DEVICE_RESET 0x0C
+#define MSG_IDENTIFY 0x80
+#define MSG_IDENTIFY_DR 0xc0 /* (disconnect/reconnect allowed) */
+#define MSG_SYNC_REQ 0x01
+
+#define STS_CHECKCOND 0x02 /* Check Condition (ie., read sense) */
+#define STS_CONDMET 0x04 /* Condition Met (ie., search worked) */
+#define STS_BUSY 0x08
+#define STS_INTERMED 0x10 /* Intermediate status sent */
+#define STS_EXT 0x80 /* Extended status valid */
+
+void siop_minphys __P((struct buf *bp));
+int siop_scsicmd __P((struct scsi_xfer *));
+
+#endif /* _SIOPVAR_H */
--- /dev/null
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/ioctl.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/tty.h>
+#include <sys/uio.h>
+#include <sys/callout.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/syslog.h>
+#include <sys/fcntl.h>
+#include <sys/device.h>
+#include <machine/autoconf.h>
+#include <machine/cpu.h>
+
+#include "pcctwo.h"
+
+#include <mvme88k/dev/vme.h>
+
+int vmematch __P((struct device *, void *, void *));
+void vmeattach __P((struct device *, struct device *, void *));
+
+int vme1chip_init __P((struct vmesoftc *sc));
+int vme2chip_init __P((struct vmesoftc *sc));
+u_long vme2chip_map __P((u_long base, int len, int dwidth));
+
+int vme2abort __P((void *cap, void *frame));
+
+static int vmebustype;
+
+struct cfattach vme_ca = {
+ sizeof(struct vmesoftc), vmematch, vmeattach
+};
+
+struct cfdriver vme_cd = {
+ NULL, "vme", DV_DULL, 0
+};
+
+int
+vmematch(parent, self, args)
+ struct device *parent;
+ void *self;
+ void *args;
+{
+ /* XXX should we look at the id/rev in GCSR area? nivas */
+ caddr_t base;
+ u_char id;
+ u_char rev;
+ struct cfdata *cf = self;
+ struct confargs *ca = args;
+
+ /*
+ * If bus or name do not match, fail.
+ */
+
+ if (ca->ca_bustype != BUS_MAIN ||
+ strcmp(cf->cf_driver->cd_name, "vme")) {
+ return 0;
+ }
+
+ if ((base = (caddr_t)cf->cf_loc[0]) == (caddr_t)-1) {
+ return 0;
+ }
+
+ ca->ca_size = 0x100;
+ ca->ca_paddr = base;
+ ca->ca_bustype = BUS_PCCTWO;
+
+ return (1);
+}
+
+/*
+ * Returns a physical address mapping for a VME address & length.
+ * Note: on some hardware it is not possible to create certain
+ * mappings, ie. the MVME147 cannot do 32 bit accesses to VME bus
+ * addresses from 0 to physmem.
+ */
+caddr_t
+vmepmap(sc, vmeaddr, len, bustype)
+ struct vmesoftc *sc;
+ caddr_t vmeaddr;
+ int len;
+ int bustype;
+{
+ u_long base = (u_long)vmeaddr;
+
+ len = roundup(len, NBPG);
+ switch (vmebustype) {
+#if NPCC > 0
+ case BUS_PCC:
+ switch (bustype) {
+ case BUS_VMES:
+ if (base > VME1_A16BASE &&
+ (base+len - VME1_A16BASE) < VME1_A16D16LEN)
+ base = base - VME1_A16BASE + VME1_A16D16BASE;
+ else if (base+len < VME1_A32D16LEN)
+ base = base + VME1_A32D16BASE;
+ else {
+ printf("%s: cannot map pa %x len %x\n",
+ sc->sc_dev.dv_xname, base, len);
+ return (NULL);
+ }
+ break;
+ case BUS_VMEL:
+ if (base >= physmem && (base+len) < VME1_A32D32LEN)
+ base = base + VME1_A32D32BASE;
+ else if (base+len < VME1_A32D16LEN) /* HACK! */
+ base = base + VME1_A32D16BASE;
+ else {
+ printf("%s: cannot map pa %x len %x\n",
+ sc->sc_dev.dv_xname, base, len);
+ return (NULL);
+ }
+ break;
+ }
+ break;
+#endif
+#if NMC > 0 || NPCCTWO > 0
+ case BUS_MC:
+ case BUS_PCCTWO:
+ switch (bustype) {
+ case BUS_VMES:
+ if (base > VME2_A16BASE &&
+ (base+len-VME2_A16BASE) < VME2_A16D16LEN)
+ base = base - VME2_A16BASE + VME2_A16D16BASE;
+ else if (base > VME2_A24BASE &&
+ (base+len-VME2_A24BASE) < VME2_A24D16LEN)
+ base = base - VME2_A24BASE + VME2_A24D16BASE;
+ else if ((base+len) < VME2_A32D16LEN)
+ base = base + VME2_A32D16BASE;
+ else {
+ base = vme2chip_map(base, len, 16);
+ if (base == NULL)
+ return (NULL);
+ }
+ break;
+ case BUS_VMEL:
+#if 0
+ if (base > VME2_A16BASE &&
+ (base+len-VME2_A16BASE) < VME2_A16D32LEN)
+ base = base - VME2_A16BASE + VME2_A16D32BASE;
+#endif
+ base = vme2chip_map(base, len, 32);
+ if (base == NULL)
+ return (NULL);
+ break;
+ }
+ break;
+#endif
+ }
+ return ((caddr_t)base);
+}
+
+/* if successful, returns the va of a vme bus mapping */
+caddr_t
+vmemap(sc, vmeaddr, len, bustype)
+ struct vmesoftc *sc;
+ caddr_t vmeaddr;
+ int len;
+ int bustype;
+{
+ caddr_t pa, va;
+ extern vm_offset_t iomap_mapin(vm_offset_t, vm_size_t, boolean_t);
+
+ pa = vmepmap(sc, pa, len, bustype);
+ if (pa == NULL)
+ return (NULL);
+#if 0
+ va = (caddr_t)iomap_mapin((vm_offset_t)pa, len, 1);
+#endif
+ va = pa;
+ return (va);
+}
+
+void
+vmeunmap(va, len)
+ caddr_t va;
+ int len;
+{
+#if 0
+ iomap_mapout(va, len);
+#endif
+}
+
+int
+vmerw(sc, uio, flags, bus)
+ struct vmesoftc *sc;
+ struct uio *uio;
+ int flags;
+ int bus;
+{
+ register vm_offset_t o, v;
+ register int c;
+ register struct iovec *iov;
+ caddr_t vme;
+ int error = 0;
+
+ while (uio->uio_resid > 0 && error == 0) {
+ iov = uio->uio_iov;
+ if (iov->iov_len == 0) {
+ uio->uio_iov++;
+ uio->uio_iovcnt--;
+ if (uio->uio_iovcnt < 0)
+ panic("vmerw");
+ continue;
+ }
+
+ v = uio->uio_offset;
+ c = min(iov->iov_len, MAXPHYS);
+ if ((v & PGOFSET) + c > NBPG) /* max NBPG at a time */
+ c = NBPG - (v & PGOFSET);
+ if (c == 0)
+ return (0);
+ vme = vmemap(sc, (caddr_t)(v & ~PGOFSET),
+ NBPG, BUS_VMES);
+ if (vme == NULL) {
+ error = EFAULT; /* XXX? */
+ continue;
+ }
+ error = uiomove((caddr_t)vme + (v & PGOFSET), c, uio);
+ vmeunmap(vme, NBPG);
+ }
+ return (error);
+}
+
+int
+vmeprint(args, bus)
+ void *args;
+ char *bus;
+{
+ struct confargs *ca = args;
+
+ if (ca->ca_ipl > 0)
+ printf(" ipl %d", ca->ca_ipl);
+ if (ca->ca_vec > 0)
+ printf(" vec %d", ca->ca_vec);
+ return (UNCONF);
+}
+
+int
+vmescan(parent, child, args, bustype)
+ struct device *parent;
+ void *child, *args;
+ int bustype;
+{
+ struct cfdata *cf = child;
+ struct vmesoftc *sc = (struct vmesoftc *)parent;
+ struct confargs *ca = args;
+ struct confargs oca;
+
+ if (parent->dv_cfdata->cf_driver->cd_indirect) {
+ printf(" indirect devices not supported\n");
+ return 0;
+ }
+
+ bzero(&oca, sizeof oca);
+ oca.ca_bustype = bustype;
+ oca.ca_paddr = (caddr_t)cf->cf_loc[0];
+ oca.ca_size = cf->cf_loc[1];
+ oca.ca_ipl = cf->cf_loc[2];
+ oca.ca_vec = cf->cf_loc[3];
+
+ /*
+ * Assign a vector if the config file did not specify
+ * one.
+ */
+
+#ifdef notyet
+ if (oca.ca_ipl > 0 && oca.ca_vec == -1)
+ oca.ca_vec = intr_freevec();
+#endif /* notyet */
+
+ oca.ca_vaddr = (void *)vmemap(sc, oca.ca_paddr, oca.ca_size,
+ oca.ca_bustype);
+ if (!oca.ca_vaddr)
+ oca.ca_vaddr = (void *)-1;
+ oca.ca_parent = (void *)sc;
+ if ((*cf->cf_attach->ca_match)(parent, cf, &oca) == 0) {
+ if (oca.ca_vaddr != (void *)-1)
+ vmeunmap(oca.ca_vaddr, oca.ca_size);
+ return (0);
+ }
+ config_attach(parent, cf, &oca, vmeprint);
+ return (1);
+}
+
+void
+vmeattach(parent, self, args)
+ struct device *parent, *self;
+ void *args;
+{
+ struct vmesoftc *sc = (struct vmesoftc *)self;
+ struct confargs *ca = args;
+ struct vme1reg *vme1;
+ struct vme2reg *vme2;
+ int scon;
+
+ /* XXX any initialization to do? */
+
+ sc->sc_vaddr = ca->ca_vaddr;
+
+ vmebustype = ca->ca_bustype;
+ switch (ca->ca_bustype) {
+#if NPCC > 0
+ case BUS_PCC:
+ vme1 = (struct vme1reg *)sc->sc_vaddr;
+ scon = (vme1->vme1_scon & VME1_SCON_SWITCH);
+ printf(": %sscon\n", scon ? "" : "not ");
+ vme1chip_init(sc);
+ break;
+#endif
+#if (NMC > 0) || (NPCCTWO > 0)
+ case BUS_MC:
+ case BUS_PCCTWO:
+ vme2 = (struct vme2reg *)sc->sc_vaddr;
+ scon = (vme2->vme2_tctl & VME2_TCTL_SCON);
+ printf(": %sscon\n", scon ? "" : "not ");
+ vme2chip_init(sc);
+ break;
+#endif
+ default:
+ printf(" unknown parent bus %x", ca->ca_bustype);
+ }
+
+ while (config_found(self, NULL, NULL))
+ ;
+}
+
+/*
+ * On the VMEbus, only one cpu may be configured to respond to any
+ * particular vme ipl. Therefore, it wouldn't make sense to globally
+ * enable all the interrupts all the time -- it would not be possible
+ * to put two cpu's and one vme card into a single cage. Rather, we
+ * enable each vme interrupt only when we are attaching a device that
+ * uses it. This makes it easier (though not trivial) to put two cpu
+ * cards in one VME cage, and both can have some limited access to vme
+ * interrupts (just can't share the same irq).
+ * Obviously no check is made to see if another cpu is using that
+ * interrupt. If you share you will lose.
+ */
+int
+vmeintr_establish(vec, ih)
+ int vec;
+ struct intrhand *ih;
+{
+ struct vmesoftc *sc = (struct vmesoftc *) vme_cd.cd_devs[0];
+#if NPCC > 0
+ struct vme1reg *vme1;
+#endif
+#if NMC > 0 || NPCCTWO > 0
+ struct vme2reg *vme2;
+#endif
+ int x;
+
+ x = (intr_establish(vec, ih));
+
+ switch (vmebustype) {
+#if NPCC > 0
+ case BUS_PCC:
+ vme1 = (struct vme1reg *)sc->sc_vaddr;
+ vme1->vme1_irqen = vme1->vme1_irqen |
+ VME1_IRQ_VME(ih->ih_ipl);
+ break;
+#endif
+#if NMC > 0 || NPCCTWO > 0
+ case BUS_MC:
+ case BUS_PCCTWO:
+ vme2 = (struct vme2reg *)sc->sc_vaddr;
+ vme2->vme2_irqen = vme2->vme2_irqen |
+ VME2_IRQ_VME(ih->ih_ipl);
+ break;
+#endif
+ }
+ return (x);
+}
+
+#if defined(MVME147)
+int
+vme1chip_init(sc)
+ struct vmesoftc *sc;
+{
+ struct vme1reg *vme1 = (struct vme1reg *)sc->sc_vaddr;
+
+ vme1->vme1_scon &= ~VME1_SCON_SYSFAIL; /* XXX doesn't work */
+}
+#endif
+
+#if defined(MVME162) || defined(MVME167) || defined(MVME177) || defined(MVME187)
+
+/*
+ * make local addresses 1G-2G correspond to VME addresses 3G-4G,
+ * as D32
+ */
+#define VME2_D32STARTPHYS (1*1024*1024*1024UL)
+#define VME2_D32ENDPHYS (2*1024*1024*1024UL)
+#define VME2_D32STARTVME (3*1024*1024*1024UL)
+#define VME2_D32BITSVME (3*1024*1024*1024UL)
+
+/*
+ * make local addresses 3G-3.75G correspond to VME addresses 3G-3.75G,
+ * as D16
+ */
+#define VME2_D16STARTPHYS (3*1024*1024*1024UL)
+#define VME2_D16ENDPHYS (3*1024*1024*1024UL + 768*1024*1024UL)
+
+/*
+ * XXX what AM bits should be used for the D32/D16 mappings?
+ */
+int
+vme2chip_init(sc)
+ struct vmesoftc *sc;
+{
+ struct vme2reg *vme2 = (struct vme2reg *)sc->sc_vaddr;
+ u_long ctl;
+
+ /* turn off SYSFAIL LED */
+ vme2->vme2_tctl &= ~VME2_TCTL_SYSFAIL;
+
+ ctl = vme2->vme2_masterctl;
+
+#if 0
+ /* unused decoders 1 & 2 */
+ printf("%s: phys 0x%08x-0x%08x to VMExxx 0x%08x-0x%08x\n",
+ sc->sc_dev.dv_xname,
+ vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000,
+ vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000);
+ printf("%s: phys 0x%08x-0x%08x to VMExxx 0x%08x-0x%08x\n",
+ sc->sc_dev.dv_xname,
+ vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000,
+ vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000);
+#endif
+
+ /* setup a D16 space */
+ vme2->vme2_master3 = ((VME2_D16ENDPHYS-1) & 0xffff0000) |
+ (VME2_D16STARTPHYS >> 16);
+ ctl &= ~(VME2_MASTERCTL_ALL << VME2_MASTERCTL_3SHIFT);
+ ctl |= (VME2_MASTERCTL_AM32SP | VME2_MASTERCTL_D16) <<
+ VME2_MASTERCTL_3SHIFT;
+#if 0
+ printf("%s: phys 0x%08x-0x%08x to VMED16 0x%08x-0x%08x\n",
+ sc->sc_dev.dv_xname,
+ VME2_D16STARTPHYS, VME2_D16ENDPHYS-1,
+ VME2_D16STARTPHYS, VME2_D16ENDPHYS-1);
+#endif
+
+ /* setup a D32 space */
+ vme2->vme2_master4 = ((VME2_D32ENDPHYS-1) & 0xffff0000) |
+ (VME2_D32STARTPHYS >> 16);
+ vme2->vme2_master4mod = (VME2_D32STARTVME & 0xffff0000) |
+ (VME2_D32BITSVME >> 16);
+ ctl &= ~(VME2_MASTERCTL_ALL << VME2_MASTERCTL_4SHIFT);
+ ctl |= (VME2_MASTERCTL_AM32SP) <<
+ VME2_MASTERCTL_4SHIFT;
+#if 0
+ printf("%s: phys 0x%08x-0x%08x to VMED32 0x%08x-0x%08x\n",
+ sc->sc_dev.dv_xname,
+ VME2_D32STARTPHYS, VME2_D32ENDPHYS-1,
+ VME2_D32STARTVME, VME2_D32STARTVME | ~VME2_D32BITSVME);
+#endif
+
+ vme2->vme2_masterctl = ctl;
+
+ ctl = vme2->vme2_gcsrctl;
+
+ /* enable A16 short IO map decoder (0xffffxxxx) */
+ ctl &= ~(VME2_GCSRCTL_I1EN | VME2_GCSRCTL_I1D16 | VME2_GCSRCTL_I1WP |
+ VME2_GCSRCTL_I1SU);
+ ctl |= VME2_GCSRCTL_I1EN | VME2_GCSRCTL_I1D16 | VME2_GCSRCTL_I1SU;
+
+ /* enable A24D16 (0xf0xxxxxx) and A32D16 (0xf[1-e]xxxxxx) decoders */
+ ctl &= ~(VME2_GCSRCTL_I2EN | VME2_GCSRCTL_I2WP | VME2_GCSRCTL_I2SU |
+ VME2_GCSRCTL_I2PD);
+ ctl |= VME2_GCSRCTL_I2EN | VME2_GCSRCTL_I2SU | VME2_GCSRCTL_I2PD;
+
+ /* map decoders 3 & 4 which were just configured */
+ ctl &= ~(VME2_GCSRCTL_MDEN4 | VME2_GCSRCTL_MDEN3 | VME2_GCSRCTL_MDEN1 |
+ VME2_GCSRCTL_MDEN2);
+ ctl |= VME2_GCSRCTL_MDEN4 | VME2_GCSRCTL_MDEN3;
+
+ vme2->vme2_gcsrctl = ctl;
+
+ /*
+ * Map the VME irq levels to the cpu levels 1:1.
+ * This is rather inflexible, but much easier.
+ */
+ vme2->vme2_irql4 = (7 << VME2_IRQL4_VME7SHIFT) |
+ (6 << VME2_IRQL4_VME6SHIFT) | (5 << VME2_IRQL4_VME5SHIFT) |
+ (4 << VME2_IRQL4_VME4SHIFT) | (3 << VME2_IRQL4_VME3SHIFT) |
+ (2 << VME2_IRQL4_VME2SHIFT) | (1 << VME2_IRQL4_VME1SHIFT);
+ /*
+ * disable all interrupts, they will be enabled by each
+ * driver when it configures
+ */
+ vme2->vme2_irqen = 0;
+ if (vmebustype == BUS_PCCTWO){
+ /*
+ * pseudo driver, abort interrupt handler
+ */
+ sc->sc_abih.ih_fn = vme2abort;
+ sc->sc_abih.ih_arg = 0;
+ sc->sc_abih.ih_ipl = IPL_NMI;
+ sc->sc_abih.ih_wantframe = 1;
+#if 0
+ printf("inserting vme_ab handler\n");
+#endif
+ intr_establish(110, &sc->sc_abih);
+ vme2->vme2_irqen |= VME2_IRQ_AB;
+ }
+
+}
+
+/*
+ * A32 accesses on the MVME1[678]x require setting up mappings in
+ * the VME2 chip.
+ * XXX VME address must be between 2G and 4G
+ * XXX We only support D32 at the moment..
+ */
+u_long
+vme2chip_map(base, len, dwidth)
+ u_long base;
+ int len, dwidth;
+{
+ switch (dwidth) {
+ case 16:
+ if (base < VME2_D16STARTPHYS ||
+ base + (u_long)len > VME2_D16ENDPHYS)
+ return (NULL);
+ return (base);
+ case 32:
+ if (base < VME2_D32STARTVME)
+ return (NULL);
+ return (base - VME2_D32STARTVME + VME2_D32STARTPHYS);
+ }
+}
+#if 1
+int
+vme2abort(void *cap, void *frame)
+{
+ struct vmesoftc *sc = (struct vmesoftc *) vme_cd.cd_devs[0];
+ struct vme2reg *vme2 = (struct vme2reg *)sc->sc_vaddr;
+ extern void nmihand(void *);
+
+ if (!(vme2->vme2_irqstat & VME2_IRQ_AB)) {
+ printf("vme2abort irq not set\n");
+ return 0;
+ }
+
+ vme2->vme2_irqclr = VME2_IRQ_AB;
+ nmihand(frame);
+ return 1;
+}
+#endif
+#endif /* MVME1[678]x */
--- /dev/null
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 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.
+ */
+
+#if 0
+#include <machine/cpu.h>
+#endif
+struct vmesoftc {
+ struct device sc_dev;
+ caddr_t sc_vaddr;
+#if 1
+ struct intrhand sc_abih; /* `abort' switch */
+#endif
+};
+
+/*
+ * MVME147 vme configuration registers.
+*/
+struct vme1reg {
+/*01*/ volatile u_short vme1_scon;
+#define VME1_SCON_SWITCH 0x01 /* SCON jumper is set */
+#define VME1_SCON_SRESET 0x02 /* assert SRESET on bus */
+#define VME1_SCON_SYSFAIL 0x04 /* assert SYSFAIL on bus */
+#define VME1_SCON_ROBIN 0x08 /* round robin bus requests */
+/*03*/ volatile u_short vme1_reqconf;
+#define VME1_REQ_IPLMASK 0x03 /* interrupt level for requester */
+#define VME1_REQ_RNEVER 0x08
+#define VME1_REQ_RWD 0x10
+#define VME1_REQ_DHB 0x40
+#define VME1_REQ_DWB 0x80
+/*05*/ volatile u_short vme1_masconf;
+#define VME1_MAS_D16 0x01 /* force d8/16 accesses only */
+#define VME1_MAS_MASA24 0x02 /* send address mod for A24 access */
+#define VME1_MAS_MASA16 0x04 /* send address mod for A16 access */
+#define VME1_MAS_MASUAT 0x08 /* handle unaligned VME cycles */
+#define VME1_MAS_CFILL 0x10 /* DO NOT USE */
+#define VME1_MAS_MASWP 0x20 /* VME fast mode (DO NOT USE) */
+/*07*/ volatile u_short vme1_slconf;
+#define VME1_SLAVE_SLVD16 0x01 /* DO NOT USE */
+#define VME1_SLAVE_SLVWP 0x20 /* DO NOT USE */
+#define VME1_SLAVE_SLVEN 0x80 /* allow access to onboard DRAM */
+/*09*/ volatile u_short vme1_timerconf;
+#define VME1_TIMER_LOCAL_MASK 0x03
+#define VME1_TIMER_LOCAL_T0 0x00 /* local timeout 102 microsec */
+#define VME1_TIMER_LOCAL_T1 0x01 /* local timeout 205 microsec */
+#define VME1_TIMER_LOCAL_T2 0x02 /* local timeout 410 microsec */
+#define VME1_TIMER_LOCAL_T3 0x03 /* local timeout disabled */
+#define VME1_TIMER_VMEACC_MASK 0x0c
+#define VME1_TIMER_VMEACC_T0 0x00 /* VME access timeout 102 microsec */
+#define VME1_TIMER_VMEACC_T1 0x04 /* VME access timeout 1.6 millisec */
+#define VME1_TIMER_VMEACC_T2 0x08 /* VME access timeout 51 millisec */
+#define VME1_TIMER_VMEACC_T3 0x0c /* VME access timeout disabled */
+#define VME1_TIMER_VMEGLO_MASK 0x30
+#define VME1_TIMER_VMEGLO_T0 0x00 /* VME glob timeout 102 microsec */
+#define VME1_TIMER_VMEGLO_T1 0x10 /* VME glob timeout 205 microsec */
+#define VME1_TIMER_VMEGLO_T2 0x20 /* VME glob timeout 410 microsec */
+#define VME1_TIMER_VMEGLO_T3 0x30 /* VME glob timeout disabled */
+#define VME1_TIMER_ARBTO 0x40 /* enable VME arbitration timer */
+/*0b*/ volatile u_short vme1_sladdrmod;
+#define VME1_SLMOD_DATA 0x01
+#define VME1_SLMOD_PRGRM 0x02
+#define VME1_SLMOD_BLOCK 0x04
+#define VME1_SLMOD_SHORT 0x08
+#define VME1_SLMOD_STND 0x10
+#define VME1_SLMOD_EXTED 0x20
+#define VME1_SLMOD_USER 0x40
+#define VME1_SLMOD_SUPER 0x80
+/*0d*/ volatile u_short vme1_msaddrmod;
+#define VME1_MSMOD_AM_MASK 0x3f
+#define VME1_MSMOD_AMSEL 0x80
+/*0f*/ volatile u_short vme1_irqen;
+#define VME1_IRQ_VME(x) (1 << (x))
+/*11*/ volatile u_short vme1_uirqen;
+/*13*/ volatile u_short vme1_uirq;
+/*15*/ volatile u_short vme1_irq;
+/*17*/ volatile u_short vme1_vmeid;
+/*19*/ volatile u_short vme1_buserr;
+/*1b*/ volatile u_short vme1_gcsr;
+#define VME1_GCSR_OFF 0x0f
+/*1d*/ u_short :16;
+/*1f*/ u_short :16;
+/*21*/ volatile u_short vme1_gcsr_gr0;
+/*23*/ volatile u_short vme1_gcsr_gr1;
+/*25*/ volatile u_short vme1_gcsr_boardid;
+/*27*/ volatile u_short vme1_gcsr_gpr0;
+/*29*/ volatile u_short vme1_gcsr_gpr1;
+/*2b*/ volatile u_short vme1_gcsr_gpr2;
+/*2d*/ volatile u_short vme1_gcsr_gpr3;
+/*2f*/ volatile u_short vme1_gcsr_gpr4;
+};
+
+/*
+ * Basic VME memory layout for the MVME147 follows:
+ * - A32D32 accesses occur at memsize-0xefffffff. This makes it
+ * impossible to do A32D32 accesses before the end of your onboard
+ * memory. If you want to do low address A24D32 accesses, and you
+ * have 16M or more onboard memory you'll find you cannot.
+ * - A32D16 accesses can occur at 0xf0000000-0xff7fffff.
+ * - A16D16 accesses can occur at 0xffff0000-0xffffffff.
+ */
+#define VME1_A32D32BASE 0x00000000UL
+#define VME1_A32D32LEN 0xf0000000UL
+#define VME1_A32D16BASE 0xf0000000UL
+#define VME1_A32D16LEN 0x0f800000UL
+#define VME1_A16D16BASE 0xffff0000UL
+#define VME1_A16D16LEN 0x00010000UL
+#define VME1_A16BASE 0xffff0000UL
+
+/*
+ * XXX: this chip has some rather inane access rules!
+ */
+struct vme2reg {
+/*00*/ volatile u_long vme2_slaveaddr1;
+/*04*/ volatile u_long vme2_slaveaddr2;
+#define VME2_SADDR_END 0xffff0000 /* VME address END & START */
+#define VME2_SADDR_START 0x0000ffff
+/*08*/ volatile u_long vme2_slavelmod1;
+/*0c*/ volatile u_long vme2_slavelmod2;
+#define VME2_SADDR_LADDR 0xffff0000 /* local base address */
+#define VME2_SADDR_SIZE(mem) (0x1000 - (mem) >> 16) /* encoding of size */
+/*10*/ volatile u_long vme2_slavectl;
+#define VME2_SLAVE_CHOOSE(bits, num) ((bits) << (16*((num)-1)))
+#define VME2_SLAVECTL_WP 0x00000100 /* write posting */
+#define VME2_SLAVECTL_SNP_NO 0x00000000 /* no snooping */
+#define VME2_SLAVECTL_SNP_SINK 0x00000200 /* sink data */
+#define VME2_SLAVECTL_SNP_INVAL 0x00000400 /* invalidate */
+#define VME2_SLAVECTL_ADDER 0x00000800 /* use adder */
+#define VME2_SLAVECTL_SUP 0x00000080 /* modifier bit */
+#define VME2_SLAVECTL_USR 0x00000040 /* modifier bit */
+#define VME2_SLAVECTL_A32 0x00000020 /* modifier bit */
+#define VME2_SLAVECTL_A24 0x00000010 /* modifier bit */
+#define VME2_SLAVECTL_D64 0x00000008 /* modifier bit */
+#define VME2_SLAVECTL_BLK 0x00000004 /* modifier bit */
+#define VME2_SLAVECTL_PGM 0x00000002 /* modifier bit */
+#define VME2_SLAVECTL_DAT 0x00000001 /* modifier bit */
+/*14*/ volatile u_long vme2_master1;
+/*18*/ volatile u_long vme2_master2;
+/*1c*/ volatile u_long vme2_master3;
+/*20*/ volatile u_long vme2_master4;
+/*24*/ volatile u_long vme2_master4mod;
+/*28*/ volatile u_long vme2_masterctl;
+#define VME2_MASTERCTL_4SHIFT 24
+#define VME2_MASTERCTL_3SHIFT 16
+#define VME2_MASTERCTL_2SHIFT 8
+#define VME2_MASTERCTL_1SHIFT 0
+#define VME2_MASTERCTL_D16 0x80
+#define VME2_MASTERCTL_WP 0x40
+#define VME2_MASTERCTL_AM 0x3f
+#define VME2_MASTERCTL_AM24SB 0x3f /* A24 Supervisory Block Transfer */
+#define VME2_MASTERCTL_AM24SP 0x3e /* A24 Supervisory Program Access */
+#define VME2_MASTERCTL_AM24SD 0x3d /* A24 Supervisory Data Access */
+#define VME2_MASTERCTL_AM24UB 0x3b /* A24 Non-priv. Block Transfer */
+#define VME2_MASTERCTL_AM24UP 0x3a /* A24 Non-priv. Program Access */
+#define VME2_MASTERCTL_AM24UD 0x39 /* A24 Non-priv. Data Access */
+#define VME2_MASTERCTL_AM16S 0x2d /* A16 Supervisory Access */
+#define VME2_MASTERCTL_AM16U 0x29 /* A16 Non-priv. Access */
+#define VME2_MASTERCTL_AM32SB 0x0f /* A32 Supervisory Block Transfer */
+#define VME2_MASTERCTL_AM32SP 0x0e /* A32 Supervisory Program Access */
+#define VME2_MASTERCTL_AM32SD 0x0d /* A32 Supervisory Data Access */
+#define VME2_MASTERCTL_AM32UB 0x0b /* A32 Non-priv. Block Transfer */
+#define VME2_MASTERCTL_AM32UP 0x0a /* A32 Non-priv. Program Access */
+#define VME2_MASTERCTL_AM32UD 0x09 /* A32 Non-priv Data Access */
+
+#define VME2_MASTERCTL_ALL 0xff
+/*2c*/ volatile u_long vme2_gcsrctl;
+#define VME2_GCSRCTL_OFF 0xf0000000
+#define VME2_GCSRCTL_MDEN4 0x00080000
+#define VME2_GCSRCTL_MDEN3 0x00040000
+#define VME2_GCSRCTL_MDEN2 0x00020000
+#define VME2_GCSRCTL_MDEN1 0x00010000
+#define VME2_GCSRCTL_I2EN 0x00008000 /* F decode (A24D16/A32D16) on */
+#define VME2_GCSRCTL_I2WP 0x00004000 /* F decode write post */
+#define VME2_GCSRCTL_I2SU 0x00002000 /* F decode is supervisor */
+#define VME2_GCSRCTL_I2PD 0x00001000 /* F decode is program */
+#define VME2_GCSRCTL_I1EN 0x00000800 /* short decode (A16Dx) on */
+#define VME2_GCSRCTL_I1D16 0x00000400 /* short decode is D16 */
+#define VME2_GCSRCTL_I1WP 0x00000200 /* short decode write post */
+#define VME2_GCSRCTL_I1SU 0x00000100 /* short decode is supervisor */
+#define VME2_GCSRCTL_ROMSIZE 0x000000c0 /* size of ROM */
+#define VME2_GCSRCTL_ROMBSPD 0x00000038 /* speed of ROM */
+#define VME2_GCSRCTL_ROMASPD 0x00000007 /* speed of ROM */
+/*30*/ volatile u_long vme2_dmactl;
+/*34*/ volatile u_long vme2_dmamode;
+/*38*/ volatile u_long vme2_dmaladdr;
+/*3c*/ volatile u_long vme2_dmavmeaddr;
+/*40*/ volatile u_long vme2_dmacount;
+/*44*/ volatile u_long vme2_dmatable;
+/*48*/ volatile u_long vme2_dmastat;
+/*4c*/ volatile u_long vme2_vmejunk;
+/*50*/ volatile u_long vme2_t1cmp;
+/*54*/ volatile u_long vme2_t1count;
+/*58*/ volatile u_long vme2_t2cmp;
+/*5c*/ volatile u_long vme2_t2count;
+/*60*/ volatile u_long vme2_tctl;
+#define VME2_TCTL_SCON 0x40000000 /* we are SCON */
+#define VME2_TCTL_SYSFAIL 0x20000000 /* light SYSFAIL led */
+/*64*/ volatile u_long vme2_prescale;
+/*68*/ volatile u_long vme2_irqstat;
+/*6c*/ volatile u_long vme2_irqen;
+/*70*/ volatile u_long vme2_setsoftirq; /* VME2_IRQ_SWx only */
+/*74*/ volatile u_long vme2_irqclr; /* except VME2_IRQ_VMEx */
+#define VME2_IRQ_ACF 0x80000000
+#define VME2_IRQ_AB 0x40000000
+#define VME2_IRQ_SYSF 0x20000000
+#define VME2_IRQ_MWP 0x10000000
+#define VME2_IRQ_PE 0x08000000
+#define VME2_IRQ_V1IE 0x04000000
+#define VME2_IRQ_TIC2 0x02000000
+#define VME2_IRQ_TIC1 0x01000000
+#define VME2_IRQ_VIA 0x00800000
+#define VME2_IRQ_DMA 0x00400000
+#define VME2_IRQ_SIG3 0x00200000
+#define VME2_IRQ_SIG2 0x00100000
+#define VME2_IRQ_SIG1 0x00080000
+#define VME2_IRQ_SIG0 0x00040000
+#define VME2_IRQ_LM1 0x00020000
+#define VME2_IRQ_LM0 0x00010000
+#define VME2_IRQ_SW7 0x00008000
+#define VME2_IRQ_SW6 0x00004000
+#define VME2_IRQ_SW5 0x00002000
+#define VME2_IRQ_SW4 0x00001000
+#define VME2_IRQ_SW3 0x00000800
+#define VME2_IRQ_SW2 0x00000400
+#define VME2_IRQ_SW1 0x00000200
+#define VME2_IRQ_SW0 0x00000100
+#define VME2_IRQ_SPARE 0x00000080
+#define VME2_IRQ_VME7 0x00000040
+#define VME2_IRQ_VME6 0x00000020
+#define VME2_IRQ_VME5 0x00000010
+#define VME2_IRQ_VME4 0x00000008
+#define VME2_IRQ_VME3 0x00000004
+#define VME2_IRQ_VME2 0x00000002
+#define VME2_IRQ_VME1 0x00000001
+#define VME2_IRQ_VME(x) (1 << ((x) - 1))
+/*78*/ volatile u_long vme2_irql1;
+#define VME2_IRQL1_ACFSHIFT 28
+#define VME2_IRQL1_ABSHIFT 24
+#define VME2_IRQL1_SYSFSHIFT 20
+#define VME2_IRQL1_WPESHIFT 16
+#define VME2_IRQL1_PESHIFT 12
+#define VME2_IRQL1_V1IESHIFT 8
+#define VME2_IRQL1_TIC2SHIFT 4
+#define VME2_IRQL1_TIC1SHIFT 0
+/*7c*/ volatile u_long vme2_irql2;
+#define VME2_IRQL2_VIASHIFT 28
+#define VME2_IRQL2_DMASHIFT 24
+#define VME2_IRQL2_SIG3SHIFT 20
+#define VME2_IRQL2_SIG2SHIFT 16
+#define VME2_IRQL2_SIG1SHIFT 12
+#define VME2_IRQL2_SIG0SHIFT 8
+#define VME2_IRQL2_LM1SHIFT 4
+#define VME2_IRQL2_LM0SHIFT 0
+/*80*/ volatile u_long vme2_irql3;
+#define VME2_IRQL3_SW7SHIFT 28
+#define VME2_IRQL3_SW6SHIFT 24
+#define VME2_IRQL3_SW5SHIFT 20
+#define VME2_IRQL3_SW4SHIFT 16
+#define VME2_IRQL3_SW3SHIFT 12
+#define VME2_IRQL3_SW2SHIFT 8
+#define VME2_IRQL3_SW1SHIFT 4
+#define VME2_IRQL3_SW0SHIFT 0
+/*84*/ volatile u_long vme2_irql4;
+#define VME2_IRQL4_SPARESHIFT 28
+#define VME2_IRQL4_VME7SHIFT 24
+#define VME2_IRQL4_VME6SHIFT 20
+#define VME2_IRQL4_VME5SHIFT 16
+#define VME2_IRQL4_VME4SHIFT 12
+#define VME2_IRQL4_VME3SHIFT 8
+#define VME2_IRQL4_VME2SHIFT 4
+#define VME2_IRQL4_VME1SHIFT 0
+/*88*/ volatile u_long vme2_vbr;
+#define VME2_VBR_0SHIFT 28
+#define VME2_VBR_1SHIFT 24
+#define VME2_VBR_GPOXXXX 0x00ffffff
+/*8c*/ volatile u_long vme2_misc;
+#define VME2_MISC_MPIRQEN 0x00000080 /* do not set */
+#define VME2_MISC_REVEROM 0x00000040 /* 167: dis eprom. 166: en flash */
+#define VME2_MISC_DISSRAM 0x00000020 /* do not set */
+#define VME2_MISC_DISMST 0x00000010
+#define VME2_MISC_NOELBBSY 0x00000008 /* do not set */
+#define VME2_MISC_DISBSYT 0x00000004 /* do not set */
+#define VME2_MISC_ENINT 0x00000002 /* do not set */
+#define VME2_MISC_DISBGN 0x00000001 /* do not set */
+};
+
+#define VME2_A16D32BASE 0xffff0000UL
+#define VME2_A16D32LEN 0x00010000UL
+#define VME2_A32D16BASE 0xf1000000UL
+#define VME2_A32D16LEN 0x01000000UL
+#define VME2_A16D16BASE 0xffff0000UL
+#define VME2_A16D16LEN 0x00010000UL
+#define VME2_A24D16BASE 0xf0000000UL
+#define VME2_A24D16LEN 0x01000000UL
+#define VME2_A16BASE 0xffff0000UL
+#define VME2_A24BASE 0xff000000UL
+
+caddr_t vmepmap __P((struct vmesoftc *sc, caddr_t vmeaddr, int len,
+ int bustype));
+caddr_t vmemap __P((struct vmesoftc *sc, caddr_t vmeaddr, int len,
+ int bustype));
+int vmerw __P((struct vmesoftc *sc, struct uio *uio, int flags, int bus));
--- /dev/null
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <machine/cpu.h>
+#include <machine/autoconf.h>
+#include <mvme88k/dev/vme.h>
+
+/*
+ * The VMEL driver deals with D32 transfers on the VME bus. The number
+ * of address bits (A16, A24, A32) is irrelevant since the mapping
+ * functions will decide how many address bits are relevant.
+ */
+
+void vmelattach __P((struct device *, struct device *, void *));
+int vmelmatch __P((struct device *, void *, void *));
+
+struct vmelsoftc {
+ struct device sc_dev;
+ struct vmesoftc *sc_vme;
+};
+
+struct cfattach vmel_ca = {
+ sizeof(struct vmelsoftc), vmelmatch, vmelattach
+};
+
+struct cfdriver vmel_cd = {
+ NULL, "vmel", DV_DULL, 0
+};
+
+int
+vmelmatch(parent, cf, args)
+ struct device *parent;
+ void *cf, *args;
+{
+ return (1);
+}
+
+int
+vmelscan(parent, child, args)
+ struct device *parent;
+ void *child, *args;
+{
+ return (vmescan(parent, child, args, BUS_VMEL));
+}
+
+void
+vmelattach(parent, self, args)
+ struct device *parent, *self;
+ void *args;
+{
+ struct vmelsoftc *sc = (struct vmelsoftc *)self;
+
+ printf("\n");
+
+ sc->sc_vme = (struct vmesoftc *)parent;
+
+ config_search(vmelscan, self, args);
+}
+
+/*ARGSUSED*/
+int
+vmelopen(dev, flag, mode)
+ dev_t dev;
+ int flag, mode;
+{
+ if (minor(dev) >= vmel_cd.cd_ndevs ||
+ vmel_cd.cd_devs[minor(dev)] == NULL)
+ return (ENODEV);
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+vmelclose(dev, flag, mode)
+ dev_t dev;
+ int flag, mode;
+{
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+vmelioctl(dev, cmd, data, flag, p)
+ dev_t dev;
+ caddr_t data;
+ int cmd, flag;
+ struct proc *p;
+{
+ int unit = minor(dev);
+ struct vmelsoftc *sc = (struct vmelsoftc *) vmel_cd.cd_devs[unit];
+ int error = 0;
+
+ switch (cmd) {
+ default:
+ error = ENOTTY;
+ break;
+ }
+ return (error);
+}
+
+int
+vmelread(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+{
+ int unit = minor(dev);
+ struct vmelsoftc *sc = (struct vmelsoftc *) vmel_cd.cd_devs[unit];
+
+ return (vmerw(sc->sc_vme, uio, flags, BUS_VMEL));
+}
+
+int
+vmelwrite(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+{
+ int unit = minor(dev);
+ struct vmelsoftc *sc = (struct vmelsoftc *) vmel_cd.cd_devs[unit];
+
+ return (vmerw(sc->sc_vme, uio, flags, BUS_VMEL));
+}
+
+int
+vmelmmap(dev, off, prot)
+ dev_t dev;
+ int off, prot;
+{
+ int unit = minor(dev);
+ struct vmelsoftc *sc = (struct vmelsoftc *) vmel_cd.cd_devs[unit];
+ caddr_t pa;
+
+ pa = vmepmap(sc->sc_vme, (caddr_t)off, NBPG, BUS_VMEL);
+ printf("vmel %x pa %x\n", off, pa);
+ if (pa == NULL)
+ return (-1);
+ return (m88k_btop(pa));
+}
--- /dev/null
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <machine/autoconf.h>
+#include <machine/cpu.h>
+#include <mvme88k/dev/vme.h>
+
+/*
+ * The VMES driver deals with D16 transfers on the VME bus. The number
+ * of address bits (A16, A24, A32) is irrelevant since the mapping
+ * functions will decide how many address bits are relevant.
+ */
+
+void vmesattach __P((struct device *, struct device *, void *));
+int vmesmatch __P((struct device *, void *, void *));
+
+struct vmessoftc {
+ struct device sc_dev;
+ struct vmesoftc *sc_vme;
+};
+
+struct cfattach vmes_ca = {
+ sizeof(struct vmessoftc), vmesmatch, vmesattach
+};
+
+struct cfdriver vmes_cd = {
+ NULL, "vmes", DV_DULL, 0
+};
+
+
+int
+vmesmatch(parent, cf, args)
+ struct device *parent;
+ void *cf, *args;
+{
+ return (1);
+}
+
+int
+vmesscan(parent, child, args)
+ struct device *parent;
+ void *child, *args;
+{
+ return (vmescan(parent, child, args, BUS_VMES));
+}
+
+void
+vmesattach(parent, self, args)
+ struct device *parent, *self;
+ void *args;
+{
+ struct vmessoftc *sc = (struct vmessoftc *)self;
+
+ printf("\n");
+
+ sc->sc_vme = (struct vmesoftc *)parent;
+
+ config_search(vmesscan, self, args);
+}
+
+/*ARGSUSED*/
+int
+vmesopen(dev, flag, mode)
+ dev_t dev;
+ int flag, mode;
+{
+ if (minor(dev) >= vmes_cd.cd_ndevs ||
+ vmes_cd.cd_devs[minor(dev)] == NULL)
+ return (ENODEV);
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+vmesclose(dev, flag, mode)
+ dev_t dev;
+ int flag, mode;
+{
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+vmesioctl(dev, cmd, data, flag, p)
+ dev_t dev;
+ caddr_t data;
+ int cmd, flag;
+ struct proc *p;
+{
+ int unit = minor(dev);
+ struct vmessoftc *sc = (struct vmessoftc *) vmes_cd.cd_devs[unit];
+ int error = 0;
+
+ switch (cmd) {
+ default:
+ error = ENOTTY;
+ break;
+ }
+ return (error);
+}
+
+int
+vmesread(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+{
+ int unit = minor(dev);
+ struct vmessoftc *sc = (struct vmessoftc *) vmes_cd.cd_devs[unit];
+
+ return (vmerw(sc->sc_vme, uio, flags, BUS_VMES));
+}
+
+int
+vmeswrite(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+{
+ int unit = minor(dev);
+ struct vmessoftc *sc = (struct vmessoftc *) vmes_cd.cd_devs[unit];
+
+ return (vmerw(sc->sc_vme, uio, flags, BUS_VMES));
+}
+
+int
+vmesmmap(dev, off, prot)
+ dev_t dev;
+ int off, prot;
+{
+ int unit = minor(dev);
+ struct vmessoftc *sc = (struct vmessoftc *) vmes_cd.cd_devs[unit];
+ caddr_t pa;
+
+ pa = vmepmap(sc->sc_vme, (caddr_t)off, NBPG, BUS_VMES);
+ printf("vmes %x pa %x\n", off, pa);
+ if (pa == NULL)
+ return (-1);
+ return (m88k_btop(pa));
+}
--- /dev/null
+/* $NetBSD: float.h,v 1.10 1995/06/20 20:45:41 jtc Exp $ */
+
+/*
+ * Copyright (c) 1989 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.
+ *
+ * @(#)float.h 7.1 (Berkeley) 5/8/90
+ */
+
+#ifndef _M88K_FLOAT_H_
+#define _M88K_FLOAT_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern int __flt_rounds();
+__END_DECLS
+
+#define FLT_RADIX 2 /* b */
+#define FLT_ROUNDS __flt_rounds()
+
+#define FLT_MANT_DIG 24 /* p */
+#define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */
+#define FLT_DIG 6 /* floor((p-1)*log10(b))+(b == 10) */
+#define FLT_MIN_EXP -125 /* emin */
+#define FLT_MIN 1.17549435E-38F /* b**(emin-1) */
+#define FLT_MIN_10_EXP -37 /* ceil(log10(b**(emin-1))) */
+#define FLT_MAX_EXP 128 /* emax */
+#define FLT_MAX 3.40282347E+38F /* (1-b**(-p))*b**emax */
+#define FLT_MAX_10_EXP 38 /* floor(log10((1-b**(-p))*b**emax)) */
+
+#define DBL_MANT_DIG 53
+#define DBL_EPSILON 2.2204460492503131E-16
+#define DBL_DIG 15
+#define DBL_MIN_EXP -1021
+#define DBL_MIN 2.2250738585072014E-308
+#define DBL_MIN_10_EXP -307
+#define DBL_MAX_EXP 1024
+#define DBL_MAX 1.7976931348623157E+308
+#define DBL_MAX_10_EXP 308
+
+#define LDBL_MANT_DIG DBL_MANT_DIG
+#define LDBL_EPSILON DBL_EPSILON
+#define LDBL_DIG DBL_DIG
+#define LDBL_MIN_EXP DBL_MIN_EXP
+#define LDBL_MIN DBL_MIN
+#define LDBL_MIN_10_EXP DBL_MIN_10_EXP
+#define LDBL_MAX_EXP DBL_MAX_EXP
+#define LDBL_MAX DBL_MAX
+#define LDBL_MAX_10_EXP DBL_MAX_10_EXP
+
+#endif /* !_M88K_FLOAT_H_ */
--- /dev/null
+/*
+ * 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.
+ *
+ * @(#)ieee.h 8.1 (Berkeley) 6/11/93
+ */
+/*
+ * Stolen from sparc port
+ */
+
+/*
+ * ieee.h defines the machine-dependent layout of the machine's IEEE
+ * floating point. It does *not* define (yet?) any of the rounding
+ * mode bits, exceptions, and so forth.
+ */
+
+/*
+ * Define the number of bits in each fraction and exponent.
+ *
+ * k k+1
+ * Note that 1.0 x 2 == 0.1 x 2 and that denorms are represented
+ *
+ * (-exp_bias+1)
+ * as fractions that look like 0.fffff x 2 . This means that
+ *
+ * -126
+ * the number 0.10000 x 2 , for instance, is the same as the normalized
+ *
+ * -127 -128
+ * float 1.0 x 2 . Thus, to represent 2 , we need one leading zero
+ *
+ * -129
+ * in the fraction; to represent 2 , we need two, and so on. This
+ *
+ * (-exp_bias-fracbits+1)
+ * implies that the smallest denormalized number is 2
+ *
+ * for whichever format we are talking about: for single precision, for
+ *
+ * -126 -149
+ * instance, we get .00000000000000000000001 x 2 , or 1.0 x 2 , and
+ *
+ * -149 == -127 - 23 + 1.
+ */
+#define SNG_EXPBITS 8
+#define SNG_FRACBITS 23
+
+#define DBL_EXPBITS 11
+#define DBL_FRACBITS 52
+
+#ifdef notyet
+#define E80_EXPBITS 15
+#define E80_FRACBITS 64
+#endif
+
+#define EXT_EXPBITS 15
+#define EXT_FRACBITS 112
+
+struct ieee_single {
+ u_int sng_sign:1;
+ u_int sng_exp:8;
+ u_int sng_frac:23;
+};
+
+struct ieee_double {
+ u_int dbl_sign:1;
+ u_int dbl_exp:11;
+ u_int dbl_frach:20;
+ u_int dbl_fracl;
+};
+
+struct ieee_ext {
+ u_int ext_sign:1;
+ u_int ext_exp:15;
+ u_int ext_frach:16;
+ u_int ext_frachm;
+ u_int ext_fraclm;
+ u_int ext_fracl;
+};
+
+/*
+ * Floats whose exponent is in [1..INFNAN) (of whatever type) are
+ * `normal'. Floats whose exponent is INFNAN are either Inf or NaN.
+ * Floats whose exponent is zero are either zero (iff all fraction
+ * bits are zero) or subnormal values.
+ *
+ * A NaN is a `signalling NaN' if its QUIETNAN bit is clear in its
+ * high fraction; if the bit is set, it is a `quiet NaN'.
+ */
+#define SNG_EXP_INFNAN 255
+#define DBL_EXP_INFNAN 2047
+#define EXT_EXP_INFNAN 32767
+
+#if 0
+#define SNG_QUIETNAN (1 << 22)
+#define DBL_QUIETNAN (1 << 19)
+#define EXT_QUIETNAN (1 << 15)
+#endif
+
+/*
+ * Exponent biases.
+ */
+#define SNG_EXP_BIAS 127
+#define DBL_EXP_BIAS 1023
+#define EXT_EXP_BIAS 16383
--- /dev/null
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * 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 Nivas Madhur.
+ * 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.
+ *
+ */
+/*
+ * Values for fp_except are selected to match the bits in FPSR (see
+ * m88100 user's manual page 6-33). This file is derived from the
+ * defintions in the ABI/88k manual and sparc port.
+ * -- Nivas
+ */
+
+#ifndef _M88K_IEEEFP_H_
+#define _M88K_IEEEFP_H_
+
+typedef int fp_except;
+#define FP_X_INV 0x10 /* invalid operation exception */
+#define FP_X_DZ 0x08 /* divide-by-zero exception */
+#define FP_X_UFL 0x04 /* underflow exception */
+#define FP_X_OFL 0x02 /* overflow exception */
+#define FP_X_IMP 0x01 /* imprecise (loss of precision) */
+
+typedef enum {
+ FP_RN=0, /* round to nearest representable number */
+ FP_RZ=1, /* round to zero (truncate) */
+ FP_RM=2, /* round toward negative infinity */
+ FP_RP=3 /* round toward positive infinity */
+} fp_rnd;
+
+#endif /* _M88K_IEEEFP_H_ */
--- /dev/null
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define MVMEPROM_INCHR 0x00
+#define MVMEPROM_INSTAT 0x01
+#define MVMEPROM_INLN 0x02
+#define MVMEPROM_READSTR 0x03
+#define MVMEPROM_READLN 0x04
+#define MVMEPROM_OUTCHR 0x20
+#define MVMEPROM_OUTSTR 0x21
+#define MVMEPROM_DSKRD 0x10
+#define MVMEPROM_DSKWR 0x11
+#define MVMEPROM_DSKCFIG 0x12
+#define MVMEPROM_DSKFMT 0x14
+#define MVMEPROM_DSKCTRL 0x15
+#define MVMEPROM_NETCTRL 0x1d
+#define MVMEPROM_OUTSTRCRLF 0x22
+#define MVMEPROM_WRITE 0x23
+#define MVMEPROM_WRITELN 0x24
+#define MVMEPROM_DELAY 0x43
+#define MVMEPROM_RTC_RD 0x53
+#define MVMEPROM_EXIT 0x63
+#define MVMEPROM_GETBRDID 0x70
+#define MVMEPROM_ENVIRON 0x71
+
+#define NETCTRLCMD_GETETHER 1
+
+#define ENVIRONCMD_WRITE 1
+#define ENVIRONCMD_READ 2
+#define ENVIRONTYPE_EOL 0
+#define ENVIRONTYPE_START 1
+#define ENVIRONTYPE_DISKBOOT 2
+#define ENVIRONTYPE_ROMBOOT 3
+#define ENVIRONTYPE_NETBOOT 4
+#define ENVIRONTYPE_MEMSIZE 5
+
+#ifndef LOCORE
+struct prom_netctrl {
+ u_char dev;
+ u_char ctrl;
+ u_short status;
+ u_long cmd;
+ u_long addr;
+ u_long len;
+ u_long flags;
+};
+
+struct prom_environ_hdr {
+ u_char type;
+ u_char len;
+};
+
+struct mvmeprom_brdid {
+ u_long eye_catcher;
+ u_char rev;
+ u_char month;
+ u_char day;
+ u_char year;
+ u_short size;
+ u_short rsv1;
+ u_short model;
+ u_short suffix;
+ u_short options;
+ u_char family;
+ u_char cpu;
+ u_short ctrlun;
+ u_short devlun;
+ u_short devtype;
+ u_short devnum;
+ u_long bug;
+
+ /*
+ * XXX: I have seen no documentation for these!
+ *
+ * The following (appears to) exist only on the MVME162 and
+ * upwards. We should figure out what the other fields are.
+ */
+ u_char xx1[16];
+ u_char xx2[4];
+ u_char longname[12];
+ u_char xx3[16];
+ u_char speed[4];
+ u_char xx4[12];
+};
+
+struct mvmeprom_time {
+ u_char year_BCD;
+ u_char month_BCD;
+ u_char day_BCD;
+ u_char wday_BCD;
+ u_char hour_BCD;
+ u_char min_BCD;
+ u_char sec_BCD;
+ u_char cal_BCD;
+};
+
+struct mvmeprom_dskio {
+ u_char ctrl_lun;
+ u_char dev_lun;
+ u_short status;
+ void *pbuffer;
+ u_long blk_num;
+ u_short blk_cnt;
+ u_char flag;
+#define BUG_FILE_MARK 0x80
+#define IGNORE_FILENUM 0x02
+#define END_OF_FILE 0x01
+ u_char addr_mod;
+};
+#define MVMEPROM_BLOCK_SIZE 256
+
+struct mvmeprom_args {
+ u_int dev_lun;
+ u_int ctrl_lun;
+ u_int flags;
+ u_int ctrl_addr;
+ u_int entry;
+ u_int conf_blk;
+ char *arg_start;
+ char *arg_end;
+};
+
+#endif
+
+#define MVMEPROM_CALL(x) \
+ asm volatile ( __CONCAT("or r9,r0,",__STRING(x)) ); \
+ asm volatile ("tb0 0,r0,496");
--- /dev/null
+/*-
+ * Copyright (c) 1990, 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.
+ *
+ * from: @(#)ansi.h 8.2 (Berkeley) 1/4/94
+ * $Id: ansi.h,v 1.1.1.1 1997/03/03 19:30:24 rahnds Exp $
+ */
+
+#ifndef _ANSI_H_
+#define _ANSI_H_
+
+/*
+ * Types which are fundamental to the implementation and may appear in
+ * more than one standard header are defined here. Standard headers
+ * then use:
+ * #ifdef _BSD_SIZE_T_
+ * typedef _BSD_SIZE_T_ size_t;
+ * #undef _BSD_SIZE_T_
+ * #endif
+ */
+#define _BSD_CLOCK_T_ unsigned long /* clock() */
+#define _BSD_PTRDIFF_T_ int /* ptr1 - ptr2 */
+#define _BSD_SIZE_T_ unsigned int /* sizeof() */
+#define _BSD_SSIZE_T_ int /* byte count or error */
+#define _BSD_TIME_T_ long /* time() */
+
+#include "va-m88k.h"
+
+#define _BSD_VA_LIST_ __gnuc_va_list
+
+/*
+ * Runes (wchar_t) is declared to be an ``int'' instead of the more natural
+ * ``unsigned long'' or ``long''. Two things are happening here. It is not
+ * unsigned so that EOF (-1) can be naturally assigned to it and used. Also,
+ * it looks like 10646 will be a 31 bit standard. This means that if your
+ * ints cannot hold 32 bits, you will be in trouble. The reason an int was
+ * chosen over a long is that the is*() and to*() routines take ints (says
+ * ANSI C), but they use _RUNE_T_ instead of int. By changing it here, you
+ * lose a bit of ANSI conformance, but your programs will still work.
+ *
+ * Note that _WCHAR_T_ and _RUNE_T_ must be of the same type. When wchar_t
+ * and rune_t are typedef'd, _WCHAR_T_ will be undef'd, but _RUNE_T remains
+ * defined for ctype.h.
+ */
+#define _BSD_WCHAR_T_ int /* wchar_t */
+#define _BSD_RUNE_T_ int /* rune_t */
+
+#endif /* _ANSI_H_ */
--- /dev/null
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1992 Carnegie Mellon University
+ * Copyright (c) 1991 OMRON Corporation
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#ifndef __M88K_ASM_H__
+#define __M88K_ASM_H__
+
+#ifdef __STDC__
+# define FUNC(NAME) _##NAME
+#else
+# define FUNC(NAME) _/**/NAME
+#endif
+
+/* Define EH_DEBUG to be non-zero to compile-in various debugging things */
+#ifndef EH_DEBUG
+#define EH_DEBUG 0
+#endif EH_DEBUG
+
+/* this gives the offsets into various structures of various elements, etc */
+#include "assym.s"
+
+#define ENTRY(NAME) \
+ .align 8; .globl FUNC(NAME); FUNC(NAME):
+
+
+#define LABEL(name) name:; .globl name ;
+/*
+ * _LABEL(name)
+ * Defines one visible only to the file, unless debugging
+ * is enabled, in which case it's visible to the world (and
+ * hence to debuggers, and such).
+ */
+#if EH_DEBUG
+# define _LABEL(name) name: .globl name ;
+#else
+# define _LABEL(name) name: ;
+#endif
+
+#define RTE NOP ; rte
+
+#define PID cr0
+#define PSR cr1
+#define EPSR cr2
+#define SSBR cr3
+#define SXIP cr4
+#define SNIP cr5
+#define SFIP cr6
+#define VBR cr7
+#define DMT0 cr8
+#define DMD0 cr9
+#define DMA0 cr10
+#define DMT1 cr11
+#define DMD1 cr12
+#define DMA1 cr13
+#define DMT2 cr14
+#define DMD2 cr15
+#define DMA2 cr16
+#define SR0 cr17
+#define SR1 cr18
+#define SR2 cr19
+#define SR3 cr20
+#define FPECR fcr0
+#define FPHS1 fcr1
+#define FPLS1 fcr2
+#define FPHS2 fcr3
+#define FPLS2 fcr4
+#define FPPT fcr5
+#define FPRH fcr6
+#define FPRL fcr7
+#define FPIT fcr8
+#define FPSR fcr62
+#define FPCR fcr63
+
+/*
+ * At various times, there is the need to clear the pipeline (i.e.
+ * synchronize). A "tb1 0, r0, foo" will do that (because a trap
+ * instruction always synchronizes, and this particular instruction
+ * will never actually take the trap).
+ */
+#define FLUSH_PIPELINE tb1 0, r0, 0
+#define NOP or r0, r0, r0
+
+/*
+ * Useful in some situations.
+ * NOTE: If ARG1 or ARG2 are r2 or r3, strange things may happen. Watch out!
+ */
+#define CALL(NAME, ARG1, ARG2) \
+ subu r31, r31, 32 ; \
+ or r2, r0, ARG1 ; \
+ bsr.n NAME ; \
+ or r3, r0, ARG2 ; \
+ addu r31, r31, 32
+
+/*
+ * SR1 - CPU FLAGS REGISTER
+ * XXX clean this when the trap handler is reworked. Among the things
+ * I like to see is having the trap frame on the kernel stack instead
+ * of putting in the PCB. If done properly, we don't need SR1 for doing
+ * anything special. nivas
+ *
+ * SR1 contains flags about the current CPU status.
+ *
+ * The bit FLAG_IGNORE_DATA_EXCEPTION indicates that any data exceptions
+ * should be ignored (well, at least treated in a special way).
+ * The bit FLAG_INTERRUPT_EXCEPTION indicates that the current exception
+ * is the interrupt exception. Such information can be gotten
+ * in other ways, but having it in the flags makes it easy for the
+ * exception handler to check quickly.
+ * The bit FLAG_ENABLING_FPU indicates that the exception handler is
+ * in the process of enabling the FPU (so that an exception can
+ * be serviced). This is needed because enabling the FPU can
+ * cause other exceptions to happen, and the whole system is
+ * in a rather precarious state and so special cautions must
+ * be taken.
+ */
+#define FLAG_CPU_FIELD_WIDTH 4 /* must be <= 12 */
+
+#define FLAG_IGNORE_DATA_EXCEPTION 5 /* bit number 5 */
+#define FLAG_INTERRUPT_EXCEPTION 6 /* bit number 6 */
+#define FLAG_ENABLING_FPU 7 /* bit number 7 */
+
+
+/* REGister OFFset into the E.F. (exception frame) */
+#define REG_OFF(reg_num) ((reg_num) * 4) /* (num * sizeof(register int)) */
+#define GENREG_OFF(num) (REG_OFF(EF_R0 + (num))) /* GENeral REGister OFFset */
+
+
+#define GENERAL_BREATHING_ROOM /* arbitrarily */ 200
+#define KERNEL_STACK_BREATHING_ROOM \
+ (GENERAL_BREATHING_ROOM + SIZEOF_STRUCT_PCB + SIZEOF_STRUCT_UTHREAD)
+
+/*
+ * Some registers used during the setting up of the new exception frame.
+ * Don't choose r1, r30, or r31 for any of them.
+ *
+ * Also, if any are 'r2' or 'r3', be careful using with CALL above!
+ */
+#define FLAGS r2
+#define TMP r3
+#define TMP2 r10
+#define TMP3 r11
+#define SAVE_TMP2 st r10, r31, GENREG_OFF(10)
+#define SAVE_TMP3 st r11, r31, GENREG_OFF(11)
+#define RESTORE_TMP2 ld r10, r31, GENREG_OFF(10)
+#define RESTORE_TMP3 ld r11, r31, GENREG_OFF(11)
+
+/*
+ * Info about the PSR
+ */
+#define PSR_SHADOW_FREEZE_BIT 0
+#define PSR_INTERRUPT_DISABLE_BIT 1
+#define PSR_FPU_DISABLE_BIT 3
+#define PSR_BIG_ENDIAN_MODE 30
+#define PSR_SUPERVISOR_MODE_BIT 31
+
+/*
+ * Status bits for an SXIP/SNIP/SFIP address.
+ */
+#define RTE_VALID_BIT 1
+#define RTE_ERROR_BIT 0
+
+/*
+ * Info about DMT0/DMT1/DMT2
+ */
+#define DMT_VALID_BIT 0
+#define DMT_WRITE_BIT 1
+#define DMT_LOCK_BIT 12
+#define DMT_DOUBLE_BIT 13
+#define DMT_DAS_BIT 14
+#define DMT_DREG_OFFSET 7
+#define DMT_DREG_WIDTH 5
+
+/*
+ * Bits for eh_debug.
+ */
+#define DEBUG_INTERRUPT_BIT 0
+#define DEBUG_DATA_BIT 1
+#define DEBUG_INSTRUCTION_BIT 2
+#define DEBUG_MISALIGN_BIT 3
+#define DEBUG_UNIMP_BIT 4
+#define DEBUG_DIVIDE_BIT 5
+#define DEBUG_OF_BIT 6
+#define DEBUG_FPp_BIT 7
+#define DEBUG_FPi_BIT 8
+#define DEBUG_SYSCALL_BIT 9
+#define DEBUG_MACHSYSCALL_BIT 10
+#define DEBUG_UNIMPLEMENTED_BIT 11
+#define DEBUG_PRIVILEGE_BIT 12
+#define DEBUG_BOUNDS_BIT 13
+#define DEBUG_OVERFLOW_BIT 14
+#define DEBUG_ERROR_BIT 15
+#define DEBUG_SIGSYS_BIT 16
+#define DEBUG_SIGTRAP_BIT 17
+#define DEBUG_BREAK_BIT 18
+#define DEBUG_TRACE_BIT 19
+#define DEBUG_KDB_BIT 20
+#define DEBUG_JKDB_BIT 21
+#define DEBUG_BUGCALL_BIT 22
+
+#define DEBUG_UNKNOWN_BIT 31
+
+/*
+ * These things for vector_init.c and locore.c
+ */
+#if defined(ASSEMBLER)
+# define PREDEFINED_BY_ROM 0xffffffff
+# define END_OF_VECTOR_LIST 0xfffffffe
+#else
+# define PREDEFINED_BY_ROM 0xffffffffU
+# define END_OF_VECTOR_LIST 0xfffffffeU
+#endif
+
+/*
+ * Define ERROR__XXX_USR if the xxx.usr bug (mask C82N) is present.
+ * This implements the workaround.
+ */
+#define ERRATA__XXX_USR 1
+
+#if !defined(CMMU_I)
+#define CMMU_I 0xFFF77000
+#endif
+#if !defined(CMMU_D)
+#define CMMU_D 0xFFF7F000
+#endif
+
+#endif /* __M88K_ASM_H__ */
--- /dev/null
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1991 Carnegie Mellon University
+ * Copyright (c) 1991 OMRON Corporation
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * HISTORY
+ * $Log: asm_macro.h,v $
+ * Revision 1.1.1.1 1997/03/03 19:30:24 rahnds
+ * Third try at importing the mvme88k port. This is a working kernel
+ * from nivas.
+ * Userland and compiler still need to be worked on.
+ * Make certain what directory the import is done from.
+ *
+ * Revision 2.2 93/01/26 18:07:26 danner
+ * Created.
+ * [93/01/24 jfriedl]
+ *
+ */
+
+#ifndef __M88K_ASM_MACRO_H__
+#define __M88K_ASM_MACRO_H__
+
+/*
+ ** Various compiler macros used for speed and efficiency.
+ ** Anyone can include.
+ */
+
+/*
+ * PSR_TYPE is the type of the Process Status Register.
+ */
+typedef unsigned long m88k_psr_type;
+
+/*
+ * disable_interrupts_return_psr()
+ *
+ * The INTERRUPT_DISABLE bit is set in the PSR and the *PREVIOUS*
+ * PSR is returned. Intended to be used with set_psr() [below] as in:
+ *
+ * {
+ * m88k_psr_type psr;
+ * .
+ * .
+ * psr = disable_interrupts_return_psr();
+ * .
+ * SHORT [time-wise] CRITICAL SECTION HERE
+ * .
+ * set_psr(psr);
+ * .
+ * .
+ */
+static inline m88k_psr_type disable_interrupts_return_psr(void)
+{
+ m88k_psr_type temp, oldpsr;
+ asm volatile (
+ "ldcr %0, cr1 \n"
+ "set %1, %0, 1<1> \n"
+ "stcr %1, cr1 \n"
+ "tcnd ne0, r0, 0 " : "=r" (oldpsr), "=r" (temp));
+ return oldpsr;
+}
+#define disable_interrupt() (void)disable_interrupts_return_psr()
+
+/*
+ * Sets the PSR. See comments above.
+ */
+static inline void set_psr(m88k_psr_type psr)
+{
+ asm volatile ("stcr %0, cr1" :: "r" (psr));
+}
+
+/*
+ * Enables interrupts.
+ */
+static inline m88k_psr_type enable_interrupts_return_psr(void)
+{
+ m88k_psr_type temp, oldpsr; /* need a temporary register */
+ asm volatile (
+ "ldcr %0, cr1 \n"
+ "clr %1, %0, 1<1> \n"
+ "stcr %1, cr1 " : "=r" (oldpsr), "=r" (temp));
+ return oldpsr;
+}
+#define enable_interrupt() (void)enable_interrupts_return_psr()
+
+#define db_enable_interrupt enable_interrupt
+#define db_disable_interrupt disable_interrupt
+
+/*
+ * flushes the data pipeline.
+ */
+static inline void flush_pipeline()
+{
+ asm volatile ("tcnd ne0, r0, 0");
+}
+#define db_flush_pipeline flush_pipeline
+
+#endif /* __M88K_ASM_MACRO_H__ */
--- /dev/null
+#define assert(x) \
+({\
+ if (!(x)) {\
+ printf("assertion failure \"%s\" line %d file %s\n", \
+ #x, __LINE__, __FILE__); \
+ panic("assertion"); \
+ } \
+})
--- /dev/null
+#ifndef __GENASSYM_INCLUDED
+#define __GENASSYM_INCLUDED 1
+
+#define P_FORW 0
+#define P_BACK 4
+#define P_VMSPACE 32
+#define P_ADDR 236
+#define P_PRIORITY 208
+#define P_STAT 45
+#define P_WCHAN 104
+#define SRUN 2
+#define VM_PMAP 132
+#define V_INTR 12
+#define UPAGES 3
+#define PGSHIFT 12
+#define USIZE 12288
+#define NBPG 4096
+#define U_PROF 836
+#define U_PROFSCALE 848
+#define PCB_ONFAULT 336
+#define SIZEOF_PCB 344
+#define PCB_USER_STATE 80
+#define SYS_exit 1
+#define SYS_execve 59
+#define SYS_sigreturn 103
+#define EF_R0 0
+#define EF_R31 31
+#define EF_FPSR 32
+#define EF_FPCR 33
+#define EF_EPSR 34
+#define EF_SXIP 35
+#define EF_SFIP 37
+#define EF_SNIP 36
+#define EF_SSBR 38
+#define EF_DMT0 39
+#define EF_DMD0 40
+#define EF_DMA0 41
+#define EF_DMT1 42
+#define EF_DMD1 43
+#define EF_DMA1 44
+#define EF_DMT2 45
+#define EF_DMD2 46
+#define EF_DMA2 47
+#define EF_FPECR 48
+#define EF_FPHS1 49
+#define EF_FPLS1 50
+#define EF_FPHS2 51
+#define EF_FPLS2 52
+#define EF_FPPT 53
+#define EF_FPRH 54
+#define EF_FPRL 55
+#define EF_FPIT 56
+#define EF_VECTOR 57
+#define EF_MASK 58
+#define EF_MODE 59
+#define EF_RET 60
+#define EF_IPFSR 61
+#define EF_DPFSR 62
+#define EF_NREGS 64
+#define SIZEOF_EF 256
+#define PCB_PC 0
+#define PCB_IPL 4
+#define PCB_R14 8
+#define PCB_R15 12
+#define PCB_R16 16
+#define PCB_R17 20
+#define PCB_R18 24
+#define PCB_R19 28
+#define PCB_R20 32
+#define PCB_R21 36
+#define PCB_R22 40
+#define PCB_R23 44
+#define PCB_R24 48
+#define PCB_R25 52
+#define PCB_R26 56
+#define PCB_R27 60
+#define PCB_R28 64
+#define PCB_R29 68
+#define PCB_R30 72
+#define PCB_SP 76
+
+#endif /* __GENASSYM_INCLUDED */
--- /dev/null
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * 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 Nivas Madhur.
+ * 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.
+ *
+ */
+/*
+ * Autoconfiguration information.
+ */
+struct confargs {
+ int ca_bustype;
+ caddr_t ca_parent;
+ caddr_t ca_vaddr;
+ caddr_t ca_paddr;
+ int ca_size;
+ int ca_ipl;
+ int ca_vec;
+};
+
+#define BUS_MAIN 0
+#define BUS_MC 1
+#define BUS_PCC 2
+#define BUS_PCCTWO 3
+#define BUS_VMES 4
+#define BUS_VMEL 5
+
+int always_match __P((struct device *, struct cfdata *, void *));
+
+#define DEVICE_UNIT(device) (device->dv_unit)
+#define CFDATA_LOC(cfdata) (cfdata->cf_loc)
--- /dev/null
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * 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 Nivas Madhur.
+ * 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.
+ *
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991 Carnegie Mellon University
+ * Copyright (c) 1991 OMRON Corporation
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ */
+#ifndef _MACHINE_BOARD_H
+#define _MACHINE_BOARD_H
+/*
+ * VME187 CPU board constants - derived from Luna88k
+ */
+
+/*
+ * Something to put append a 'U' to a long constant if it's C so that
+ * it'll be unsigned in both ANSI and traditional.
+ */
+#if defined(ASSEMBLER)
+# define U(num) num
+#else
+# if defined(__STDC__)
+# define U(num) num ## U
+# else
+# define U(num) num/**/U
+# endif
+#endif
+
+#define MAX_CPUS 1 /* no. of CPUs */
+#define MAX_CMMUS 2 /* 2 CMMUs - 1 data and 1 code */
+
+#define SYSV_BASE U(0x00000000) /* system virtual base */
+
+#define MAXU_ADDR U(0x40000000) /* size of user virtual space */
+#define MAXPHYSMEM U(0x10000000) /* max physical memory */
+
+#define BUGROM_START U(0xFF800000) /* start of BUG PROM */
+#define BUGROM_SIZE U(0x003FFFFF) /* size of BUG PROM */
+#define SRAM_START U(0xFFE00000) /* start of sram used by bug */
+#define SRAM_SIZE U(0x0001FFFF) /* size of sram */
+#define OBIO_START U(0xFFF00000) /* start of local IO */
+#define OBIO_SIZE U(0x000EFFFF) /* size of obio space */
+
+#define INT_PRI_LEVEL U(0xFFF4203E) /* interrupt priority level */
+#define INT_MASK_LEVEL U(0xFFF4203F) /* interrupt mask level */
+
+#define LOCAL_IO_DEVS U(0xFFF00000) /* local IO devices */
+#define VMEA16 U(0xFFFF0000) /* VMEbus A16 */
+
+#define PCC2_ADDR U(0xFFF42000) /* PCCchip2 Regs */
+#define MEM_CTLR U(0xFFF43000) /* MEMC040 mem controller */
+#define SCC_ADDR U(0xFFF45000) /* Cirrus Chip */
+#define LANCE_ADDR U(0xFFF46000) /* 82596CA */
+#define SCSI_ADDR U(0xFFF47000) /* NCR 710 address */
+#define NCR710_SIZE U(0x00000040) /* NCR 710 size */
+#define MK48T08_ADDR U(0xFFFC0000) /* BBRAM, TOD */
+
+#define TOD_CAL_CTL U(0xFFFC1FF8) /* calendar control register */
+#define TOD_CAL_SEC U(0xFFFC1FF9) /* seconds */
+#define TOD_CAL_MIN U(0xFFFC1FFA) /* minutes */
+#define TOD_CAL_HOUR U(0xFFFC1FFB) /* hours */
+#define TOD_CAL_DOW U(0xFFFC1FFC) /* Day Of the Week */
+#define TOD_CAL_DAY U(0xFFFC1FFD) /* days */
+#define TOD_CAL_MON U(0xFFFC1FFE) /* months */
+#define TOD_CAL_YEAR U(0xFFFC1FFF) /* years */
+
+#define CMMU_I U(0xFFF77000) /* CMMU instruction */
+#define CMMU_D U(0xFFF7F000) /* CMMU data */
+#define CMMU_SIZE 0x1000
+
+#if 0
+/* interrupt vectors */
+
+#define PPBSY 0x50 /* printer port busy */
+#define PPPE 0x51 /* printer port PE */
+#define PPSEL 0x52 /* printer port select */
+#define PPFLT 0x53 /* printer port fault */
+#define PPACK 0x54 /* printer port ack */
+#define SCSIIRQ 0x55 /* SCSI IRQ */
+#define LANCERR 0x56 /* LANC ERR */
+#define LANCIRQ 0x57 /* LANC IRQ */
+#define TIMER2IRQ 0x58 /* Tick Timer 2 vec */
+#define TIMER1IRQ 0x59 /* Tick Timer 1 vec */
+#define GPIOIRQ 0x5A /* GPIO IRQ */
+#define SRXEXIRQ 0x5C /* Serial RX Exception IRQ */
+#define SRMIRQ 0x5D /* Serial Modem IRQ */
+#define STXIRQ 0x5E /* Serial TX IRQ */
+#define SRXIRQ 0x5F /* Serial RX IRQ */
+#endif /* 0 */
+
+#endif /* _MACHINE_BOARD_H */
--- /dev/null
+#include <machine/bugio.h>
+
+struct bugenv {
+ int clun;
+ int dlun;
+ int ipl;
+ int ctlr;
+ int (*entry)();
+ int cfgblk;
+ char *argstart;
+ char *argend;
+};
--- /dev/null
+#include "sys/cdefs.h"
+
+struct bugdisk_io {
+ char clun;
+ char dlun;
+ short status;
+ void *addr;
+ int blkno;
+#define fileno blkno
+ short nblks;
+ char flag;
+#define FILEMARKFLAG 0x80
+#define IGNOREFILENO 0x02
+#define ENDOFFILE 0x01
+ char am;
+};
+
+/* values are in BCD {upper nibble+lower nibble} */
+
+struct bugrtc {
+ unsigned char Y;
+ unsigned char M;
+ unsigned char D;
+ unsigned char d;
+ unsigned char H;
+ unsigned char m;
+ unsigned char s;
+ unsigned char c;
+};
+
+/* Board ID - lots of info */
+
+struct bugbrdid {
+ unsigned char eye[4];
+ char rev;
+ char month;
+ char day;
+ char year;
+ short packetsize;
+ short dummy;
+ short brdno;
+ unsigned char brdsuf[2];
+ char options[3];
+ char family:4;
+ char cpu:4;
+ short clun;
+ short dlun;
+ short type;
+ short dev;
+ int option;
+};
+
+struct bugniocall {
+ unsigned char clun;
+ unsigned char dlun;
+ unsigned char ci;
+ unsigned char cd;
+#define NETCTRL_INITDEVICE 0
+#define NETCTRL_GETHDW 1
+#define NETCTRL_TX 2
+#define NETCTRL_RX 3
+#define NETCTRL_FLUSH 4
+#define NETCTRL_RESET 5
+ unsigned int cid;
+ unsigned int memaddr;
+ unsigned int nbytes;
+ unsigned int csword;
+};
+
+char buginchr __P((void));
+int buginstat __P((void));
+int bugoutchr __P((unsigned char));
+int bugoutstr __P((char *, char *));
+int bugpcrlf __P((void));
+int bugdskrd __P((struct bugdisk_io *));
+int bugdskwr __P((struct bugdisk_io *));
+int bugrtcrd __P((struct bugrtc *));
+int bugreturn __P((void));
+int bugbrdid __P((struct bugbrdid *));
+int bugnetctrl __P((struct bugniocall *));
--- /dev/null
+/* $NetBSD: cdefs.h,v 1.2 1995/03/23 20:10:48 jtc Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@wimsey.com> 01/17/95.
+ * Public domain.
+ */
+
+#ifndef _MACHINE_CDEFS_H_
+#define _MACHINE_CDEFS_H_
+
+#ifdef __STDC__
+#define _C_LABEL(x) _STRING(_ ## x)
+#else
+#define _C_LABEL(x) _STRING(_/**/x)
+#endif
+
+#ifdef __GNUC__
+#ifdef __STDC__
+#define __indr_reference(sym,alias) \
+ __asm__(".stabs \"_" #alias "\",11,0,0,0"); \
+ __asm__(".stabs \"_" #sym "\",1,0,0,0")
+#define __warn_references(sym,msg) \
+ __asm__(".stabs \"" msg "\",30,0,0,0"); \
+ __asm__(".stabs \"_" #sym "\",1,0,0,0")
+#else
+#define __indr_reference(sym,alias) \
+ __asm__(".stabs \"_/**/alias\",11,0,0,0"); \
+ __asm__(".stabs \"_/**/sym\",1,0,0,0")
+#define __warn_references(sym,msg) \
+ __asm__(".stabs msg,30,0,0,0"); \
+ __asm__(".stabs \"_/**/sym\",1,0,0,0")
+#endif
+#endif
+
+#endif /* !_MACHINE_CDEFS_H_ */
--- /dev/null
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * 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.
+ */
+
+#ifndef _CPU_H_
+#define _CPU_H_
+
+/*
+ * CTL_MACHDEP definitinos.
+ */
+#define CPU_MAXID 1 /* no valid machdep ids */
+
+#define CTL_MACHDEP_NAMES { \
+ { 0, 0 }, \
+}
+
+#ifdef _KERNEL
+
+#include <machine/psl.h>
+#include <machine/pcb.h>
+
+/*
+ * definitions of cpu-dependent requirements
+ * referenced in generic code
+ */
+#define COPY_SIGCODE /* copy sigcode above user stack in exec */
+
+#define cpu_exec(p) /* nothing */
+#define cpu_wait(p) /* nothing */
+#define cpu_swapout(p) /* nothing */
+
+/*
+ * Arguments to hardclock and gatherstats encapsulate the previous
+ * machine state in an opaque clockframe. CLKF_INTR is only valid
+ * if the process is in kernel mode. Clockframe is really trapframe,
+ * so pointer to clockframe can be safely cast into a pointer to
+ * trapframe.
+ */
+struct clockframe {
+ struct trapframe tf;
+};
+
+extern intstack;
+
+#define CLKF_USERMODE(framep) ((((struct trapframe *)(framep))->epsr & 80000000) == 0)
+#define CLKF_BASEPRI(framep) (((struct trapframe *)(framep))->mask == 0)
+#define CLKF_PC(framep) (((struct trapframe *)(framep))->sxip & ~3)
+#define CLKF_INTR(framep) (((struct trapframe *)(framep))->r[31] > intstack)
+
+#define SIR_NET 1
+#define SIR_CLOCK 2
+
+#define setsoftnet() (ssir |= SIR_NET)
+#define setsoftclock() (ssir |= SIR_CLOCK)
+
+#define siroff(x) (ssir &= ~x)
+
+int ssir;
+int want_ast;
+
+/*
+ * Preempt the current process if in interrupt from user mode,
+ * or after the current trap/syscall if in system mode.
+ */
+int want_resched; /* resched() was called */
+#define need_resched() (want_resched = 1, want_ast = 1)
+
+/*
+ * Give a profiling tick to the current process when the user profiling
+ * buffer pages are invalid. On the sparc, request an ast to send us
+ * through trap(), marking the proc as needing a profiling tick.
+ */
+#define need_proftick(p) ((p)->p_flag |= P_OWEUPC, want_ast = 1)
+
+/*
+ * Notify the current process (p) that it has a signal pending,
+ * process as soon as possible.
+ */
+#define signotify(p) (want_ast = 1)
+
+struct intrhand {
+ int (*ih_fn)();
+ void *ih_arg;
+ int ih_ipl;
+ int ih_wantframe;
+ struct intrhand *ih_next;
+};
+
+int intr_establish __P((int vec, struct intrhand *));
+
+/*
+ * return values for intr_establish()
+ */
+
+#define INTR_EST_SUCC 0
+#define INTR_EST_BADVEC 1
+#define INTR_EST_BADIPL 2
+
+
+/*
+ * There are 256 possible vectors on a MVME1x7 platform (including
+ * onboard and VME vectors. Use intr_establish() to register a
+ * handler for the given vector. vector number is used to index
+ * into the intr_handlers[] table.
+ */
+extern struct intrhand *intr_handlers[256];
+
+/*
+ * switchframe - should be double word aligned.
+ */
+struct switchframe {
+ u_int sf_pc; /* pc */
+ void *sf_proc; /* proc pointer */
+};
+
+#endif /* _KERNEL */
+#endif /* _CPU_H_ */
--- /dev/null
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ *
+ * HISTORY
+ */
+/*
+ Versions Idents for 88k family chips
+ */
+
+#ifndef _M88K_CPUS_
+#define _M88K_CPUS_
+
+/*
+ * cpu Processor Identification Register (PID).
+ */
+#ifndef ASSEMBLER
+union cpupid {
+ unsigned cpupid;
+ struct {
+ unsigned
+ /*empty*/:16,
+ arc:8,
+ version:7,
+ master:1;
+ } m88100;
+ struct {
+ unsigned
+ id:8,
+ type:3,
+ version:5,
+ /*empty*/:16;
+ } m88200;
+};
+#endif ASSEMBLER
+
+#define M88100 0
+#define M88200 5
+#define M88204 6
+
+#endif _M88K_CPUS_
--- /dev/null
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1991 Carnegie Mellon University
+ * Copyright (c) 1991 OMRON Corporation
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * HISTORY
+ */
+
+/*
+ * Machine-dependent defined for the new kernel debugger
+ */
+
+#ifndef _M88K_DB_MACHDEP_H_
+#define _M88K_DB_MACHDEP_H_ 1
+
+#include <sys/types.h>
+#include <vm/vm_prot.h>
+#include <vm/vm_param.h>
+#include <vm/vm_inherit.h>
+#include <vm/lock.h>
+#include <machine/pcb.h> /* m88100_saved_state */
+#include <machine/psl.h>
+#include <machine/trap.h>
+
+#define BKPT_SIZE (4) /* number of bytes in bkpt inst. */
+#define BKPT_INST (0xF000D082U) /* tb0, 0,r0, vector 132 */
+#define BKPT_SET(inst) (BKPT_INST)
+
+/* Entry trap for the debugger - used for inline assembly breaks*/
+#define ENTRY_ASM "tb0 0, r0, 132"
+#define DDB_ENTRY_TRAP_NO 132
+
+typedef vm_offset_t db_addr_t;
+typedef int db_expr_t;
+typedef struct m88100_saved_state db_regs_t;
+db_regs_t ddb_regs; /* register state */
+#define DDB_REGS (&ddb_regs)
+
+/*
+ * the low two bits of sxip, snip, sfip have valid bits
+ * in them that need to masked to get the correct addresses
+ */
+
+#define m88k_pc(regs) \
+({ \
+ int ret; \
+ \
+ if (regs->sxip & 2) /* is valid */ \
+ ret = regs->sxip & ~3; \
+ else if (regs->snip & 2) \
+ ret = regs->snip & ~3; \
+ else if (regs->sfip & 2) \
+ ret = regs->sfip & ~3; \
+ /* we are in trouble - none of the program counters is valid */ \
+ ret; \
+})
+
+/*
+ * This is an actual function due to the fact that the sxip
+ * or snip could be nooped out due to a jmp or rte
+ */
+#define PC_REGS(regs) ((regs->sxip & 2) ? regs->sxip & ~3 : (regs->snip & 2 ? \
+ regs->snip & ~3 : regs->sfip & ~3))
+
+#define pC_REGS(regs) (regs->sxip & 2) ? regs->sxip : (regs->snip & 2 ? \
+ regs->snip : regs->sfip)
+extern int db_noisy;
+#define NOISY(x) if (db_noisy) x
+#define NOISY2(x) if (db_noisy >= 2) x
+#define NOISY3(x) if (db_noisy >= 3) x
+
+extern int quiet_db_read_bytes;
+
+/* These versions are not constantly doing SPL */
+#define cnmaygetc db_getc
+#define cngetc db_getc
+#define cnputc db_putc
+
+/* breakpoint/watchpoint foo */
+#define IS_BREAKPOINT_TRAP(type,code) ((type)==T_KDB_BREAK)
+#if defined(T_WATCHPOINT)
+#define IS_WATCHPOINT_TRAP(type,code) ((type)==T_KDB_WATCH)
+#else
+#define IS_WATCHPOINT_TRAP(type,code) 0
+#endif /* T_WATCHPOINT */
+
+/* we don't want coff support */
+#define DB_NO_COFF 1
+
+/* need software single step */
+#define SOFTWARE_SSTEP 1
+
+/*
+ * Debugger can get to any address space
+ */
+
+#define DB_ACCESS_LEVEL DB_ACCESS_ANY
+
+#define DB_VALID_KERN_ADDR(addr) (!badaddr((void*)(addr), 1))
+#define DB_VALID_ADDRESS(addr,user) \
+ (user ? db_check_user_addr(addr) : DB_VALID_KERN_ADDR(addr))
+
+/* instruction type checking - others are implemented in db_sstep.c */
+
+#define inst_trap_return(ins) ((ins) == 0xf400fc00U)
+
+/* don't need to load symbols */
+#define DB_SYMBOLS_PRELOADED 1
+
+/* machine specific commands have been added to ddb */
+#define DB_MACHINE_COMMANDS 1
+/* inst_return(ins) - is the instruction a function call return.
+ * Not mutually exclusive with inst_branch. Should be a jmp r1. */
+#define inst_return(I) (((I)&0xfffffbffU) == 0xf400c001U ? TRUE : FALSE)
+
+#ifdef __GNUC__
+/*
+ * inst_call - function call predicate: is the instruction a function call.
+ * Could be either bsr or jsr
+ */
+#define inst_call(I) ({ unsigned i = (I); \
+ ((((i) & 0xf8000000U) == 0xc8000000U || /*bsr*/ \
+ ((i) & 0xfffffbe0U) == 0xf400c800U) /*jsr*/ \
+ ? TRUE : FALSE) \
+;})
+
+/*
+ * This routine should return true for instructions that result in unconditonal
+ * transfers of the flow of control. (Unconditional Jumps, subroutine calls,
+ * subroutine returns, etc).
+ *
+ * Trap and return from trap should not be listed here.
+ */
+#define inst_unconditional_flow_transfer(I) ({ unsigned i = (I); \
+ ((((i) & 0xf0000000U) == 0xc0000000U || /* br, bsr */ \
+ ((i) & 0xfffff3e0U) == 0xf400c000U) /* jmp, jsr */ \
+ ? TRUE: FALSE) \
+;})
+
+/* Return true if the instruction has a delay slot. */
+#define db_branch_is_delayed(I) inst_delayed(I)
+
+#endif /* __GNUC__ */
+
+#define db_printf_enter db_printing
+
+#endif /* _M88K_DB_MACHDEP_H_ */
--- /dev/null
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * Copyright (c) 1995 Dale Rahn.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Dale Rahn.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_DISKLABEL_H_
+#define _MACHINE_DISKLABEL_H_
+
+/* number of boot pieces , ie xxboot bootxx */
+#define NUMBOOT 2
+
+#define PARTITIONSHIFT 4
+
+#define LABELSECTOR 0 /* sector containing label */
+#define LABELOFFSET 0 /* offset of label in sector */
+#define MAXPARTITIONS (1 << PARTITIONSHIFT) /* number of partitions */
+#define RAW_PART 2 /* raw partition: xx?c */
+
+/*
+ * used to encode disk minor numbers
+ * this should probably be moved to sys/disklabel.h
+ */
+#define DISKUNIT(dev) (minor(dev) / MAXPARTITIONS)
+#define DISKPART(dev) (minor(dev) % MAXPARTITIONS)
+#define MAKEDISKDEV(maj, unit, part) \
+ (makedev((maj), ((unit) * MAXPARTITIONS) + (part)))
+
+/*
+ * Note: this structure is exactly 512 bytes in size. If you move fields
+ * around, make sure the various members are properly aligned and the
+ * compiler won't do any additional padding.
+ */
+
+struct cpu_disklabel {
+ /* VID */
+ u_char vid_id[4];
+ u_char vid_0[16];
+ u_int vid_oss;
+ u_short vid_osl;
+ u_char vid_1[4];
+ u_short vid_osa_u;
+ u_short vid_osa_l;
+ u_char version;
+ u_char vid_2[1];
+ u_short checksum; /* 2 */
+ u_short partitions;
+ u_char vid_vd[16];
+ u_long bbsize;
+ u_long magic1; /* 4 */
+ u_short type; /* 2 */
+ u_short subtype; /* 2 */
+ u_char packname[16]; /* 16 */
+ u_long flags; /* 4 */
+ u_long drivedata[5]; /* 4 */
+ u_long spare[5]; /* 4 */
+
+ u_long secpercyl; /* 4 */
+ u_long secperunit; /* 4 */
+ u_long headswitch; /* 4 */
+
+ u_char vid_3[4];
+ u_int vid_cas;
+ u_char vid_cal;
+ u_char vid_4_0[3];
+ u_char vid_4[64];
+ u_char vid_4_1[28];
+ u_long sbsize;
+ u_char vid_mot[8];
+
+ /* CFG */
+ u_char cfg_0[4];
+ u_short cfg_atm;
+ u_short cfg_prm;
+ u_short cfg_atw;
+ u_short cfg_rec;
+
+ u_short sparespertrack;
+ u_short sparespercyl;
+ u_long acylinders;
+ u_short rpm;
+ u_short cylskew;
+
+ u_char cfg_spt;
+ u_char cfg_hds;
+ u_short cfg_trk;
+ u_char cfg_ilv;
+ u_char cfg_sof;
+ u_short cfg_psm;
+ u_short cfg_shd;
+ u_char cfg_2[2];
+ u_short cfg_pcom;
+ u_char cfg_3;
+ u_char cfg_ssr;
+ u_short cfg_rwcc;
+ u_short cfg_ecc;
+ u_short cfg_eatm;
+ u_short cfg_eprm;
+ u_short cfg_eatw;
+ u_char cfg_gpb1;
+ u_char cfg_gpb2;
+ u_char cfg_gpb3;
+ u_char cfg_gpb4;
+ u_char cfg_ssc;
+ u_char cfg_runit;
+ u_short cfg_rsvc1;
+ u_short cfg_rsvc2;
+ u_long magic2;
+ u_char cfg_4[192];
+};
+#endif _MACHINE_DISKLABEL_H_
--- /dev/null
+/*
+ * Copyright (c) 1987, 1991, 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.
+ *
+ * from: @(#)endian.h 8.1 (Berkeley) 6/11/93
+ * $Id: endian.h,v 1.1.1.1 1997/03/03 19:30:24 rahnds Exp $
+ */
+
+#ifndef _ENDIAN_H_
+#define _ENDIAN_H_
+
+/*
+ * Define the order of 32-bit words in 64-bit words.
+ */
+#define _QUAD_HIGHWORD 0
+#define _QUAD_LOWWORD 1
+
+#ifndef _POSIX_SOURCE
+/*
+ * Definitions for byte order, according to byte significance from low
+ * address to high.
+ */
+
+#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */
+#define BIG_ENDIAN 4321 /* MSB first: 68000, 88000 ibm, net */
+#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long */
+
+#define BYTE_ORDER BIG_ENDIAN
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+unsigned long htonl __P((unsigned long));
+unsigned short htons __P((unsigned short));
+unsigned long ntohl __P((unsigned long));
+unsigned short ntohs __P((unsigned short));
+__END_DECLS
+
+/*
+ * Macros for network/external number representation conversion.
+ */
+#if BYTE_ORDER == BIG_ENDIAN && !defined(lint)
+#define ntohl(x) (x)
+#define ntohs(x) (x)
+#define htonl(x) (x)
+#define htons(x) (x)
+
+#define NTOHL(x) (x)
+#define NTOHS(x) (x)
+#define HTONL(x) (x)
+#define HTONS(x) (x)
+
+#else
+
+#define NTOHL(x) (x) = ntohl((u_long)x)
+#define NTOHS(x) (x) = ntohs((u_short)x)
+#define HTONL(x) (x) = htonl((u_long)x)
+#define HTONS(x) (x) = htons((u_short)x)
+#endif
+#endif /* ! _POSIX_SOURCE */
+#endif /* !_ENDIAN_H_ */
--- /dev/null
+/*
+ * Mach Operating System
+ * Copyright (c) 1991, 1992 Carnegie Mellon University
+ * Copyright (c) 1991 OMRON Corporation
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#ifndef UNDEFINED
+# define UNDEFINED unknown_handler
+#endif
+/* vector 0x00 (#0) */ word error_handler
+/* vector 0x01 (#1) */ word interrupt_handler
+/* vector 0x02 (#2) */ word instruction_access_handler
+/* vector 0x03 (#3) */ word data_exception_handler
+/* vector 0x04 (#4) */ word misaligned_handler
+/* vector 0x05 (#5) */ word unimplemented_handler
+/* vector 0x06 (#6) */ word privilege_handler
+/* vector 0x07 (#7) */ word bounds_handler
+/* vector 0x08 (#8) */ word divide_handler
+/* vector 0x09 (#9) */ word overflow_handler
+/* vector 0x0a (#10) */ word error_handler
+/* vector 0x0b (#11) */ word UNDEFINED
+/* vector 0x0c (#12) */ word UNDEFINED
+/* vector 0x0d (#13) */ word UNDEFINED
+/* vector 0x0e (#14) */ word UNDEFINED
+/* vector 0x0f (#15) */ word UNDEFINED
+/* vector 0x10 (#16) */ word UNDEFINED
+/* vector 0x11 (#17) */ word UNDEFINED
+/* vector 0x12 (#18) */ word UNDEFINED
+/* vector 0x13 (#19) */ word UNDEFINED
+/* vector 0x14 (#20) */ word UNDEFINED
+/* vector 0x15 (#21) */ word UNDEFINED
+/* vector 0x16 (#22) */ word UNDEFINED
+/* vector 0x17 (#23) */ word UNDEFINED
+/* vector 0x18 (#24) */ word UNDEFINED
+/* vector 0x19 (#25) */ word UNDEFINED
+/* vector 0x1a (#26) */ word UNDEFINED
+/* vector 0x1b (#27) */ word UNDEFINED
+/* vector 0x1c (#28) */ word UNDEFINED
+/* vector 0x1d (#29) */ word UNDEFINED
+/* vector 0x1e (#30) */ word UNDEFINED
+/* vector 0x1f (#31) */ word UNDEFINED
+/* vector 0x20 (#32) */ word UNDEFINED
+/* vector 0x21 (#33) */ word UNDEFINED
+/* vector 0x22 (#34) */ word UNDEFINED
+/* vector 0x23 (#35) */ word UNDEFINED
+/* vector 0x24 (#36) */ word UNDEFINED
+/* vector 0x25 (#37) */ word UNDEFINED
+/* vector 0x26 (#38) */ word UNDEFINED
+/* vector 0x27 (#39) */ word UNDEFINED
+/* vector 0x28 (#40) */ word UNDEFINED
+/* vector 0x29 (#41) */ word UNDEFINED
+/* vector 0x2a (#42) */ word UNDEFINED
+/* vector 0x2b (#43) */ word UNDEFINED
+/* vector 0x2c (#44) */ word UNDEFINED
+/* vector 0x2d (#45) */ word UNDEFINED
+/* vector 0x2e (#46) */ word UNDEFINED
+/* vector 0x2f (#47) */ word UNDEFINED
+/* vector 0x30 (#48) */ word UNDEFINED
+/* vector 0x31 (#49) */ word UNDEFINED
+/* vector 0x32 (#50) */ word UNDEFINED
+/* vector 0x33 (#51) */ word UNDEFINED
+/* vector 0x34 (#52) */ word UNDEFINED
+/* vector 0x35 (#53) */ word UNDEFINED
+/* vector 0x36 (#54) */ word UNDEFINED
+/* vector 0x37 (#55) */ word UNDEFINED
+/* vector 0x38 (#56) */ word UNDEFINED
+/* vector 0x39 (#57) */ word UNDEFINED
+/* vector 0x3a (#58) */ word UNDEFINED
+/* vector 0x3b (#59) */ word UNDEFINED
+/* vector 0x3c (#60) */ word UNDEFINED
+/* vector 0x3d (#61) */ word UNDEFINED
+/* vector 0x3e (#62) */ word UNDEFINED
+/* vector 0x3f (#63) */ word UNDEFINED
+/* vector 0x40 (#64) */ word UNDEFINED
+/* vector 0x41 (#65) */ word UNDEFINED
+/* vector 0x42 (#66) */ word UNDEFINED
+/* vector 0x43 (#67) */ word UNDEFINED
+/* vector 0x44 (#68) */ word UNDEFINED
+/* vector 0x45 (#69) */ word UNDEFINED
+/* vector 0x46 (#70) */ word UNDEFINED
+/* vector 0x47 (#71) */ word UNDEFINED
+/* vector 0x48 (#72) */ word UNDEFINED
+/* vector 0x49 (#73) */ word UNDEFINED
+/* vector 0x4a (#74) */ word UNDEFINED
+/* vector 0x4b (#75) */ word UNDEFINED
+/* vector 0x4c (#76) */ word UNDEFINED
+/* vector 0x4d (#77) */ word UNDEFINED
+/* vector 0x4e (#78) */ word UNDEFINED
+/* vector 0x4f (#79) */ word UNDEFINED
+/* vector 0x50 (#80) */ word UNDEFINED
+/* vector 0x51 (#81) */ word UNDEFINED
+/* vector 0x52 (#82) */ word UNDEFINED
+/* vector 0x53 (#83) */ word UNDEFINED
+/* vector 0x54 (#84) */ word UNDEFINED
+/* vector 0x55 (#85) */ word UNDEFINED
+/* vector 0x56 (#86) */ word UNDEFINED
+/* vector 0x57 (#87) */ word UNDEFINED
+/* vector 0x58 (#88) */ word UNDEFINED
+/* vector 0x59 (#89) */ word UNDEFINED
+/* vector 0x5a (#90) */ word UNDEFINED
+/* vector 0x5b (#91) */ word UNDEFINED
+/* vector 0x5c (#92) */ word UNDEFINED
+/* vector 0x5d (#93) */ word UNDEFINED
+/* vector 0x5e (#94) */ word UNDEFINED
+/* vector 0x5f (#95) */ word UNDEFINED
+/* vector 0x60 (#96) */ word UNDEFINED
+/* vector 0x61 (#97) */ word UNDEFINED
+/* vector 0x62 (#98) */ word UNDEFINED
+/* vector 0x63 (#99) */ word UNDEFINED
+/* vector 0x64 (#100) */ word UNDEFINED
+/* vector 0x65 (#101) */ word UNDEFINED
+/* vector 0x66 (#102) */ word UNDEFINED
+/* vector 0x67 (#103) */ word UNDEFINED
+/* vector 0x68 (#104) */ word UNDEFINED
+/* vector 0x69 (#105) */ word UNDEFINED
+/* vector 0x6a (#106) */ word UNDEFINED
+/* vector 0x6b (#107) */ word UNDEFINED
+/* vector 0x6c (#108) */ word UNDEFINED
+/* vector 0x6d (#109) */ word UNDEFINED
+/* vector 0x6e (#110) */ word UNDEFINED
+/* vector 0x6f (#111) */ word UNDEFINED
+/* vector 0x70 (#112) */ word UNDEFINED
+/* vector 0x71 (#113) */ word UNDEFINED
+/* vector 0x72 (#114) */ word fp_precise_handler
+/* vector 0x73 (#115) */ word fp_imprecise_handler
+/* vector 0x74 (#116) */ word unimplemented_handler
+/* vector 0x75 (#117) */ word UNDEFINED
+/* vector 0x76 (#118) */ word unimplemented_handler
+/* vector 0x77 (#119) */ word UNDEFINED
+/* vector 0x78 (#120) */ word unimplemented_handler
+/* vector 0x79 (#121) */ word UNDEFINED
+/* vector 0x7a (#122) */ word unimplemented_handler
+/* vector 0x7b (#123) */ word UNDEFINED
+/* vector 0x7c (#124) */ word unimplemented_handler
+/* vector 0x7d (#125) */ word UNDEFINED
+/* vector 0x7e (#126) */ word unimplemented_handler
+/* vector 0x7f (#127) */ word UNDEFINED
+/* vector 0x80 (#128) */ word _syscall_handler
+/* vector 0x81 (#129) */ word _syscall_handler
+/* vector 0x82 (#130) */ word break
+/* vector 0x83 (#131) */ word trace
+/* vector 0x84 (#132) */ word entry
+#if defined(RAW_PRINTF) && RAW_PRINTF
+/* vector 0x85 (#133) */ word user_raw_putstr /* for USER raw_printf() */
+/* vector 0x85 (#134) */ word user_raw_xpr /* for USER raw_xpr() */
+#endif
--- /dev/null
+#ifndef _MACHINE_EXEC_H_
+#define _MACHINE_EXEC_H_
+
+#define __LDPGSZ 4096
+
+struct relocation_info_m88k {
+ unsigned int r_address; /* offset in text or data segment */
+ unsigned int r_symbolnum : 24, /* ordinal number of add symbol */
+ r_extern : 1, /* 1 if need to add symbol to value */
+ r_baserel : 1,
+ r_pcrel : 1,
+ r_jmptable : 1,
+ r_type : 4;
+
+ int r_addend;
+};
+#define relocation_info relocation_info_m88k
+#endif _MACHINE_EXEC_H_
--- /dev/null
+/* $NetBSD: float.h,v 1.10 1995/06/20 20:45:41 jtc Exp $ */
+
+/*
+ * Copyright (c) 1989 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.
+ *
+ * @(#)float.h 7.1 (Berkeley) 5/8/90
+ */
+
+#ifndef _M88K_FLOAT_H_
+#define _M88K_FLOAT_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern int __flt_rounds();
+__END_DECLS
+
+#define FLT_RADIX 2 /* b */
+#define FLT_ROUNDS __flt_rounds()
+
+#define FLT_MANT_DIG 24 /* p */
+#define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */
+#define FLT_DIG 6 /* floor((p-1)*log10(b))+(b == 10) */
+#define FLT_MIN_EXP -125 /* emin */
+#define FLT_MIN 1.17549435E-38F /* b**(emin-1) */
+#define FLT_MIN_10_EXP -37 /* ceil(log10(b**(emin-1))) */
+#define FLT_MAX_EXP 128 /* emax */
+#define FLT_MAX 3.40282347E+38F /* (1-b**(-p))*b**emax */
+#define FLT_MAX_10_EXP 38 /* floor(log10((1-b**(-p))*b**emax)) */
+
+#define DBL_MANT_DIG 53
+#define DBL_EPSILON 2.2204460492503131E-16
+#define DBL_DIG 15
+#define DBL_MIN_EXP -1021
+#define DBL_MIN 2.2250738585072014E-308
+#define DBL_MIN_10_EXP -307
+#define DBL_MAX_EXP 1024
+#define DBL_MAX 1.7976931348623157E+308
+#define DBL_MAX_10_EXP 308
+
+#define LDBL_MANT_DIG DBL_MANT_DIG
+#define LDBL_EPSILON DBL_EPSILON
+#define LDBL_DIG DBL_DIG
+#define LDBL_MIN_EXP DBL_MIN_EXP
+#define LDBL_MIN DBL_MIN
+#define LDBL_MIN_10_EXP DBL_MIN_10_EXP
+#define LDBL_MAX_EXP DBL_MAX_EXP
+#define LDBL_MAX DBL_MAX
+#define LDBL_MAX_10_EXP DBL_MAX_10_EXP
+
+#endif /* !_M88K_FLOAT_H_ */
--- /dev/null
+/*
+ * 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.
+ *
+ * @(#)ieee.h 8.1 (Berkeley) 6/11/93
+ */
+/*
+ * Stolen from sparc port
+ */
+
+/*
+ * ieee.h defines the machine-dependent layout of the machine's IEEE
+ * floating point. It does *not* define (yet?) any of the rounding
+ * mode bits, exceptions, and so forth.
+ */
+
+/*
+ * Define the number of bits in each fraction and exponent.
+ *
+ * k k+1
+ * Note that 1.0 x 2 == 0.1 x 2 and that denorms are represented
+ *
+ * (-exp_bias+1)
+ * as fractions that look like 0.fffff x 2 . This means that
+ *
+ * -126
+ * the number 0.10000 x 2 , for instance, is the same as the normalized
+ *
+ * -127 -128
+ * float 1.0 x 2 . Thus, to represent 2 , we need one leading zero
+ *
+ * -129
+ * in the fraction; to represent 2 , we need two, and so on. This
+ *
+ * (-exp_bias-fracbits+1)
+ * implies that the smallest denormalized number is 2
+ *
+ * for whichever format we are talking about: for single precision, for
+ *
+ * -126 -149
+ * instance, we get .00000000000000000000001 x 2 , or 1.0 x 2 , and
+ *
+ * -149 == -127 - 23 + 1.
+ */
+#define SNG_EXPBITS 8
+#define SNG_FRACBITS 23
+
+#define DBL_EXPBITS 11
+#define DBL_FRACBITS 52
+
+#ifdef notyet
+#define E80_EXPBITS 15
+#define E80_FRACBITS 64
+#endif
+
+#define EXT_EXPBITS 15
+#define EXT_FRACBITS 112
+
+struct ieee_single {
+ u_int sng_sign:1;
+ u_int sng_exp:8;
+ u_int sng_frac:23;
+};
+
+struct ieee_double {
+ u_int dbl_sign:1;
+ u_int dbl_exp:11;
+ u_int dbl_frach:20;
+ u_int dbl_fracl;
+};
+
+struct ieee_ext {
+ u_int ext_sign:1;
+ u_int ext_exp:15;
+ u_int ext_frach:16;
+ u_int ext_frachm;
+ u_int ext_fraclm;
+ u_int ext_fracl;
+};
+
+/*
+ * Floats whose exponent is in [1..INFNAN) (of whatever type) are
+ * `normal'. Floats whose exponent is INFNAN are either Inf or NaN.
+ * Floats whose exponent is zero are either zero (iff all fraction
+ * bits are zero) or subnormal values.
+ *
+ * A NaN is a `signalling NaN' if its QUIETNAN bit is clear in its
+ * high fraction; if the bit is set, it is a `quiet NaN'.
+ */
+#define SNG_EXP_INFNAN 255
+#define DBL_EXP_INFNAN 2047
+#define EXT_EXP_INFNAN 32767
+
+#if 0
+#define SNG_QUIETNAN (1 << 22)
+#define DBL_QUIETNAN (1 << 19)
+#define EXT_QUIETNAN (1 << 15)
+#endif
+
+/*
+ * Exponent biases.
+ */
+#define SNG_EXP_BIAS 127
+#define DBL_EXP_BIAS 1023
+#define EXT_EXP_BIAS 16383
--- /dev/null
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * 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 Nivas Madhur.
+ * 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.
+ *
+ */
+/*
+ * Values for fp_except are selected to match the bits in FPSR (see
+ * m88100 user's manual page 6-33). This file is derived from the
+ * defintions in the ABI/88k manual and sparc port.
+ * -- Nivas
+ */
+
+#ifndef _M88K_IEEEFP_H_
+#define _M88K_IEEEFP_H_
+
+typedef int fp_except;
+#define FP_X_INV 0x10 /* invalid operation exception */
+#define FP_X_DZ 0x08 /* divide-by-zero exception */
+#define FP_X_UFL 0x04 /* underflow exception */
+#define FP_X_OFL 0x02 /* overflow exception */
+#define FP_X_IMP 0x01 /* imprecise (loss of precision) */
+
+typedef enum {
+ FP_RN=0, /* round to nearest representable number */
+ FP_RZ=1, /* round to zero (truncate) */
+ FP_RM=2, /* round toward negative infinity */
+ FP_RP=3 /* round toward positive infinity */
+} fp_rnd;
+
+#endif /* _M88K_IEEEFP_H_ */
--- /dev/null
+/*
+ * Copyright (c) 1988, 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.
+ *
+ * from: @(#)limits.h 8.3 (Berkeley) 1/4/94
+ * $Id: limits.h,v 1.1.1.1 1997/03/03 19:30:24 rahnds Exp $
+ */
+
+#define CHAR_BIT 8 /* number of bits in a char */
+#define MB_LEN_MAX 6 /* Allow 31 bit UTF2 */
+
+/*
+ * According to ANSI (section 2.2.4.2), the values below must be usable by
+ * #if preprocessing directives. Additionally, the expression must have the
+ * same type as would an expression that is an object of the corresponding
+ * type converted according to the integral promotions. The subtraction for
+ * INT_MIN and LONG_MIN is so the value is not unsigned; 2147483648 is an
+ * unsigned int for 32-bit two's complement ANSI compilers (section 3.1.3.2).
+ * These numbers work for pcc as well. The UINT_MAX and ULONG_MAX values
+ * are written as hex so that GCC will be quiet about large integer constants.
+ */
+#define SCHAR_MAX 127 /* min value for a signed char */
+#define SCHAR_MIN (-128) /* max value for a signed char */
+
+#define UCHAR_MAX 255 /* max value for an unsigned char */
+#define CHAR_MAX 127 /* max value for a char */
+#define CHAR_MIN (-128) /* min value for a char */
+
+#define USHRT_MAX 65535 /* max value for an unsigned short */
+#define SHRT_MAX 32767 /* max value for a short */
+#define SHRT_MIN (-32768) /* min value for a short */
+
+#define UINT_MAX 0xffffffff /* max value for an unsigned int */
+#define INT_MAX 2147483647 /* max value for an int */
+#define INT_MIN (-2147483647-1) /* min value for an int */
+
+#define ULONG_MAX 0xffffffff /* max value for an unsigned long */
+#define LONG_MAX 2147483647 /* max value for a long */
+#define LONG_MIN (-2147483647-1) /* min value for a long */
+
+#if !defined(_ANSI_SOURCE)
+#define SSIZE_MAX INT_MAX /* max value for a ssize_t */
+
+#if !defined(_POSIX_SOURCE)
+#define SIZE_T_MAX UINT_MAX /* max value for a size_t */
+
+/* GCC requires that quad constants be written as expressions. */
+#define UQUAD_MAX ((u_quad_t)0-1) /* max value for a uquad_t */
+ /* max value for a quad_t */
+#define QUAD_MAX ((quad_t)(UQUAD_MAX >> 1))
+#define QUAD_MIN (-QUAD_MAX-1) /* min value for a quad_t */
+
+#endif /* !_POSIX_SOURCE */
+#endif /* !_ANSI_SOURCE */
--- /dev/null
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1991 Carnegie Mellon University
+ * Copyright (c) 1991 OMRON Corporation
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/* "locore.h" Omron Corporation
+ * This file created by Omron Corporation, 1990.
+ * NOTE: Any assembly file that includes this one must define ASSEMBLER first
+ */
+
+#ifndef __MACHINE_LOCORE_H__
+#define __MACHINE_LOCORE_H__
+
+
+/*
+ **********************************************************************
+ SYNTACTICAL AND SEMANTIC DOO-DADS
+ **********************************************************************
+ */
+/*
+ * NEWLINE is defined in 'assmy.s' in the object area to be a double
+ * backslash, which 'as' interprets the same as '\n'
+ */
+
+/*
+ * If this has been included in an assembly file, make sure
+ * LOCORE is defined. Always make sure KERNEL is defined.
+ */
+#if defined(ASSEMBLER) && !defined(LOCORE)
+# define LOCORE
+#endif
+#if !defined(KERNEL)
+# define KERNEL
+#endif
+
+/* Define EH_DEBUG to be non-zero to compile-in various debugging things */
+#ifndef EH_DEBUG
+#define EH_DEBUG 0
+#endif EH_DEBUG
+
+/* this gives the offsets into various structures of various elements, etc */
+#include "assym.s"
+
+/*
+ * LABEL(name)
+ * Defines the name to be a label visible to the world.
+ *
+ * _LABEL(name)
+ * Defines one visible only to the file, unless debugging
+ * is enabled, in which case it's visible to the world (and
+ * hence to debuggers, and such).
+ */
+#define LABEL(name) name: global name NEWLINE
+#if EH_DEBUG
+# define _LABEL(name) name: global name NEWLINE
+#else
+# define _LABEL(name) name: NEWLINE
+#endif
+
+
+/*
+ * Useful in some situations.
+ * NOTE: If ARG1 or ARG2 are r2 or r3, strange things may happen. Watch out!
+ */
+#define CALL(NAME, ARG1, ARG2) \
+ subu r31, r31, 32 NEWLINE \
+ or r2, r0, ARG1 NEWLINE \
+ bsr.n NAME NEWLINE \
+ or r3, r0, ARG2 NEWLINE \
+ addu r31, r31, 32
+
+/*
+ **********************************************************************
+ SYMBOLIC CONSTANTS AND VALUES and other important things
+ **********************************************************************
+ */
+
+/*
+ * SR1 - CPU FLAGS REGISTER
+ *
+ * SR1 contains flags about the current CPU status.
+ *
+ * The lowest FLAG_CPU_FIELD_WIDTH bits hold the cpu number (currently 0-3).
+ *
+ *
+ * The bit FLAG_IGNORE_DATA_EXCEPTION indicates that any data exceptions
+ * should be ignored (well, at least treated in a special way).
+ * The bit FLAG_INTERRUPT_EXCEPTION indicates that the current exception
+ * is the interrupt exception. Such information can be gotten
+ * in other ways, but having it in the flags makes it easy for the
+ * exception handler to check quickly.
+ * The bit FLAG_ENABLING_FPU indicates that the exception handler is
+ * in the process of enabling the FPU (so that an exception can
+ * be serviced). This is needed because enabling the FPU can
+ * cause other exceptions to happen, and the whole system is
+ * in a rather precarious state and so special cautions must
+ * be taken.
+ */
+#define FLAG_CPU_FIELD_WIDTH 4 /* must be <= 12 */
+
+#define FLAG_IGNORE_DATA_EXCEPTION 5 /* bit number 5 */
+#define FLAG_INTERRUPT_EXCEPTION 6 /* bit number 6 */
+#define FLAG_ENABLING_FPU 7 /* bit number 7 */
+
+
+/* REGister OFFset into the E.F. (exception frame) */
+#define REG_OFF(reg_num) ((reg_num) * 4) /* (num * sizeof(register int)) */
+#define GENREG_OFF(num) (REG_OFF(EF_R0 + (num))) /* GENeral REGister OFFset */
+
+
+#define GENERAL_BREATHING_ROOM /* arbitrarily */ 200
+#define KERNEL_STACK_BREATHING_ROOM \
+ (GENERAL_BREATHING_ROOM + SIZEOF_STRUCT_PCB + SIZEOF_STRUCT_UTHREAD)
+
+/*
+ * Some registers used during the setting up of the new exception frame.
+ * Don't choose r1, r30, or r31 for any of them.
+ *
+ * Also, if any are 'r2' or 'r3', be careful using with CALL above!
+ */
+#define FLAGS r2
+#define TMP r3
+#define TMP2 r10
+#define TMP3 r11
+#define SAVE_TMP2 st r10, r31, GENREG_OFF(10)
+#define SAVE_TMP3 st r11, r31, GENREG_OFF(11)
+#define RESTORE_TMP2 ld r10, r31, GENREG_OFF(10)
+#define RESTORE_TMP3 ld r11, r31, GENREG_OFF(11)
+
+
+/* alternate CPU control register names */
+#define PID cr0
+#define PSR cr1
+#define EPSR cr2
+#define SSBR cr3
+#define SXIP cr4
+#define SNIP cr5
+#define SFIP cr6
+#define VBR cr7
+#define DMT0 cr8
+#define DMD0 cr9
+#define DMA0 cr10
+#define DMT1 cr11
+#define DMD1 cr12
+#define DMA1 cr13
+#define DMT2 cr14
+#define DMD2 cr15
+#define DMA2 cr16
+#define SR0 cr17
+#define SR1 cr18
+#define SR2 cr19
+#define SR3 cr20
+#define FPECR fcr0
+#define FPHS1 fcr1
+#define FPLS1 fcr2
+#define FPHS2 fcr3
+#define FPLS2 fcr4
+#define FPPT fcr5
+#define FPRH fcr6
+#define FPRL fcr7
+#define FPIT fcr8
+#define FPSR fcr62
+#define FPCR fcr63
+
+/*
+ * Info about the PSR
+ */
+#define PSR_SHADOW_FREEZE_BIT 0
+#define PSR_INTERRUPT_DISABLE_BIT 1
+#define PSR_FPU_DISABLE_BIT 3
+#define PSR_BIG_ENDIAN_MODE 30
+#define PSR_SUPERVISOR_MODE_BIT 31
+
+/*
+ * Status bits for an SXIP/SNIP/SFIP address.
+ */
+#define RTE_VALID_BIT 1
+#define RTE_ERROR_BIT 0
+
+/*
+ * Info about DMT0/DMT1/DMT2
+ */
+#define DMT_VALID_BIT 0
+#define DMT_WRITE_BIT 1
+#define DMT_LOCK_BIT 12
+#define DMT_DOUBLE_BIT 13
+#define DMT_DAS_BIT 14
+#define DMT_DREG_OFFSET 7
+#define DMT_DREG_WIDTH 5
+
+/*
+ * Bits for eh_debug.
+ */
+#define DEBUG_INTERRUPT_BIT 0
+#define DEBUG_DATA_BIT 1
+#define DEBUG_INSTRUCTION_BIT 2
+#define DEBUG_MISALIGN_BIT 3
+#define DEBUG_UNIMP_BIT 4
+#define DEBUG_DIVIDE_BIT 5
+#define DEBUG_OF_BIT 6
+#define DEBUG_FPp_BIT 7
+#define DEBUG_FPi_BIT 8
+#define DEBUG_SYSCALL_BIT 9
+#define DEBUG_MACHSYSCALL_BIT 10
+#define DEBUG_UNIMPLEMENTED_BIT 11
+#define DEBUG_PRIVILEGE_BIT 12
+#define DEBUG_BOUNDS_BIT 13
+#define DEBUG_OVERFLOW_BIT 14
+#define DEBUG_ERROR_BIT 15
+#define DEBUG_SIGSYS_BIT 16
+#define DEBUG_SIGTRAP_BIT 17
+#define DEBUG_BREAK_BIT 18
+#define DEBUG_TRACE_BIT 19
+#define DEBUG_KDB_BIT 20
+#define DEBUG_JKDB_BIT 21
+#define DEBUG_BUGCALL_BIT 22
+
+#define DEBUG_UNKNOWN_BIT 31
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+#define YES 1
+#define NO 0
+
+#define SCSI_INTS 0x10
+#define SCSI_SSTS 0x18
+#define SCSI_DREG 0x28
+
+/* change software timer for 8mm device support -- 90/08/21 CEC OKUI */
+#define SCSI_WAIT 0x5000000
+
+/*
+ * At various times, there is the need to clear the pipeline (i.e.
+ * synchronize). A "tcnd ne0, r0, foo" will do that (because a trap
+ * instruction always synchronizes, and this particular instruction
+ * will never actually take the trap).
+ */
+#define FLUSH_PIPELINE tcnd ne0, r0, 0
+
+/*
+ * NOP -- NO-Operation.
+ *
+ * A do-nothing one clock doesn't-touch-the-scoreboard type of instruction,
+ * in case one's needed (sometimes useful for debugging).
+ */
+#define NOP or r0, r0, r0
+
+/*
+ * These things for vector_init.c and locore.c
+ */
+#if defined(ASSEMBLER)
+# define PREDEFINED_BY_ROM 0xffffffff
+# define END_OF_VECTOR_LIST 0xfffffffe
+#else
+# define PREDEFINED_BY_ROM 0xffffffffU
+# define END_OF_VECTOR_LIST 0xfffffffeU
+#endif
+
+/*
+ * Define ERROR__XXX_USR if the xxx.usr bug (mask C82N) is present.
+ * This implements the workaround.
+ */
+#define ERRATA__XXX_USR 1
+
+#define USERMODE(x) (!(x & (1 << PSR_SUPERVISOR_MODE_BIT)))
+
+#endif /* __MACHINE_LOCORE_H__ */
--- /dev/null
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * HISTORY
+ */
+/*
+ * M88100 flags
+ */
+
+#ifndef _M88100_H_
+#define _M88100_H_
+
+
+/*
+ * 88100 RISC definitions
+ */
+
+/* DMT0, DMT1, DMT2 */
+#define DMT_BO 0x00008000 /* Byte-Ordering */
+#define DMT_DAS 0x00004000 /* Data Access Space */
+#define DMT_DOUB1 0x00002000 /* Double Word */
+#define DMT_LOCKBAR 0x00001000 /* Bud Lock */
+#define DMT_DREG 0x00000F80 /* Destination Registers 5bits */
+#define DMT_SIGNED 0x00000040 /* Sign-Extended Bit */
+#define DMT_EN 0x0000003C /* Byte Enable Bit */
+#define DMT_WRITE 0x00000002 /* Read/Write Transaction Bit */
+#define DMT_VALID 0x00000001 /* Valid Transaction Bit */
+
+#ifndef ASSEMBLER
+#include "sys/types.h"
+
+struct dmt_reg {
+ unsigned int :16,
+ dmt_bo:1,
+ dmt_das:1,
+ dmt_doub1:1,
+ dmt_lockbar:1,
+ dmt_dreg:5,
+ dmt_signed:1,
+ dmt_en:4,
+ dmt_write:1,
+ dmt_valid:1;
+};
+#endif
+
+#endif _M88100_H_
--- /dev/null
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * HISTORY
+ *
+ */
+
+
+#ifndef __MACHINE_M882XX_H__
+#define __MACHINE_M882XX_H__
+
+#ifndef ASSEMBLER
+# include <machine/mmu.h> /* batc_template_t */
+#endif
+
+#include <machine/board.h>
+
+/*
+ * 88200 CMMU definitions
+ */
+#define CMMU_IDR 0x000 /* CMMU id register */
+#define CMMU_SCR 0x004 /* system command register */
+#define CMMU_SSR 0x008 /* system status register */
+#define CMMU_SAR 0x00C /* system address register */
+#define CMMU_SCTR 0x104 /* system control register */
+#define CMMU_PFSR 0x108 /* P bus fault status register */
+#define CMMU_PFAR 0x10C /* P bus fault address register */
+#define CMMU_SAPR 0x200 /* supervisor area pointer register */
+#define CMMU_UAPR 0x204 /* user area pointer register */
+#define CMMU_BWP0 0x400 /* block ATC writer port 0 */
+#define CMMU_BWP1 0x404 /* block ATC writer port 1 */
+#define CMMU_BWP2 0x408 /* block ATC writer port 2 */
+#define CMMU_BWP3 0x40C /* block ATC writer port 3 */
+#define CMMU_BWP4 0x410 /* block ATC writer port 4 */
+#define CMMU_BWP5 0x414 /* block ATC writer port 5 */
+#define CMMU_BWP6 0x418 /* block ATC writer port 6 */
+#define CMMU_BWP7 0x41C /* block ATC writer port 7 */
+#define CMMU_CDP0 0x800 /* cache data port 0 */
+#define CMMU_CDP1 0x804 /* cache data port 1 */
+#define CMMU_CDP2 0x808 /* cache data port 2 */
+#define CMMU_CDP3 0x80C /* cache data port 3 */
+#define CMMU_CTP0 0x840 /* cache tag port 0 */
+#define CMMU_CTP1 0x844 /* cache tag port 1 */
+#define CMMU_CTP2 0x848 /* cache tag port 2 */
+#define CMMU_CTP3 0x84C /* cache tag port 3 */
+#define CMMU_CSSP 0x880 /* cache set status register */
+
+/* 88204 CMMU definitions */
+#define CMMU_CSSP0 0x880 /* cache set status register */
+#define CMMU_CSSP1 0x890 /* cache set status register */
+#define CMMU_CSSP2 0x8A0 /* cache set status register */
+#define CMMU_CSSP3 0x8B0 /* cache set status register */
+
+/* CMMU systerm commands */
+#define CMMU_FLUSH_USER_LINE 0x30 /* flush PATC */
+#define CMMU_FLUSH_USER_PAGE 0x31
+#define CMMU_FLUSH_USER_SEGMENT 0x32
+#define CMMU_FLUSH_USER_ALL 0x33
+#define CMMU_FLUSH_SUPER_LINE 0x34
+#define CMMU_FLUSH_SUPER_PAGE 0x35
+#define CMMU_FLUSH_SUPER_SEGMENT 0x36
+#define CMMU_FLUSH_SUPER_ALL 0x37
+#define CMMU_PROBE_USER 0x20 /* probe user address */
+#define CMMU_PROBE_SUPER 0x24 /* probe supervisor address */
+#define CMMU_FLUSH_CACHE_INV_LINE 0x14 /* data cache invalidate */
+#define CMMU_FLUSH_CACHE_INV_PAGE 0x15
+#define CMMU_FLUSH_CACHE_INV_SEGMENT 0x16
+#define CMMU_FLUSH_CACHE_INV_ALL 0x17
+#define CMMU_FLUSH_CACHE_CB_LINE 0x18 /* data cache copyback */
+#define CMMU_FLUSH_CACHE_CB_PAGE 0x19
+#define CMMU_FLUSH_CACHE_CB_SEGMENT 0x1A
+#define CMMU_FLUSH_CACHE_CB_ALL 0x1B
+#define CMMU_FLUSH_CACHE_CBI_LINE 0x1C /* copyback and invalidate */
+#define CMMU_FLUSH_CACHE_CBI_PAGE 0x1D
+#define CMMU_FLUSH_CACHE_CBI_SEGMENT 0x1E
+#define CMMU_FLUSH_CACHE_CBI_ALL 0x1F
+
+/* CMMU system control command */
+#define CMMU_SCTR_PE 0x00008000 /* parity enable */
+#define CMMU_SCTR_SE 0x00004000 /* snoop enable */
+#define CMMU_SCTR_PR 0x00002000 /* priority arbitration */
+
+/* CMMU P bus fault status */
+#define CMMU_PFSR_SUCCESS 0 /* no fault */
+#define CMMU_PFSR_BERROR 3 /* bus error */
+#define CMMU_PFSR_SFAULT 4 /* segment fault */
+#define CMMU_PFSR_PFAULT 5 /* page fault */
+#define CMMU_PFSR_SUPER 6 /* supervisor violation */
+#define CMMU_PFSR_WRITE 7 /* writer violation */
+
+/* Area Description */
+#define AREA_D_WT 0x00000200 /* write through */
+#define AREA_D_G 0x00000080 /* global */
+#define AREA_D_CI 0x00000040 /* cache inhibit */
+#define AREA_D_TE 0x00000001 /* translation enable */
+
+/* Segment Description */
+#define SEG_D_WT 0x00000200 /* write through */
+#define SEG_D_SP 0x00000100 /* supervisor protection */
+#define SEG_D_G 0x00000080 /* global */
+#define SEG_D_CI 0x00000040 /* cache inhibit */
+#define SEG_D_WP 0x00000004 /* write protect */
+#define SEG_D_V 0x00000001 /* valid */
+
+/*
+ * Flags for cmmu_flush_tlb
+ */
+#define FLUSH_KERNEL 1
+#define FLUSH_USER 0
+#define FLUSH_ALL ((vm_offset_t)~0)
+
+
+#ifndef ASSEMBLER
+/*
+ * This file defines the data structures for the mmu.
+ * One major data structure, the page descriptor, is not defined here
+ * but rather in pte.h as struct pte.
+ */
+
+struct area_d { /* area descriptor */
+ unsigned
+ ad_addr:20, /* segment table base address */
+ : 2,
+ ad_wt : 1, /* write through */
+ : 1,
+ ad_g : 1, /* global */
+ ad_ci : 1, /* cache inhibit */
+ : 5,
+ ad_te : 1; /* translation enable */
+};
+
+struct segment_d { /* segment descriptor */
+ unsigned
+ sd_addr:20, /* page table base address */
+ : 2,
+ sd_wt : 1, /* write through */
+ sd_sp : 1, /* supervisor protection */
+ sd_g : 1, /* global */
+ sd_ci : 1, /* cache inhibit */
+ : 3,
+ sd_wp : 1, /* write protect */
+ : 1,
+ sd_v : 1; /* valid */
+};
+
+typedef struct segment_d segment_d_t;
+
+struct pfsr { /* P bus fault status register */
+ unsigned
+ :13,
+ pfsr_fc: 3, /* falut code */
+ :16;
+};
+
+struct batc { /* block address translation register */
+ unsigned
+ batc_lba:13, /* logical block address */
+ batc_pba:13, /* physical block address */
+ batc_s : 1, /* supervisor */
+ batc_wt : 4, /* write through */
+ batc_g : 1, /* global */
+ batc_ci : 1, /* cache inhibit */
+ batc_wp : 1, /* write protect */
+ batc_v : 1; /* valid */
+};
+
+/*
+ * Prototypes and stuff for cmmu.c.
+ */
+extern unsigned cpu_sets[MAX_CPUS];
+extern unsigned ncpus;
+extern unsigned cache_policy;
+
+#ifdef CMMU_DEBUG
+ void show_apr(unsigned value);
+ void show_sctr(unsigned value);
+#endif
+
+/*
+ * Prototypes from "motorola/m88k/m88100/cmmu.c"
+ */
+unsigned cmmu_cpu_number(void);
+#if !DDB
+static
+#endif /* !DDB */
+unsigned cmmu_remote_get(unsigned cpu, unsigned r, unsigned data);
+unsigned cmmu_get_idr(unsigned data);
+void cmmu_init(void);
+void cmmu_shutdown_now(void);
+void cmmu_parity_enable(void);
+#if !DDB
+static
+#endif /* !DDB */
+void cmmu_remote_set(unsigned cpu, unsigned r, unsigned data, unsigned x);
+void cmmu_set_sapr(unsigned ap);
+void cmmu_remote_set_sapr(unsigned cpu, unsigned ap);
+void cmmu_set_uapr(unsigned ap);
+void cmmu_flush_tlb(unsigned kernel, vm_offset_t vaddr, int size);
+void cmmu_flush_remote_cache(int cpu, vm_offset_t physaddr, int size);
+void cmmu_flush_cache(vm_offset_t physaddr, int size);
+void cmmu_flush_remote_inst_cache(int cpu, vm_offset_t physaddr, int size);
+void cmmu_flush_inst_cache(vm_offset_t physaddr, int size);
+void cmmu_flush_remote_data_cache(int cpu, vm_offset_t physaddr, int size);
+void cmmu_flush_data_cache(vm_offset_t physaddr, int size);
+
+void cmmu_pmap_activate(
+ unsigned cpu,
+ unsigned uapr,
+ batc_template_t i_batc[BATC_MAX],
+ batc_template_t d_batc[BATC_MAX]);
+
+void cmmu_flush_remote_tlb(
+ unsigned cpu,
+ unsigned kernel,
+ vm_offset_t vaddr,
+ int size);
+
+void cmmu_set_batc_entry(
+ unsigned cpu,
+ unsigned entry_no,
+ unsigned data, /* 1 = data, 0 = instruction */
+ unsigned value); /* the value to stuff into the batc */
+
+void cmmu_set_pair_batc_entry(
+ unsigned cpu,
+ unsigned entry_no,
+ unsigned value); /* the value to stuff into the batc */
+
+#endif /* ASSEMBLER */
+
+#define INST_CMMU 0
+#define DATA_CMMU 1
+
+#define NBSG (4*1024*1024) /* segment size */
+
+#endif /* __MACHINE_M882XX_H__ */
--- /dev/null
+/*
+ * Ashura Project
+ */
+/*
+ * HISTORY
+ *
+ * Original SCCS ID in ISEDL
+ * @(#)mmu.h 1.22 90/09/20 19:13:34
+ */
+
+#ifndef _MACHINE_MMU_
+#define _MACHINE_MMU_
+
+/* for m88k_pgbytes, m8kk_pgshift */
+#include <machine/vmparam.h>
+
+
+/*
+ * Parameters which determine the 'geometry' of the M88K page tables in memory.
+ */
+#define SDT_BITS 10 /* M88K segment table size bits */
+#define PDT_BITS 10 /* M88K page table size bits */
+#define PG_BITS M88K_PGSHIFT /* M88K hardware page size bits */
+
+/*
+ * Shifts and masks for M88K (hardware) page
+ */
+/* M88K_PGBYTES, PG_SHIFT in vm_param.h */
+#define M88K_PGOFSET (M88K_PGBYTES-1) /* offset into M88K page */
+#define M88K_PGMASK (~M88K_PGOFSET) /* page mask */
+
+/*
+ * Convert byte address to page frame number
+ */
+#define M88K_BTOP(x) (((unsigned) (x)) >> M88K_PGSHIFT)
+#define M88K_PTOB(x) (((unsigned) (x)) << M88K_PGSHIFT)
+
+/*
+ * Round off or truncate to the nearest page. These will work for
+ * either addresses of counts. (i.e. 1 byte round to 1 page bytes).
+ */
+#define M88K_TRUNC_PAGE(x) (((unsigned) (x) & M88K_PGMASK))
+#define M88K_ROUND_PAGE(x) M88K_TRUNC_PAGE((x) + M88K_PGOFSET)
+
+/*
+ * M88K area descriptors
+ */
+typedef struct cmmu_apr {
+ unsigned long
+ st_base:20, /* segment table base address */
+ rsvA:2, /* reserved */
+ wt:1, /* writethrough (cache control) */
+ rsvB:1, /* reserved */
+ g:1, /* global (cache control) */
+ ci:1, /* cache inhibit */
+ rsvC:5, /* reserved */
+ te:1; /* transration enable */
+} cmmu_apr_t;
+
+typedef union apr_template {
+ cmmu_apr_t field;
+ unsigned long bits;
+} apr_template_t;
+
+/*
+ * M88K segment descriptors
+ */
+typedef struct sdt_entry {
+ unsigned long
+ table_addr:20, /* page table base address */
+ rsvA:2, /* reserved */
+ wt:1, /* writethrough (cache control) */
+ sup:1, /* supervisor protection */
+ g:1, /* global (cache control) */
+ no_cache:1, /* cache inhibit */
+ rsvB:3, /* reserved */
+ prot:1, /* write protect */
+ rsvC:1, /* reserved */
+ dtype:1; /* valid */
+} sdt_entry_t;
+
+typedef union sdt_entry_template {
+ sdt_entry_t sdt_desc;
+ unsigned long bits;
+} sdt_entry_template_t;
+
+#define SDT_ENTRY_NULL ((sdt_entry_t *) 0)
+
+/*
+ * M88K page descriptors
+ */
+typedef struct pt_entry {
+ unsigned long
+ pfn:20, /* page frame address */
+ rsvA:1, /* reserved */
+ wired:1, /* wired bit <<software>> */
+ wt:1, /* writethrough (cache control) */
+ sup:1, /* supervisor protection */
+ g:1, /* global (cache control) */
+ ci:1, /* cache inhibit */
+ rsvB:1, /* reserved */
+ modified:1, /* modified */
+ pg_used:1, /* used (referenced) */
+ prot:1, /* write protect */
+ rsvC:1, /* reserved */
+ dtype:1; /* valid */
+} pt_entry_t;
+
+typedef union pte_template {
+ pt_entry_t pte;
+ unsigned long bits;
+} pte_template_t;
+
+#define PT_ENTRY_NULL ((pt_entry_t *) 0)
+
+/*
+ * 88200 PATC (TLB)
+ */
+
+#define PATC_ENTRIES 56
+
+/*
+ * M88K BATC entries
+ */
+typedef struct {
+ unsigned long
+ lba:13, /* logical block address */
+ pba:13, /* physical block address */
+ sup:1, /* supervisor mode bit */
+ wt:1, /* writethrough (cache control) */
+ g:1, /* global (cache control) */
+ ci:1, /* cache inhibit */
+ wp:1, /* write protect */
+ v:1; /* valid */
+} batc_entry_t;
+
+typedef union batc_template {
+ batc_entry_t field;
+ unsigned long bits;
+} batc_template_t;
+
+/*
+ * Parameters and macros for BATC
+ */
+#define BATC_BLKBYTES (512*1024) /* 'block' size of a BATC entry mapping */
+#define BATC_BLKSHIFT 19 /* number of bits to BATC shift (log2(BATC_BLKBYTES)) */
+#define BATC_BLKMASK (BATC_BLKBYTES-1) /* BATC block mask */
+
+#define BATC_MAX 8 /* number of BATC entries */
+
+#define BATC_BLK_ALIGNED(x) ((x & BATC_BLKMASK) == 0)
+
+#define M88K_BTOBLK(x) (x >> BATC_BLKSHIFT)
+
+/*
+ * protection codes (prot field)
+ */
+#define M88K_RO 1 /* read only */
+#define M88K_RW 0 /* read/write */
+
+/*
+ * protection codes (sup field)
+ */
+#define M88K_SUPV 1 /* translation can only be done in supervisor mode */
+#define M88K_USER 0 /* translation can be done supv. or user mode */
+
+/*
+ * descriptor types
+ */
+#define DT_INVALID 0
+#define DT_VALID 1
+
+/*
+ * Number of entries in a page table.
+ */
+#define SDT_ENTRIES (1<<(SDT_BITS))
+#define PDT_ENTRIES (1<<(PDT_BITS))
+
+/*
+ * Size in bytes of a single page table.
+ */
+#define SDT_SIZE (sizeof(sdt_entry_t) * SDT_ENTRIES)
+#define PDT_SIZE (sizeof(pt_entry_t) * PDT_ENTRIES)
+
+/*
+ * Shifts and masks
+ */
+#define SDT_SHIFT (PDT_BITS + PG_BITS)
+#define PDT_SHIFT (PG_BITS)
+
+#define SDT_MASK (((1<<SDT_BITS)-1) << SDT_SHIFT)
+#define PDT_MASK (((1<<PDT_BITS)-1) << PDT_SHIFT)
+
+#define SDT_NEXT(va) ((va + (1<<SDT_SHIFT)) & SDT_MASK)
+#define PDT_NEXT(va) ((va + (1<<PDT_SHIFT)) & (SDT_MASK|PDT_MASK))
+
+#define SDTIDX(va) ((va & SDT_MASK) >> SDT_SHIFT)
+#define PDTIDX(va) ((va & PDT_MASK) >> PDT_SHIFT)
+
+#define SDTENT(map, va) ((sdt_entry_t *)(map->sdt_vaddr + SDTIDX(va)))
+
+/*
+ * Size of a PDT table group.
+ */
+#define LOG2_PDT_SIZE (PDT_BITS + 2)
+#define LOG2_PDT_TABLE_GROUP_SIZE (PAGE_SHIFT - LOG2_PDT_SIZE)
+#define PDT_TABLE_GROUP_SIZE (1 << LOG2_PDT_TABLE_GROUP_SIZE)
+#define PT_FREE(tbl) kmem_free(kernel_map, (vm_offset_t)tbl, PAGE_SIZE)
+
+/*
+ * Va spaces mapped by tables and PDT table group.
+ */
+#define PDT_VA_SPACE (PDT_ENTRIES * M88K_PGBYTES)
+#define PDT_TABLE_GROUP_VA_SPACE (PDT_VA_SPACE * PDT_TABLE_GROUP_SIZE)
+
+/*
+ * Number of sdt entries used to map user and kernel space.
+ */
+#define USER_SDT_ENTRIES SDTIDX(VM_MIN_KERNEL_ADDRESS)
+#define KERNEL_SDT_ENTRIES (SDT_ENTRIES - USER_SDT_ENTRIES)
+
+/*
+ * Macros to check if the descriptor is valid.
+ */
+#define SDT_VALID(sd_ptr) ((sd_ptr)->dtype == DT_VALID)
+#define PDT_VALID(pd_ptr) ((pd_ptr)->dtype == DT_VALID)
+
+/*
+ * Alignment checks for pages (must lie on page boundaries).
+ */
+#define PAGE_ALIGNED(ad) (((vm_offset_t)(ad) & ~M88K_PGMASK) == 0)
+#define CHECK_PAGE_ALIGN(ad,who) \
+ if (!PAGE_ALIGNED(ad)) \
+ printf("%s: addr %x not page aligned.\n", who, ad)
+
+/*
+ * Validate PTE's for all hardware pages in a VM page.
+ * "ptes_per_vm_page" should be set in pmap_bootstrap.
+ *
+ * PARAMETERS:
+ * pt_entry_t *start;
+ * unsigned long template;
+ */
+#define DO_PTES(start, template) \
+{ \
+ int i_; \
+ pt_entry_t *p_ = start; \
+ \
+ for (i_ = ptes_per_vm_page; i_>0; i_--) { \
+ *(int *)p_++ = (unsigned long)(template); \
+ template += M88K_PGBYTES; \
+ /* (unsigned long)(template) for m88k C compiler\
+ '90.7.24 Fuzzy */ \
+ } \
+}
+
+/*
+ * Flags for cmmu_store() <cmmu.s>
+ */
+#define STORE_CMD 0
+#define STORE_UAPR 4
+#define STORE_SAPR 8
+#define STORE_BATCWP 0x400
+
+#define C_CMMU 0
+#define D_CMMU 0x1000
+
+/*
+ * Parameters for ATC(TLB) fulsh
+ */
+
+#define CMMU_SCR 0x004
+
+#define FLUSH_SUP_ALL 0x37
+#define FLUSH_USR_ALL 0x33
+#define FLUSH_SUP_SEG 0x36
+#define FLUSH_USR_SEG 0x32
+#define FLUSH_SUP_PG 0x35
+#define FLUSH_USR_PG 0x31
+
+/*
+ * Cache coontrol bits for pte
+ */
+#define CACHE_DFL 0
+#define CACHE_INH 0x40
+#define CACHE_GLOBAL 0x80
+#define CACHE_WT 0x200
+
+#define CACHE_MASK (~(unsigned)(CACHE_INH | CACHE_GLOBAL | CACHE_WT))
+
+/*
+ * Prototype for invalidate_pte found in "motorola/m88k/m88100/misc.s"
+ */
+unsigned invalidate_pte(pt_entry_t *pointer);
+
+extern vm_offset_t kmapva;
+
+#define kvtopte(va) \
+({ \
+ sdt_entry_t *sdt; \
+ sdt = (sdt_entry_t *)kmapva + SDTIDX(va) + SDT_ENTRIES; \
+ (pte_template_t *)(sdt->table_addr << PDT_SHIFT) + PDTIDX(va); \
+})
+
+
+#define DMA_CACHE_SYNC 0x1
+#define DMA_CACHE_SYNC_INVAL 0x2
+#define DMA_CACHE_INV 0x3
+extern void dma_cachectl(vm_offset_t, int, int);
+
+#endif
+/* endif _MACHINE_MMU_ */
--- /dev/null
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * 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.
+ *
+ * from: Utah $Hdr: machparam.h 1.11 89/08/14$
+ *
+ * @(#)param.h 7.8 (Berkeley) 6/28/91
+ * $Id: param.h,v 1.1.1.1 1997/03/03 19:30:24 rahnds Exp $
+ */
+#ifndef _MACHINE_PARAM_H_
+#define _MACHINE_PARAM_H_
+
+#define MACHINE "m88k"
+#define MACHINE_ARCH "m88k"
+#define MID_MACHINE MID_M88K
+
+/*
+ * Round p (pointer or byte index) up to a correctly-aligned value
+ * for all data types (int, long, ...). The result is u_int and
+ * must be cast to any desired pointer type. ALIGN() is used for
+ * aligning stack, which needs to be on a double word boundary for
+ * 88k.
+ */
+#define ALIGNBYTES (sizeof(int) - 1)
+#define ALIGN(p) (((u_int)(p) + (sizeof(double) - 1)) & ~(sizeof(double) - 1))
+
+#ifndef NBPG
+#define NBPG 4096 /* bytes/page */
+#endif /* NBPG */
+#define PGOFSET (NBPG-1) /* byte offset into page */
+#define PGSHIFT 12 /* LOG2(NBPG) */
+#define NPTEPG (NBPG/(sizeof(u_int)))
+
+#define NBSEG (1<<22) /* bytes/segment */
+#define SEGOFSET (NBSEG-1) /* byte offset into segment */
+#define SEGSHIFT 22 /* LOG2(NBSEG) */
+
+/*
+ * 187 Bug uses the bottom 64k. We allocate ptes to map this into the
+ * kernel. But when we link the kernel, we tell it to start linking
+ * past this 64k. How does this change KERNBASE? XXX
+ */
+
+#define KERNBASE 0x0 /* start of kernel virtual */
+#define BTOPKERNBASE ((u_long)KERNBASE >> PGSHIFT)
+
+#define DEV_BSIZE 512
+#define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */
+#define BLKDEV_IOSIZE 2048 /* Should this be changed? XXX */
+#define MAXPHYS (64 * 1024) /* max raw I/O transfer size */
+
+#define CLSIZE 1
+#define CLSIZELOG2 0
+
+/* NOTE: SSIZE, SINCR and UPAGES must be multiples of CLSIZE */
+#define SSIZE 1 /* initial stack size/NBPG */
+#define SINCR 1 /* increment of stack/NBPG */
+#define USPACE ctob(UPAGES)
+
+#define UPAGES 3 /* pages of u-area */
+#define UADDR 0xEEE00000 /* address of u */
+#define UVPN (UADDR>>PGSHIFT)/* virtual page number of u */
+#define KERNELSTACK (UADDR+UPAGES*NBPG) /* top of kernel stack */
+
+#define PHYSIO_MAP_START 0xEEF00000
+#define PHYSIO_MAP_SIZE 0x00100000
+#define IOMAP_MAP_START 0xEF000000 /* VME etc */
+#define IOMAP_SIZE 0x018F0000
+#define NIOPMAP 32
+
+/*
+ * Constants related to network buffer management.
+ * MCLBYTES must be no larger than CLBYTES (the software page size), and,
+ * on machines that exchange pages of input or output buffers with mbuf
+ * clusters (MAPPED_MBUFS), MCLBYTES must also be an integral multiple
+ * of the hardware page size.
+ */
+#define MSIZE 128 /* size of an mbuf */
+#define MCLBYTES 1024
+#define MCLSHIFT 10
+#define MCLOFSET (MCLBYTES - 1)
+#ifndef NMBCLUSTERS
+#ifdef GATEWAY
+#define NMBCLUSTERS 512 /* map size, max cluster allocation */
+#else
+#define NMBCLUSTERS 256 /* map size, max cluster allocation */
+#endif
+#endif
+
+/*
+ * Size of kernel malloc arena in CLBYTES-sized logical pages
+ */
+#ifndef NKMEMCLUSTERS
+#define NKMEMCLUSTERS (3072*1024/CLBYTES)
+#endif
+
+/* pages ("clicks") to disk blocks */
+#define ctod(x) ((x)<<(PGSHIFT-DEV_BSHIFT))
+#define dtoc(x) ((x)>>(PGSHIFT-DEV_BSHIFT))
+#define dtob(x) ((x)<<DEV_BSHIFT)
+
+/* pages to bytes */
+#define ctob(x) ((x)<<PGSHIFT)
+
+/* bytes to pages */
+#define btoc(x) (((unsigned)(x)+(NBPG-1))>>PGSHIFT)
+
+#define btodb(bytes) /* calculates (bytes / DEV_BSIZE) */ \
+ ((unsigned)(bytes) >> DEV_BSHIFT)
+#define dbtob(db) /* calculates (db * DEV_BSIZE) */ \
+ ((unsigned)(db) << DEV_BSHIFT)
+
+/*
+ * Map a ``block device block'' to a file system block.
+ * This should be device dependent, and should use the bsize
+ * field from the disk label.
+ * For now though just use DEV_BSIZE.
+ */
+#define bdbtofsb(bn) ((bn) / (BLKDEV_IOSIZE/DEV_BSIZE))
+#include <machine/psl.h>
+
+#ifdef _KERNEL
+#define DELAY(x) delay(x)
+#endif
+
+#ifdef _KERNEL
+extern int cputyp;
+extern int cpumod;
+#endif
+/*
+ * Values for the cputyp variable.
+ */
+#define CPU_187 0x187
+#endif /* !_MACHINE_PARAM_H_ */
--- /dev/null
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * Mach Operating System
+ * Copyright (c) 1993-1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * Motorola 88100 pcb definitions
+ *
+ */
+/*
+ */
+#ifndef _PCB_H_
+#define _PCB_H_
+
+/*
+ * Our PCB is the regular PCB+Save area for kernel frame.
+ * Upon entering kernel mode from user land, save the user context
+ * in the saved_state area - this is passed as the exception frame.
+ * On a context switch, only registers that need to be saved by the
+ * C calling convention and few other regs (pc, psr etc) are saved
+ * in the kernel_state part of the PCB. Typically, trap fames are
+ * save on the stack (by low level handlers or by hardware) but,
+ * we just decided to do it in the PCB.
+ */
+
+/*
+ * This must always be an even number of words long so that our stack
+ * will always be properly aligned (88k need 8 byte alignmet). Also,
+ * place r14 on double word boundary so that we can use st.d while
+ * saving the regs.
+ */
+
+struct m88100_pcb {
+ unsigned pcb_pc; /* address to return */
+ unsigned pcb_ipl;
+ unsigned pcb_r14;
+ unsigned pcb_r15;
+ unsigned pcb_r16;
+ unsigned pcb_r17;
+ unsigned pcb_r18;
+ unsigned pcb_r19;
+ unsigned pcb_r20;
+ unsigned pcb_r21;
+ unsigned pcb_r22;
+ unsigned pcb_r23;
+ unsigned pcb_r24;
+ unsigned pcb_r25;
+ unsigned pcb_r26;
+ unsigned pcb_r27;
+ unsigned pcb_r28;
+ unsigned pcb_r29;
+ unsigned pcb_r30;
+ unsigned pcb_sp; /* kernel stack pointer */
+};
+
+
+/*
+ * m88100_saved_state this structure corresponds to the state
+ * of the user registers as saved on the
+ * stack upon kernel entry. This structure
+ * is used internally only. Since this
+ * structure may change from version to
+ * version, it is hidden from the user.
+ */
+
+/* This must always be an even number of words long */
+
+struct m88100_saved_state {
+ unsigned r[32];
+ unsigned fpsr;
+ unsigned fpcr;
+ unsigned epsr;
+ unsigned sxip;
+ unsigned snip;
+ unsigned sfip;
+ unsigned ssbr;
+ unsigned dmt0;
+ unsigned dmd0;
+ unsigned dma0;
+ unsigned dmt1;
+ unsigned dmd1;
+ unsigned dma1;
+ unsigned dmt2;
+ unsigned dmd2;
+ unsigned dma2;
+ unsigned fpecr;
+ unsigned fphs1;
+ unsigned fpls1;
+ unsigned fphs2;
+ unsigned fpls2;
+ unsigned fppt;
+ unsigned fprh;
+ unsigned fprl;
+ unsigned fpit;
+ unsigned vector; /* exception vector number */
+ unsigned mask; /* interrupt mask level */
+ unsigned mode; /* interrupt mode */
+ unsigned scratch1; /* used by locore trap handling code */
+ unsigned ipfsr; /* P BUS status - used in inst fault handling */
+ unsigned dpfsr; /* P BUS status - used in data fault handling */
+ unsigned pad; /* alignment */
+};
+
+#define trapframe m88100_saved_state
+
+struct pcb
+{
+ struct m88100_pcb kernel_state;
+ struct m88100_saved_state user_state;
+ int pcb_onfault; /* for copyin/copyout faults */
+ int pcb_pad; /* pad it XXX */
+};
+
+typedef struct pcb *pcb_t; /* exported */
+
+/*
+ * Location of saved user registers for the proc.
+ */
+#define USER_REGS(p) \
+ (((struct m88100_saved_state *) (&((p)->p_addr->u_pcb.user_state))))
+/*
+ * The pcb is augmented with machine-dependent additional data for
+ * core dumps. Note that the trapframe here is a copy of the one
+ * from the top of the kernel stack (included here so that the kernel
+ * stack itself need not be dumped).
+ */
+struct md_coredump {
+ struct trapframe md_tf;
+};
+
+#endif _PCB_H_
--- /dev/null
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 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.
+ */
+
+/*
+ * MVME1x7/16x PCC2 chip: sort of a confused mish-mash of the MC in the 162
+ * and the PCC in the 147
+ */
+struct pcctworeg {
+ volatile u_char pcc2_chipid;
+ volatile u_char pcc2_chiprev;
+ volatile u_char pcc2_genctl;
+ volatile u_char pcc2_vecbase; /* irq vector base */
+ volatile u_long pcc2_t1cmp; /* timer1 compare */
+ volatile u_long pcc2_t1count; /* timer1 count */
+ volatile u_long pcc2_t2cmp; /* timer2 compare */
+ volatile u_long pcc2_t2count; /* timer2 count */
+ volatile u_char pcc2_pscalecnt; /* timer prescaler counter */
+ volatile u_char pcc2_pscaleadj; /* timer prescaler adjust */
+ volatile u_char pcc2_t2ctl; /* timer2 ctrl reg */
+ volatile u_char pcc2_t1ctl; /* timer1 ctrl reg */
+ volatile u_char pcc2_gpioirq; /* gpio irq */
+ volatile u_char pcc2_gpio; /* gpio i/o */
+ volatile u_char pcc2_t2irq;
+ volatile u_char pcc2_t1irq;
+ volatile u_char pcc2_sccerr;
+ volatile u_char pcc2_sccirq;
+ volatile u_char pcc2_scctx;
+ volatile u_char pcc2_sccrx;
+ volatile u_char :8;
+ volatile u_char :8;
+ volatile u_char :8;
+ volatile u_char pcc2_sccmoiack;
+ volatile u_char :8;
+ volatile u_char pcc2_scctxiack;
+ volatile u_char :8;
+ volatile u_char pcc2_sccrxiack;
+ volatile u_char pcc2_ieerr;
+ volatile u_char :8;
+ volatile u_char pcc2_iectl;
+ volatile u_char pcc2_ieirq;
+ volatile u_char pcc2_ncrerr;
+ volatile u_char :8;
+ volatile u_char :8;
+ volatile u_char pcc2_ncrirq;
+ volatile u_char pcc2_prtairq;
+ volatile u_char pcc2_prtfirq;
+ volatile u_char pcc2_prtsirq;
+ volatile u_char pcc2_prtpirq;
+ volatile u_char pcc2_prtbirq;
+ volatile u_char :8;
+ volatile u_char pcc2_prtstat;
+ volatile u_char pcc2_prtctl;
+ volatile u_short pcc2_speed; /* DO NOT USE */
+ volatile u_short pcc2_prtdat;
+ volatile u_short :16;
+ volatile u_char pcc2_ipl;
+ volatile u_char pcc2_mask;
+};
+#define PCC2_PCC2CHIP_ADDR 0xFFF42000
+#define PCC2_PCC2CHIP_OFF 0x42000
+#define PCC2_CHIPID 0x20
+
+/*
+ * points to system's PCCTWO. This is not active until the pcctwo0
+ * device has been attached. After that, it gives the virtual address
+ * at which the PCCTWO can be accessed.
+ */
+extern struct pcctworeg *sys_pcc2;
+
+/*
+ * We lock off our interrupt vector at 0x50.
+ */
+#define PCC2_VECBASE 0x50
+#define PCC2_NVEC 12
+
+/*
+ * Vectors we use
+ */
+#define PCC2V_NCR 0x05
+#define PCC2V_IE_ERR 0x06
+#define PCC2V_IE 0x07
+#define PCC2V_TIMER2 0x08
+#define PCC2V_TIMER1 0x09
+#define PCC2V_GPIO 0x0A
+
+#define PCC2_TCTL_CEN 0x01
+#define PCC2_TCTL_COC 0x02
+#define PCC2_TCTL_COVF 0x04
+#define PCC2_TCTL_OVF 0xf0
+
+#define PCC2_GPIO_PLTY 0x80
+#define PCC2_GPIO_EL 0x40
+
+#define PCC2_GPIOCR_OE 0x2
+#define PCC2_GPIOCR_O 0x1
+
+#define PCC2_SCC_AVEC 0x08
+#define PCC2_SCCRX_INHIBIT (0 << 6)
+#define PCC2_SCCRX_SNOOP (1 << 6)
+#define PCC2_SCCRX_INVAL (2 << 6)
+#define PCC2_SCCRX_RESV (3 << 6)
+
+#define pcc2_timer_us2lim(us) (us) /* timer increments in "us" */
+
+#define PCC2_IRQ_IPL 0x07
+#define PCC2_IRQ_ICLR 0x08
+#define PCC2_IRQ_IEN 0x10
+#define PCC2_IRQ_INT 0x20
+
+#define PCC2_GENCTL_FAST 0x01
+#define PCC2_GENCTL_IEN 0x02
+#define PCC2_GENCTL_C040 0x03
+
+#define PCC2_SC_INHIBIT (0 << 6)
+#define PCC2_SC_SNOOP (1 << 6)
+#define PCC2_SC_INVAL (2 << 6)
+#define PCC2_SC_RESV (3 << 6)
--- /dev/null
+/*
+ * Mach Operating System
+ * Copyright (c) 1991 Carnegie Mellon University
+ * Copyright (c) 1991 OMRON Corporation
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ */
+#ifndef _MACHINE_PMAP_H_
+#define _MACHINE_PMAP_H_
+#define OMRON_PMAP
+
+#include <machine/psl.h> /* get standard goodies */
+#include <vm/vm_param.h>
+#include <vm/vm_prot.h> /* vm_prot_t */
+#include <machine/mmu.h> /* batc_template_t, BATC_MAX, etc.*/
+#include <machine/pcb.h> /* pcb_t, etc.*/
+
+typedef struct sdt_entry *sdt_ptr_t;
+
+/*
+ * PMAP structure
+ */
+typedef struct pmap *pmap_t;
+
+struct pmap {
+ sdt_ptr_t sdt_paddr; /* physical pointer to sdt */
+ sdt_ptr_t sdt_vaddr; /* virtual pointer to sdt */
+ int ref_count; /* reference count */
+
+ struct pmap_statistics stats; /* pmap statistics */
+
+#ifdef DEBUG
+ pmap_t next;
+ pmap_t prev;
+#endif
+
+ /* for OMRON_PMAP */
+ batc_template_t i_batc[BATC_MAX]; /* instruction BATCs */
+ batc_template_t d_batc[BATC_MAX]; /* data BATCs */
+ /* end OMRON_PMAP */
+
+};
+
+#include <vm/vm.h>
+
+#define PMAP_NULL ((pmap_t) 0)
+
+extern pmap_t kernel_pmap;
+
+#define PMAP_ACTIVATE(pmap, th, my_cpu) _pmap_activate(pmap, th, my_cpu)
+#define PMAP_DEACTIVATE(pmap, th, my_cpu) _pmap_deactivate(pmap, th, my_cpu)
+
+#define PMAP_CONTEXT(pmap, thread)
+
+#define pmap_resident_count(pmap) ((pmap)->stats.resident_count)
+
+/* Used in builtin/device_pager.c */
+#define pmap_phys_address(frame) ((vm_offset_t) (M88K_PTOB(frame)))
+
+/* Used in kern/mach_timedev.c */
+#define pmap_phys_to_frame(phys) ((int) (M88K_BTOP(phys)))
+
+/*
+ * Since Our PCB has no infomation about the mapping,
+ * we have nothing to do in PMAP_PCB_INITIALIZE.
+ * XXX
+ */
+/* Used in machine/pcb.c */
+#define PMAP_PCB_INITIALIZE(x)
+
+/*
+ * Modes used when calling pmap_cache_fulsh().
+ */
+#define FLUSH_CACHE 0
+#define FLUSH_CODE_CACHE 1
+#define FLUSH_DATA_CACHE 2
+#define FLUSH_LOCAL_CACHE 3
+#define FLUSH_LOCAL_CODE_CACHE 4
+#define FLUSH_LOCAL_DATA_CACHE 5
+
+/**************************************************************************/
+/*** Prototypes for public functions defined in pmap.c ********************/
+/**************************************************************************/
+
+void _pmap_activate(pmap_t pmap, pcb_t, int my_cpu);
+void _pmap_deactivate(pmap_t pmap, pcb_t, int my_cpu);
+void pmap_activate(pmap_t my_pmap, pcb_t);
+void pmap_deactivate(pmap_t pmap, pcb_t);
+int pmap_check_transaction(pmap_t pmap, vm_offset_t va, vm_prot_t type);
+
+vm_offset_t pmap_map_batc(
+ vm_offset_t virt,
+ vm_offset_t start,
+ vm_offset_t end,
+ vm_prot_t prot,
+ unsigned cmode);
+
+#ifdef JUNK
+int pmap_attribute(
+ pmap_t pmap,
+ vm_offset_t address,
+ vm_size_t size,
+ vm_machine_attribute_t attribute,
+ vm_machine_attribute_val_t* value); /* IN/OUT */
+#endif /* JUNK */
+
+void pmap_bootstrap(
+ vm_offset_t load_start, /* IN */
+ vm_offset_t *phys_start, /* IN/OUT */
+ vm_offset_t *phys_end, /* IN */
+ vm_offset_t *virt_start, /* OUT */
+ vm_offset_t *virt_end); /* OUT */
+
+pt_entry_t *pmap_pte(pmap_t map, vm_offset_t virt);
+void pmap_cache_ctrl(pmap_t pmap, vm_offset_t s, vm_offset_t e, unsigned mode);
+void pmap_zero_page(vm_offset_t phys);
+void pmap_remove_all(vm_offset_t phys);
+vm_offset_t pmap_extract_unlocked(pmap_t pmap, vm_offset_t va);
+pmap_t pmap_kernel(void);
+void copy_to_phys(vm_offset_t srcva, vm_offset_t dstpa, int bytecount);
+void copy_from_phys(vm_offset_t srcpa, vm_offset_t dstva, int bytecount);
+void pmap_redzone(pmap_t pmap, vm_offset_t va);
+boolean_t pmap_verify_free(vm_offset_t phys);
+boolean_t pmap_valid_page(vm_offset_t p);
+void icache_flush(vm_offset_t pa);
+void pmap_dcache_flush(pmap_t pmap, vm_offset_t va);
+void pmap_cache_flush(pmap_t pmap, vm_offset_t virt, int bytes, int mode);
+void pmap_print (pmap_t pmap);
+void pmap_print_trace (pmap_t pmap, vm_offset_t va, boolean_t long_format);
+
+#if 0
+#ifdef OMRON_PMAP
+ void pmap_set_batc(
+ pmap_t pmap,
+ boolean_t data,
+ int i,
+ vm_offset_t va,
+ vm_offset_t pa,
+ boolean_t super,
+ boolean_t wt,
+ boolean_t global,
+ boolean_t ci,
+ boolean_t wp,
+ boolean_t valid);
+
+ void use_batc(
+ task_t task,
+ boolean_t data, /* for data-cmmu ? */
+ int i, /* batc number */
+ vm_offset_t va, /* virtual address */
+ vm_offset_t pa, /* physical address */
+ boolean_t s, /* for super-mode ? */
+ boolean_t wt, /* is writethrough */
+ boolean_t g, /* is global ? */
+ boolean_t ci, /* is cache inhibited ? */
+ boolean_t wp, /* is write-protected ? */
+ boolean_t v); /* is valid ? */
+#endif
+#endif /* 0 */
+
+#endif /* endif _MACHINE_PMAP_H_ */
--- /dev/null
+/*
+ * Mach Operating System
+ * Copyright (c) 1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+/*
+ * HISTORY
+ */
+
+
+/* an entry is considered invalid if pm_size = 0 */
+/* end of list is indicated by pm_size 0xffffffff */
+
+typedef struct {
+ vm_offset_t phys_start; /* in bytes */
+ vm_offset_t virt_start; /* in bytes */
+ unsigned int size; /* in bytes */
+ unsigned int prot; /* vm_prot_read, vm_prot_write */
+ unsigned int cacheability; /* none, writeback, normal */
+} pmap_table_entry;
+
+typedef pmap_table_entry *pmap_table_t;
+
--- /dev/null
+/*
+ * 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.
+ *
+ * @(#)proc.h 8.1 (Berkeley) 6/11/93
+ *
+ * from: Header: proc.h,v 1.6 92/11/26 02:04:41 torek Exp (LBL)
+ * $Id: proc.h,v 1.1.1.1 1997/03/03 19:30:23 rahnds Exp $
+ */
+
+#include <machine/pcb.h>
+#include <machine/mmu.h>
+
+/*
+ * Machine-dependent part of the proc structure for VME1X7.
+ */
+struct mdproc {
+ struct trapframe *md_tf; /* trap/syscall registers */
+ struct fpstate *md_fpstate; /* fpu state, if any; always resident */
+ int md_upte[UPAGES]; /* ptes for mapping u page */
+};
--- /dev/null
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * Copyright (c) 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.
+ *
+ * from: @(#)profile.h 8.1 (Berkeley) 6/11/93
+ * $Id: profile.h,v 1.1.1.1 1997/03/03 19:30:26 rahnds Exp $
+ */
+
+#define _MCOUNT_DECL static inline void _mcount
+
+#define MCOUNT \
+extern void mcount() asm("mcount"); \
+void \
+mcount() \
+{ \
+ int selfret; \
+ register int callerret; \
+ /* \
+ * find the return address for mcount, \
+ * and the return address for mcount's caller. \
+ * \
+ * selfret = ret pushed by mcount call \
+ */ \
+ asm volatile("st r1,%0" : "=m" (selfret)); \
+ /* \
+ * callerret = ret pushed by call into self. \
+ */ \
+ /* \
+ * This may not be right. It all depends on where the \
+ * caller stores the return address. XXX \
+ */ \
+ asm volatile("addu r10,r31,48"); \
+ asm volatile("ld %0,r10,36" : "=r" (callerret)); \
+ _mcount(callerret, selfret); \
+}
+
+#ifdef KERNEL
+/*
+ * Note that we assume splhigh() and splx() cannot call mcount()
+ * recursively.
+ */
+#define MCOUNT_ENTER s = splhigh()
+#define MCOUNT_EXIT splx(s)
+#endif /* KERNEL */
--- /dev/null
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define MVMEPROM_INCHR 0x00
+#define MVMEPROM_INSTAT 0x01
+#define MVMEPROM_INLN 0x02
+#define MVMEPROM_READSTR 0x03
+#define MVMEPROM_READLN 0x04
+#define MVMEPROM_OUTCHR 0x20
+#define MVMEPROM_OUTSTR 0x21
+#define MVMEPROM_DSKRD 0x10
+#define MVMEPROM_DSKWR 0x11
+#define MVMEPROM_DSKCFIG 0x12
+#define MVMEPROM_DSKFMT 0x14
+#define MVMEPROM_DSKCTRL 0x15
+#define MVMEPROM_NETCTRL 0x1d
+#define MVMEPROM_OUTSTRCRLF 0x22
+#define MVMEPROM_WRITE 0x23
+#define MVMEPROM_WRITELN 0x24
+#define MVMEPROM_DELAY 0x43
+#define MVMEPROM_RTC_RD 0x53
+#define MVMEPROM_EXIT 0x63
+#define MVMEPROM_GETBRDID 0x70
+#define MVMEPROM_ENVIRON 0x71
+
+#define NETCTRLCMD_GETETHER 1
+
+#define ENVIRONCMD_WRITE 1
+#define ENVIRONCMD_READ 2
+#define ENVIRONTYPE_EOL 0
+#define ENVIRONTYPE_START 1
+#define ENVIRONTYPE_DISKBOOT 2
+#define ENVIRONTYPE_ROMBOOT 3
+#define ENVIRONTYPE_NETBOOT 4
+#define ENVIRONTYPE_MEMSIZE 5
+
+#ifndef LOCORE
+struct prom_netctrl {
+ u_char dev;
+ u_char ctrl;
+ u_short status;
+ u_long cmd;
+ u_long addr;
+ u_long len;
+ u_long flags;
+};
+
+struct prom_environ_hdr {
+ u_char type;
+ u_char len;
+};
+
+struct mvmeprom_brdid {
+ u_long eye_catcher;
+ u_char rev;
+ u_char month;
+ u_char day;
+ u_char year;
+ u_short size;
+ u_short rsv1;
+ u_short model;
+ u_short suffix;
+ u_short options;
+ u_char family;
+ u_char cpu;
+ u_short ctrlun;
+ u_short devlun;
+ u_short devtype;
+ u_short devnum;
+ u_long bug;
+
+ /*
+ * XXX: I have seen no documentation for these!
+ *
+ * The following (appears to) exist only on the MVME162 and
+ * upwards. We should figure out what the other fields are.
+ */
+ u_char xx1[16];
+ u_char xx2[4];
+ u_char longname[12];
+ u_char xx3[16];
+ u_char speed[4];
+ u_char xx4[12];
+};
+
+struct mvmeprom_time {
+ u_char year_BCD;
+ u_char month_BCD;
+ u_char day_BCD;
+ u_char wday_BCD;
+ u_char hour_BCD;
+ u_char min_BCD;
+ u_char sec_BCD;
+ u_char cal_BCD;
+};
+
+struct mvmeprom_dskio {
+ u_char ctrl_lun;
+ u_char dev_lun;
+ u_short status;
+ void *pbuffer;
+ u_long blk_num;
+ u_short blk_cnt;
+ u_char flag;
+#define BUG_FILE_MARK 0x80
+#define IGNORE_FILENUM 0x02
+#define END_OF_FILE 0x01
+ u_char addr_mod;
+};
+#define MVMEPROM_BLOCK_SIZE 256
+
+struct mvmeprom_args {
+ u_int dev_lun;
+ u_int ctrl_lun;
+ u_int flags;
+ u_int ctrl_addr;
+ u_int entry;
+ u_int conf_blk;
+ char *arg_start;
+ char *arg_end;
+};
+
+#endif
+
+#define MVMEPROM_CALL(x) \
+ asm volatile ( __CONCAT("or r9,r0,",__STRING(x)) ); \
+ asm volatile ("tb0 0,r0,496");
--- /dev/null
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * 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 Nivas Madhur.
+ * 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.
+ *
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991 Carnegie Mellon University
+ * Copyright (c) 1991 OMRON Corporation
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ */
+#ifndef __M88K_M88100_PSL_H__
+#define __M88K_M88100_PSL_H__
+
+/* needs major cleanup - XXX nivas */
+
+#if 0
+spl0 is a function by itself. I really am serious about the clean up
+above...
+#define spl0() spln(0)
+#endif /* 0 */
+#define spl1() setipl(1)
+#define spl2() setipl(2)
+#define spl3() setipl(3)
+#define spl4() setipl(4)
+#define spl5() setipl(5)
+#define spl6() setipl(6)
+#define spl7() setipl(7)
+
+/*
+ * IPL levels.
+ * We use 6 as IPL_HIGH so that abort can be programmed at 7 so that
+ * it is always possible to break into the system unless interrupts
+ * are disabled.
+ */
+
+#define IPL_NONE 0
+#define IPL_SOFTCLOCK 1
+#define IPL_SOFTNET 1
+#define IPL_BIO 2
+#define IPL_NET 3
+#define IPL_TTY 3
+#define IPL_CLOCK 5
+#define IPL_STATCLOCK 5
+#define IPL_IMP 6
+#define IPL_VM 6
+#define IPL_HIGH 6
+#define IPL_SCHED 6
+#define IPL_NMI 7
+#define IPL_ABORT 7
+
+#define splnone spl0
+#define splsoftclock() setipl(IPL_SOFTCLOCK)
+#define splsoftnet() setipl(IPL_SOFTNET)
+#define splbio() setipl(IPL_BIO)
+#define splnet() setipl(IPL_NET)
+#define spltty() setipl(IPL_TTY)
+#define splclock() setipl(IPL_CLOCK)
+#define splstatclock() setipl(IPL_STATCLOCK)
+#define splimp() setipl(IPL_IMP)
+#define splvm() setipl(IPL_VM)
+#define splhigh() setipl(IPL_HIGH)
+#define splsched() setipl(IPL_SCHED)
+
+#define splx(x) ((x) ? setipl((x)) : spl0())
+
+/*
+ * 88100 control registers
+ */
+
+/*
+ * processor identification register (PID)
+ */
+#define PID_ARN 0x0000FF00U /* architectural revision number */
+#define PID_VN 0x000000FEU /* version number */
+#define PID_MC 0x00000001U /* master/checker */
+
+/*
+ * processor status register
+ */
+#define PSR_MODE 0x80000000U /* supervisor/user mode */
+#define PSR_BO 0x40000000U /* byte-ordering 0:big 1:little */
+#define PSR_SER 0x20000000U /* serial mode */
+#define PSR_C 0x10000000U /* carry */
+#define PSR_SFD 0x000003F0U /* SFU disable */
+#define PSR_SFD1 0x00000008U /* SFU1 (FPU) disable */
+#define PSR_MXM 0x00000004U /* misaligned access enable */
+#define PSR_IND 0x00000002U /* interrupt disable */
+#define PSR_SFRZ 0x00000001U /* shadow freeze */
+
+/*
+ * This is used in ext_int() and hard_clock().
+ */
+#define PSR_IPL 0x00001000 /* for basepri */
+#define PSR_IPL_LOG 12 /* = log2(PSR_IPL) */
+
+#define PSR_MODE_LOG 31 /* = log2(PSR_MODE) */
+#define PSR_BO_LOG 30 /* = log2(PSR_BO) */
+#define PSR_SER_LOG 29 /* = log2(PSR_SER) */
+#define PSR_SFD1_LOG 3 /* = log2(PSR_SFD1) */
+#define PSR_MXM_LOG 2 /* = log2(PSR_MXM) */
+#define PSR_IND_LOG 1 /* = log2(PSR_IND) */
+#define PSR_SFRZ_LOG 0 /* = log2(PSR_SFRZ) */
+
+#define PSR_SUPERVISOR (PSR_MODE | PSR_SFD)
+#define PSR_USER (PSR_SFD)
+#define PSR_SET_BY_USER (PSR_BO | PSR_SER | PSR_C | PSR_MXM)
+
+#ifndef ASSEMBLER
+struct psr {
+ unsigned
+ psr_mode: 1,
+ psr_bo : 1,
+ psr_ser : 1,
+ psr_c : 1,
+ :18,
+ psr_sfd : 6,
+ psr_sfd1: 1,
+ psr_mxm : 1,
+ psr_ind : 1,
+ psr_sfrz: 1;
+};
+#endif
+
+#define FIP_V 0x00000002U /* valid */
+#define FIP_E 0x00000001U /* exception */
+#define FIP_ADDR 0xFFFFFFFCU /* address mask */
+#define NIP_V 0x00000002U /* valid */
+#define NIP_E 0x00000001U /* exception */
+#define NIP_ADDR 0xFFFFFFFCU /* address mask */
+#define XIP_V 0x00000002U /* valid */
+#define XIP_E 0x00000001U /* exception */
+#define XIP_ADDR 0xFFFFFFFCU /* address mask */
+
+#endif /* __M88K_M88100_PSL_H__ */
+
--- /dev/null
+/*
+ * 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.
+ *
+ * @(#)ptrace.h 8.1 (Berkeley) 6/11/93
+ *
+ * from: Header: ptrace.h,v 1.6 92/11/26 02:04:43 torek Exp (LBL)
+ * $Id: ptrace.h,v 1.1.1.1 1997/03/03 19:30:26 rahnds Exp $
+ */
+
+/*
+ * m88k-dependent ptrace definitions.
+ */
+#define PT_GETREGS (PT_FIRSTMACH + 0)
+#define PT_SETREGS (PT_FIRSTMACH + 1)
+#define PT_GETFPREGS (PT_FIRSTMACH + 2)
+#define PT_SETFPREGS (PT_FIRSTMACH + 3)
--- /dev/null
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * 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 Nivas Madhur.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <machine/pcb.h>
+
+struct reg {
+ unsigned r_r[32];
+ unsigned r_fpsr;
+ unsigned r_fpcr;
+ unsigned r_epsr;
+ unsigned r_sxip;
+ unsigned r_snip;
+ unsigned r_sfip;
+ unsigned r_ssbr;
+ unsigned r_dmt0;
+ unsigned r_dmd0;
+ unsigned r_dma0;
+ unsigned r_dmt1;
+ unsigned r_dmd1;
+ unsigned r_dma1;
+ unsigned r_dmt2;
+ unsigned r_dmd2;
+ unsigned r_dma2;
+ unsigned r_fpecr;
+ unsigned r_fphs1;
+ unsigned r_fpls1;
+ unsigned r_fphs2;
+ unsigned r_fpls2;
+ unsigned r_fppt;
+ unsigned r_fprh;
+ unsigned r_fprl;
+ unsigned r_fpit;
+ unsigned r_vector; /* exception vector number */
+ unsigned r_mask; /* interrupt mask level */
+ unsigned r_mode; /* interrupt mode */
+ unsigned r_scratch1; /* used by locore trap handling code */
+ unsigned r_pad; /* to make an even length */
+} ;
+
+struct fpreg {
+ unsigned fp_fpecr;
+ unsigned fp_fphs1;
+ unsigned fp_fpls1;
+ unsigned fp_fphs2;
+ unsigned fp_fpls2;
+ unsigned fp_fppt;
+ unsigned fp_fprh;
+ unsigned fp_fprl;
+ unsigned fp_fpit;
+};
--- /dev/null
+/* $NetBSD: setjmp.h,v 1.1 1994/12/20 10:37:10 cgd Exp $ */
+
+/*
+ * machine/setjmp.h: machine dependent setjmp-related information.
+ */
+
+#define _JBLEN 22 /* size, in longs, of a jmp_buf */
--- /dev/null
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * 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 Nivas Madhur.
+ * 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.
+ *
+ */
+typedef int sig_atomic_t;
+
+/*
+ * Information pushed on stack when a signal is delivered.
+ * This is used by the kernel to restore state following
+ * execution of the signal handler. It is also made available
+ * to the handler to allow it to restore state properly if
+ * a non-standard exit is performed.
+ *
+ * All machines must have an sc_onstack and sc_mask.
+ */
+struct sigcontext {
+ int sc_onstack; /* sigstack state to restore */
+ int sc_mask; /* signal mask to restore */
+ /* begin machine dependent portion */
+ int sc_regs[32];
+#define sc_sp sc_regs[31]
+ int sc_xip;
+ int sc_nip;
+ int sc_fip;
+ int sc_ps;
+ int sc_fpsr;
+ int sc_fpcr;
+ int sc_ssbr;
+ int sc_dmt0;
+ int sc_dmd0;
+ int sc_dma0;
+ int sc_dmt1;
+ int sc_dmd1;
+ int sc_dma1;
+ int sc_dmt2;
+ int sc_dmd2;
+ int sc_dma2;
+ int sc_fpecr;
+ int sc_fphs1;
+ int sc_fpls1;
+ int sc_fphs2;
+ int sc_fpls2;
+ int sc_fppt;
+ int sc_fprh;
+ int sc_fprl;
+ int sc_fpit;
+ int sc_xxxx; /* padd to double word boundary */
+};
--- /dev/null
+/* This file has local changes by MOTOROLA
+Thu Sep 9 09:06:29 CDT 1993 Dale Rahn (drahn@pacific)
+ * (gstdarg.h, gvarargs.h) C-Front requires all builtins to
+ be defined. This is to insert these definitions if
+ __cplusplus is defined but not using the G++ compiler.
+ */
+/* stdarg.h for GNU.
+ Note that the type used in va_arg is supposed to match the
+ actual type **after default promotions**.
+ Thus, va_arg (..., short) is not valid. */
+
+#ifndef _STDARG_H
+#ifndef _ANSI_STDARG_H_
+#ifndef __need___va_list
+#define _STDARG_H
+#define _ANSI_STDARG_H_
+#endif /* not __need___va_list */
+#undef __need___va_list
+
+#ifndef __GNUC__
+/* Use the system's macros with the system's compiler.
+ This is relevant only when building GCC with some other compiler. */
+#include <stdarg.h>
+#else
+#ifdef __clipper__
+#include <va-clipper.h>
+#else
+#ifdef __m88k__
+#include <machine/va-m88k.h>
+#else
+#ifdef __i860__
+#include <va-i860.h>
+#else
+#ifdef __hppa__
+#include <va-pa.h>
+#else
+#ifdef __mips__
+#include <va-mips.h>
+#else
+#ifdef __sparc__
+#include <va-sparc.h>
+#else
+#ifdef __i960__
+#include <va-i960.h>
+#else
+#ifdef __alpha__
+#include <va-alpha.h>
+#else
+
+/* Define __gnuc_va_list. */
+
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+#if defined(__svr4__) || defined(_AIX) || defined(_M_UNIX)
+typedef char *__gnuc_va_list;
+#else
+typedef void *__gnuc_va_list;
+#endif
+#endif
+
+/* Define the standard macros for the user,
+ if this invocation was from the user program. */
+#ifdef _STDARG_H
+
+/* Amount of space required in an argument list for an arg of type TYPE.
+ TYPE may alternatively be an expression whose type is used. */
+
+#define __va_rounded_size(TYPE) \
+ (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
+
+#define va_start(AP, LASTARG) \
+ (AP = ((__gnuc_va_list) __builtin_next_arg ()))
+
+#undef va_end
+void va_end (__gnuc_va_list); /* Defined in libgcc.a */
+#define va_end(AP)
+
+/* We cast to void * and then to TYPE * because this avoids
+ a warning about increasing the alignment requirement. */
+
+#if defined (__arm__) || defined (__i386__) || defined (__ns32000__) || defined (__vax__)
+/* This is for little-endian machines; small args are padded upward. */
+#define va_arg(AP, TYPE) \
+ (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \
+ *((TYPE *) (void *) ((char *) (AP) - __va_rounded_size (TYPE))))
+#else /* big-endian */
+/* This is for big-endian machines; small args are padded downward. */
+#define va_arg(AP, TYPE) \
+ (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \
+ *((TYPE *) (void *) ((char *) (AP) - ((sizeof (TYPE) < 4 \
+ ? sizeof (TYPE) \
+ : __va_rounded_size (TYPE))))))
+#endif /* big-endian */
+#endif /* _STDARG_H */
+
+#endif /* not alpha */
+#endif /* not i960 */
+#endif /* not sparc */
+#endif /* not mips */
+#endif /* not hppa */
+#endif /* not i860 */
+#endif /* not m88k */
+#endif /* not clipper */
+
+#ifdef _STDARG_H
+/* Define va_list, if desired, from __gnuc_va_list. */
+/* We deliberately do not define va_list when called from
+ stdio.h, because ANSI C says that stdio.h is not supposed to define
+ va_list. stdio.h needs to have access to that data type,
+ but must not use that name. It should use the name __gnuc_va_list,
+ which is safe because it is reserved for the implementation. */
+
+#ifdef _HIDDEN_VA_LIST /* On OSF1, this means varargs.h is "half-loaded". */
+#undef _VA_LIST
+#endif
+
+#ifdef _BSD_VA_LIST_
+#undef _BSD_VA_LIST_
+#define _BSD_VA_LIST_ __gnuc_va_list
+#endif /* _BSD_VA_LIST_ */
+
+#ifdef __svr4__
+/* SVR4.2 uses _VA_LIST for an internal alias for va_list,
+ so we must avoid testing it and setting it here.
+ SVR4 uses _VA_LIST as a flag in stdarg.h, but we should
+ have no conflict with that. */
+#ifndef _VA_LIST_
+#define _VA_LIST_
+#ifdef __i860__
+#ifndef _VA_LIST
+#define _VA_LIST va_list
+#endif
+#endif /* __i860__ */
+typedef __gnuc_va_list va_list;
+#endif /* _VA_LIST_ */
+#else /* not __svr4__ */
+
+/* The macro _VA_LIST_ is the same thing used by this file in Ultrix.
+ But on BSD NET2 we must not test or define or undef it.
+ (Note that the comments in NET 2's ansi.h
+ are incorrect for _VA_LIST_--see stdio.h!) */
+#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____)
+/* The macro _VA_LIST is used in SCO Unix 3.2. */
+#ifndef _VA_LIST
+/* The macro _VA_LIST_T_H is used in the Bull dpx2 */
+#ifndef _VA_LIST_T_H
+#define _VA_LIST_T_H
+#if !(defined (__BSD_NET2__) || defined (____386BSD____))
+#define _VA_LIST_
+#endif
+#define _VA_LIST
+typedef __gnuc_va_list va_list;
+#endif /* not _VA_LIST_T_H */
+#endif /* not _VA_LIST */
+#endif /* not _VA_LIST_ */
+
+#endif /* not __svr4__ */
+
+#if defined(__cplusplus) && !defined(__GNUG__)
+
+/* This is added to work with AT&T C++. */
+extern "C" {
+ char *__builtin_next_arg(void);
+ __gnuc_va_list *__builtin_saveregs(void);
+ void *__builtin_saveregs2(int);
+ int *__builtin_argptr(void);
+ int __builtin_argsize(void);
+ int __builtin_classify_type(...);
+ int __alignof__(...);
+}
+#endif
+
+#endif /* _STDARG_H */
+
+#endif /* __GNUC__ */
+#endif /* not _ANSI_STDARG_H_ */
+#endif /* not _STDARG_H */
--- /dev/null
+/*
+ * Mach Operating System
+ * Copyright (c) 1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * Trap codes
+ */
+
+#ifndef _M88K_TRAP_H
+#define _M88K_TRAP_H 1
+
+/*
+ * Trap type values
+ */
+
+#define T_RESADFLT 0 /* reserved addressing fault */
+#define T_PRIVINFLT 1 /* privileged instruction fault */
+#define T_RESOPFLT 2 /* reserved operand fault */
+
+/* End of known constants */
+
+#define T_INSTFLT 3 /* instruction access exception */
+#define T_DATAFLT 4 /* data access exception */
+#define T_MISALGNFLT 5 /* misaligned access exception */
+#define T_ILLFLT 6 /* unimplemented opcode exception */
+#define T_BNDFLT 7 /* bounds check violation exception */
+#define T_ZERODIV 8 /* illegal divide exception */
+#define T_OVFFLT 9 /* integer overflow exception */
+#define T_ERRORFLT 10 /* error exception */
+#define T_FPEPFLT 11 /* floating point precise exception */
+#define T_FPEIFLT 12 /* floating point imprecise exception */
+#define T_ASTFLT 13 /* software trap */
+#if DDB
+#define T_KDB_ENTRY 14 /* force entry to kernel debugger */
+#define T_KDB_BREAK 15 /* break point hit */
+#define T_KDB_TRACE 16 /* trace */
+#endif /* DDB */
+#define T_UNKNOWNFLT 17 /* unknown exception */
+#define T_SIGTRAP 18 /* generate SIGTRAP */
+#define T_SIGSYS 19 /* generate SIGSYS */
+#define T_STEPBPT 20 /* special breakpoint for single step */
+#define T_USERBPT 21 /* user set breakpoint (for debugger) */
+#define T_SYSCALL 22 /* Syscall */
+#define T_USER 23 /* user mode fault */
+#if DDB
+#define T_KDB_WATCH 24 /* watchpoint hit */
+#endif /* DDB */
+
+#endif _M88K_TRAP_H
+
--- /dev/null
+/* $NetBSD: types.h,v 1.7 1995/07/05 17:46:11 pk 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.
+ *
+ * @(#)types.h 8.1 (Berkeley) 6/11/93
+ */
+
+#ifndef _MACHTYPES_H_
+#define _MACHTYPES_H_
+
+#include <sys/cdefs.h>
+
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
+typedef struct _physadr {
+ short r[1];
+} *physadr;
+
+typedef struct label_t {
+ int val[2];
+} label_t;
+#endif
+
+typedef unsigned long vm_offset_t;
+typedef unsigned long vm_size_t;
+
+/*
+ * Basic integral types. Omit the typedef if
+ * not possible for a machine/compiler combination.
+ */
+#define __BIT_TYPES_DEFINED__
+typedef __signed char int8_t;
+typedef unsigned char u_int8_t;
+typedef short int16_t;
+typedef unsigned short u_int16_t;
+typedef int int32_t;
+typedef unsigned int u_int32_t;
+typedef long long int64_t;
+typedef unsigned long long u_int64_t;
+
+typedef int32_t register_t;
+
+#define __BDEVSW_DUMP_OLD_TYPE
+
+#endif /* _MACHTYPES_H_ */
--- /dev/null
+/* This file has local changes by MOTOROLA
+Thu Sep 9 09:06:29 CDT 1993 Dale Rahn (drahn@pacific)
+ * Due to C-Front's usage of __alignof__ builtin the
+ usage of it must be changed to have an object of that type
+ as the argument not just the type.
+ */
+/* GNU C varargs support for the Motorola 88100 */
+
+/* Define __gnuc_va_list. */
+
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+
+typedef struct
+{
+ int __va_arg; /* argument number */
+ int *__va_stk; /* start of args passed on stack */
+ int *__va_reg; /* start of args passed in regs */
+} __gnuc_va_list;
+#endif /* not __GNUC_VA_LIST */
+
+/* If this is for internal libc use, don't define anything but
+ __gnuc_va_list. */
+#if defined (_STDARG_H) || defined (_VARARGS_H)
+
+#ifdef _STDARG_H /* stdarg.h support */
+
+#if __GNUC__ > 1 /* GCC 2.0 and beyond */
+#define va_start(AP,LASTARG) ((AP) = *(__gnuc_va_list *)__builtin_saveregs())
+#else
+#define va_start(AP,LASTARG) \
+ ( (AP).__va_reg = (int *) __builtin_saveregs2(0), \
+ (AP).__va_stk = (int *) __builtin_argptr(), \
+ (AP).__va_arg = (int) (__builtin_argsize() + 3) / 4 )
+#endif
+
+#else /* varargs.h support */
+
+#if __GNUC__ > 1 /* GCC 2.0 and beyond */
+#define va_start(AP) ((AP) = *(__gnuc_va_list *)__builtin_saveregs())
+#else
+#define va_start(AP) \
+ ( (AP).__va_reg = (int *) __builtin_saveregs2(1), \
+ (AP).__va_stk = (int *) __builtin_argptr(), \
+ (AP).__va_arg = (int) (__builtin_argsize() - 4 + 3) / 4 )
+#endif
+#define va_alist __va_1st_arg
+#define va_dcl register int va_alist;
+
+#endif /* _STDARG_H */
+
+/* Avoid trouble between this file and _int_varargs.h under DG/UX. This file
+ can be included by <stdio.h> and others and provides definitions of
+ __va_size and __va_reg_p and a va_list typedef. Avoid defining va_list
+ again with _VA_LIST. */
+#ifdef __INT_VARARGS_H
+#undef __va_size
+#undef __va_reg_p
+#define __gnuc_va_list va_list
+#define _VA_LIST
+#else
+/* Similarly, if this gets included first, do nothing in _int_varargs.h. */
+#define __INT_VARARGS_H
+#endif
+
+#define __va_reg_p(TYPE) \
+ (__builtin_classify_type(*(TYPE *)0) < 12 \
+ ? sizeof(TYPE) <= 8 : sizeof(TYPE) == 4 && __alignof__(*(TYPE *)0) == 4)
+
+#define __va_size(TYPE) ((sizeof(TYPE) + 3) >> 2)
+
+/* We cast to void * and then to TYPE * because this avoids
+ a warning about increasing the alignment requirement. */
+#define va_arg(AP,TYPE) \
+ ( (AP).__va_arg = (((AP).__va_arg + (1 << (__alignof__(*(TYPE *)0) >> 3)) - 1) \
+ & ~((1 << (__alignof__(*(TYPE *)0) >> 3)) - 1)) \
+ + __va_size(TYPE), \
+ *((TYPE *) (void *) ((__va_reg_p(TYPE) \
+ && (AP).__va_arg < 8 + __va_size(TYPE) \
+ ? (AP).__va_reg : (AP).__va_stk) \
+ + ((AP).__va_arg - __va_size(TYPE)))))
+
+#define va_end(AP)
+
+#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
--- /dev/null
+/* This file has local changes by MOTOROLA
+Thu Sep 9 09:06:29 CDT 1993 Dale Rahn (drahn@pacific)
+ * (gstdarg.h, gvarargs.h) C-Front requires all builtins to
+ be defined. This is to insert these definitions if
+ __cplusplus is defined but not using the G++ compiler.
+ */
+#ifndef __GNUC__
+/* Use the system's macros with the system's compiler. */
+#include <varargs.h>
+#else
+/* Record that this is varargs.h; this turns off stdarg.h. */
+
+#ifndef _VARARGS_H
+#define _VARARGS_H
+
+#ifdef __sparc__
+#include <va-sparc.h>
+#else
+#ifdef __spur__
+#include <va-spur.h>
+#else
+#ifdef __mips__
+#include <va-mips.h>
+#else
+#ifdef __i860__
+#include <va-i860.h>
+#else
+#ifdef __pyr__
+#include <va-pyr.h>
+#else
+#ifdef __clipper__
+#include <va-clipper.h>
+#else
+#ifdef __m88k__
+#include <machine/va-m88k.h>
+#else
+#if defined(__hppa__) || defined(hp800)
+#include <va-pa.h>
+#else
+#ifdef __i960__
+#include <va-i960.h>
+#else
+#ifdef __alpha__
+#include <va-alpha.h>
+#else
+
+#ifdef __NeXT__
+
+/* On Next, erase any vestiges of stdarg.h. */
+
+#ifdef _ANSI_STDARG_H_
+#define _VA_LIST_
+#endif
+#define _ANSI_STDARG_H_
+
+#undef va_alist
+#undef va_dcl
+#undef va_list
+#undef va_start
+#undef va_end
+#undef __va_rounded_size
+#undef va_arg
+#endif /* __NeXT__ */
+
+/* In GCC version 2, we want an ellipsis at the end of the declaration
+ of the argument list. GCC version 1 can't parse it. */
+
+#if __GNUC__ > 1
+#define __va_ellipsis ...
+#else
+#define __va_ellipsis
+#endif
+
+/* These macros implement traditional (non-ANSI) varargs
+ for GNU C. */
+
+#define va_alist __builtin_va_alist
+/* The ... causes current_function_varargs to be set in cc1. */
+#define va_dcl int __builtin_va_alist; __va_ellipsis
+
+/* Define __gnuc_va_list, just as in gstdarg.h. */
+
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+#if defined(__svr4__) || defined(_AIX) || defined(_M_UNIX)
+typedef char *__gnuc_va_list;
+#else
+typedef void *__gnuc_va_list;
+#endif
+#endif
+
+#define va_start(AP) AP=(char *) &__builtin_va_alist
+
+#define va_end(AP)
+
+#define __va_rounded_size(TYPE) \
+ (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
+
+#if defined (__arm__) || defined (__i386__) || defined (__ns32000__) || defined (__vax__)
+/* This is for little-endian machines; small args are padded upward. */
+#define va_arg(AP, TYPE) \
+ (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \
+ *((TYPE *) (void *) ((char *) (AP) - __va_rounded_size (TYPE))))
+#else /* big-endian */
+/* This is for big-endian machines; small args are padded downward. */
+#define va_arg(AP, TYPE) \
+ (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \
+ *((TYPE *) (void *) ((char *) (AP) - ((sizeof (TYPE) < 4 \
+ ? sizeof (TYPE) \
+ : __va_rounded_size (TYPE))))))
+#endif /* big-endian */
+
+#endif /* not alpha */
+#endif /* not i960 */
+#endif /* not hppa */
+#endif /* not m88k */
+#endif /* not clipper */
+#endif /* not pyr */
+#endif /* not i860 */
+#endif /* not mips */
+#endif /* not spur */
+#endif /* not sparc */
+#endif /* not _VARARGS_H */
+
+/* Define va_list from __gnuc_va_list. */
+
+#ifdef _HIDDEN_VA_LIST /* On OSF1, this means varargs.h is "half-loaded". */
+#undef _VA_LIST
+#endif
+
+#ifdef __svr4__
+/* SVR4.2 uses _VA_LIST for an internal alias for va_list,
+ so we must avoid testing it and setting it here.
+ SVR4 uses _VA_LIST as a flag in stdarg.h, but we should
+ have no conflict with that. */
+#ifndef _VA_LIST_
+#define _VA_LIST_
+#ifdef __i860__
+#ifndef _VA_LIST
+#define _VA_LIST va_list
+#endif
+#endif /* __i860__ */
+typedef __gnuc_va_list va_list;
+#endif /* _VA_LIST_ */
+
+#else /* not __svr4__ */
+
+/* The macro _VA_LIST_ is the same thing used by this file in Ultrix.
+ But on BSD NET2 we must not test or define or undef it.
+ (Note that the comments in NET 2's ansi.h
+ are incorrect for _VA_LIST_--see stdio.h!) */
+#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____)
+/* The macro _VA_LIST is used in SCO Unix 3.2. */
+#ifndef _VA_LIST
+/* The macro _VA_LIST_T_H is used in the Bull dpx2 */
+#ifndef _VA_LIST_T_H
+#define _VA_LIST_T_H
+#if !(defined (__BSD_NET2__) || defined (____386BSD____))
+#define _VA_LIST_
+#endif
+#define _VA_LIST
+typedef __gnuc_va_list va_list;
+#endif /* not _VA_LIST_T_H */
+#endif /* not _VA_LIST */
+#endif /* not _VA_LIST_ */
+
+#endif /* not __svr4__ */
+
+/* took this one out Nivas */
+/* The next BSD release (if there is one) wants this symbol to be
+ undefined instead of _VA_LIST_. */
+#ifdef _BSD_VA_LIST_
+#undef _BSD_VA_LIST_
+#define _BSD_VA_LIST_ __gnuc_va_list
+#endif /* _BSD_VA_LIST_ */
+#if defined(__cplusplus) && !defined(__GNUG__)
+
+/* This is added to work with AT&T C++. */
+extern "C" {
+ char *__builtin_next_arg(void);
+ __gnuc_va_list *__builtin_saveregs(void);
+ void *__builtin_saveregs2(int);
+ int *__builtin_argptr(void);
+ int __builtin_argsize(void);
+ int __builtin_classify_type(...);
+ int __alignof__(...);
+}
+#endif
+
+
+#endif /* __GNUC__ */
--- /dev/null
+#define START_BLOCK 1
+#define LOADER_SIZE 2
+#define LOADER_ADDRESS 0x1F0000
+
+#ifndef __ASSEMBLER__
+struct vid {
+ unsigned char vid_id[4];
+ unsigned char vid_0[16];
+ unsigned int vid_oss;
+ unsigned short vid_osl;
+ unsigned char vid_1[4];
+ unsigned short vid_osa_u;
+ unsigned short vid_osa_l;
+ unsigned char vid_2[4];
+ unsigned char vid_vd[20];
+ unsigned char vid_3[86];
+ unsigned int vid_cas;
+ unsigned char vid_cal;
+ unsigned char vid_4[99];
+ unsigned char vid_mot[8];
+};
+struct cfg {
+
+ unsigned char cfg_0[4];
+ unsigned short cfg_atm;
+ unsigned short cfg_prm;
+ unsigned short cfg_atw;
+ unsigned short cfg_rec;
+ unsigned char cfg_1[12];
+ unsigned char cfg_spt;
+ unsigned char cfg_hds;
+ unsigned short cfg_trk;
+ unsigned char cfg_ilv;
+ unsigned char cfg_sof;
+ unsigned short cfg_psm;
+ unsigned short cfg_shd;
+ unsigned char cfg_2[2];
+ unsigned short cfg_pcom;
+ unsigned char cfg_3;
+ unsigned char cfg_ssr;
+ unsigned short cfg_rwcc;
+ unsigned short cfg_ecc;
+ unsigned short cfg_eatm;
+ unsigned short cfg_eprm;
+ unsigned short cfg_eatw;
+ unsigned char cfg_gpb1;
+ unsigned char cfg_gpb2;
+ unsigned char cfg_gpb3;
+ unsigned char cfg_gpb4;
+ unsigned char cfg_ssc;
+ unsigned char cfg_runit;
+ unsigned short cfg_rsvc1;
+ unsigned short cfg_rsvc2;
+ unsigned char cfg_4[196];
+};
+#endif
--- /dev/null
+/*
+ * Mach Operating System
+ * Copyright (c) 1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+/*
+ * HISTORY
+ */
+/*
+ * File: vm_param.h
+ *
+ * machine dependent virtual memory parameters.
+ * Most of the declarations are preceeded by M88K_ (or m88k_)
+ * which is OK because only M88K specific code will be using
+ * them.
+ */
+
+
+#ifndef _MACHINE_VM_PARAM_
+#define _MACHINE_VM_PARAM_
+
+/*
+ * USRTEXT is the start of the user text/data space, while USRSTACK
+ * is the top (end) of the user stack.
+ */
+#define USRTEXT 0x1000 /* Start of user text */
+#define USRSTACK 0x80000000 /* Start of user stack */
+
+/*
+ * Virtual memory related constants, all in bytes
+ */
+#ifndef MAXTSIZ
+#define MAXTSIZ (8*1024*1024) /* max text size */
+#endif
+#ifndef DFLDSIZ
+#define DFLDSIZ (16*1024*1024) /* initial data size limit */
+#endif
+#ifndef MAXDSIZ
+#define MAXDSIZ (64*1024*1024) /* max data size */
+#endif
+#ifndef DFLSSIZ
+#define DFLSSIZ (512*1024) /* initial stack size limit */
+#endif
+#ifndef MAXSSIZ
+#define MAXSSIZ MAXDSIZ /* max stack size */
+#endif
+
+/*
+ * Default sizes of swap allocation chunks (see dmap.h).
+ * The actual values may be changed in vminit() based on MAXDSIZ.
+ * With MAXDSIZ of 16Mb and NDMAP of 38, dmmax will be 1024.
+ * DMMIN should be at least ctod(1) so that vtod() works.
+ * vminit() insures this.
+ */
+#define DMMIN 32 /* smallest swap allocation */
+#define DMMAX 4096 /* largest potential swap allocation */
+#define DMTEXT 1024 /* swap allocation for text */
+
+/*
+ * Size of shared memory map
+ */
+#ifndef SHMMAXPGS
+#define SHMMAXPGS 1024
+#endif
+
+/*
+ * The time for a process to be blocked before being very swappable.
+ * This is a number of seconds which the system takes as being a non-trivial
+ * amount of real time. You probably shouldn't change this;
+ * it is used in subtle ways (fractions and multiples of it are, that is, like
+ * half of a ``long time'', almost a long time, etc.)
+ * It is related to human patience and other factors which don't really
+ * change over time.
+ */
+#define MAXSLP 20
+
+/*
+ * A swapped in process is given a small amount of core without being bothered
+ * by the page replacement algorithm. Basically this says that if you are
+ * swapped in you deserve some resources. We protect the last SAFERSS
+ * pages against paging and will just swap you out rather than paging you.
+ * Note that each process has at least UPAGES+CLSIZE pages which are not
+ * paged anyways (this is currently 8+2=10 pages or 5k bytes), so this
+ * number just means a swapped in process is given around 25k bytes.
+ * Just for fun: current memory prices are 4600$ a megabyte on VAX (4/22/81),
+ * so we loan each swapped in process memory worth 100$, or just admit
+ * that we don't consider it worthwhile and swap it out to disk which costs
+ * $30/mb or about $0.75.
+ */
+#define SAFERSS 4 /* nominal ``small'' resident set size
+ protected against replacement */
+
+#define VM_MINUSER_ADDRESS ((vm_offset_t) 0)
+#define VM_MAXUSER_ADDRESS ((vm_offset_t) 0xffc00000U)
+
+#define VM_MINKERNEL_ADDRESS ((vm_offset_t) 0)
+#define VM_MAXKERNEL_ADDRESS ((vm_offset_t) 0x1fffffff)
+
+/*
+ * Mach derived constants
+ */
+#define BYTE_SIZE 8 /* byte size in bits */
+
+#define M88K_PGBYTES (1<<12) /* bytes per m88k page */
+#define M88K_PGSHIFT 12 /* number of bits to shift for pages */
+
+/*
+ * Convert bytes to pages and convert pages to bytes.
+ * No rounding is used.
+ */
+
+#define m88k_btop(x) (((unsigned)(x)) >> M88K_PGSHIFT)
+#define m88k_ptob(x) (((unsigned)(x)) << M88K_PGSHIFT)
+
+/*
+ * Round off or truncate to the nearest page. These will work
+ * for either addresses or counts. (i.e. 1 byte rounds to 1 page
+ * bytes.
+ */
+
+#define m88k_round_page(x) ((((unsigned)(x)) + M88K_PGBYTES - 1) & \
+ ~(M88K_PGBYTES-1))
+#define m88k_trunc_page(x) (((unsigned)(x)) & ~(M88K_PGBYTES-1))
+
+#define VM_MIN_ADDRESS ((vm_offset_t) 0)
+#define VM_MAX_ADDRESS ((vm_offset_t) 0xffc00000U)
+
+#define VM_MIN_USER_ADDRESS ((vm_offset_t) 0)
+#define VM_MAX_USER_ADDRESS ((vm_offset_t) 0xffc00000U)
+
+/* on vme188, max = 0xf0000000 */
+
+#define VM_MIN_KERNEL_ADDRESS ((vm_offset_t) 0)
+#define VM_MAX_KERNEL_ADDRESS ((vm_offset_t) 0x1fffffff)
+
+#define KERNEL_STACK_SIZE (3*4096) /* kernel stack size */
+#define INTSTACK_SIZE (3*4096) /* interrupt stack size */
+
+/* virtual sizes (bytes) for various kernel submaps */
+#define VM_MBUF_SIZE (NMBCLUSTERS*MCLBYTES)
+#define VM_KMEM_SIZE (NKMEMCLUSTERS*CLBYTES)
+
+/*
+ * Conversion between MACHINE pages and VM pages
+ */
+
+#define trunc_m88k_to_vm(p) (atop(trunc_page(m88k_ptob(p))))
+#define round_m88k_to_vm(p) (atop(round_page(m88k_ptob(p))))
+#define vm_to_m88k(p) (m88k_btop(ptoa(p)))
+
+#if 1 /*Do we really need all this stuff*/
+#if 1 /*Do we really need all this stuff*/
+#if 1 /*Do we really need all this stuff*/
+#define M88K_SGPAGES (1<<10) /* pages per m88k segment */
+#define M88K_SGPGSHIFT 10 /* number of bits to shift for segment-page */
+#define M88K_ALSEGMS (1<<10) /* segments per m88k all space */
+#define M88K_ALSGSHIFT 10 /* number of bits to shift for all-segment */
+
+#define M88K_SGBYTES (1<<22) /* bytes per m88k segments */
+#define M88K_SGSHIFT 22 /* number of bits to shift for segment */
+#define M88K_ALPAGES (1<<20) /* pages per m88k all space */
+#define M88K_ALPGSHIFT 20 /* number of bits to shift for all-page */
+
+/*
+ * Convert bytes to pages and convert pages to bytes.
+ * No rounding is used.
+ */
+
+#define m88k_btopr(x) (((unsigned)(x) + (M88K_PGBYTES - 1)) >> M88K_PGSHIFT)
+#define m88k_btosr(x) (((unsigned)(x) + (M88K_SGBYTES - 1)) >> M88K_SGSHIFT)
+#define m88k_btos(x) (((unsigned)(x)) >> M88K_SGSHIFT)
+#define m88k_stob(x) (((unsigned)(x)) << M88K_SGSHIFT)
+#define m88k_ptosr(x) (((unsigned)(x) + (M88K_SGPAGES - 1)) >> M88K_SGPGSHIFT)
+#define m88k_ptos(x) (((unsigned)(x)) >> M88K_SGPGSHIFT)
+#define m88k_stop(x) (((unsigned)(x)) << M88K_SGPGSHIFT)
+
+/*
+ * Round off or truncate to the nearest page. These will work
+ * for either addresses or counts. (i.e. 1 byte rounds to 1 page
+ * bytes.
+ */
+
+#define m88k_round_segm(x) ((((unsigned)(x)) + M88K_SGBYTES - 1) & \
+ ~(M88K_SGBYTES-1))
+#define m88k_next_segm(x) ((((unsigned)(x)) & ~(M88K_SGBYTES-1)) + \
+ M88K_SGBYTES)
+#define m88k_trunc_segm(x) (((unsigned)(x)) & ~(M88K_SGBYTES-1))
+
+#define m88k_round_seg(x) ((((unsigned)(x)) + M88K_SGBYTES - 1) & \
+ ~(M88K_SGBYTES-1))
+#define m88k_trunc_seg(x) (((unsigned)(x)) & ~(M88K_SGBYTES-1))
+
+#define VEQR_ADDR 0x20000000 /* kernel virtual eq phy mapping */
+#endif /* Do we really need all this stuff */
+#endif /* Do we really need all this stuf */
+#endif /* Do we really need all this stuff */
+
+#endif _MACHINE_VM_PARAM_
--- /dev/null
+/*
+ * Copyright (c) 1995 Dale Rahn.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Dale Rahn.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/buf.h>
+#define DKTYPENAMES
+#include <sys/disklabel.h>
+
+#define b_cylin b_resid
+
+#ifdef DEBUG
+int disksubr_debug = 0;
+#endif
+
+static void bsdtocpulabel __P((struct disklabel *lp,
+ struct cpu_disklabel *clp));
+static void cputobsdlabel __P((struct disklabel *lp,
+ struct cpu_disklabel *clp));
+
+#ifdef DEBUG
+static void printlp __P((struct disklabel *lp, char *str));
+static void printclp __P((struct cpu_disklabel *clp, char *str));
+#endif
+
+int
+dk_establish()
+{
+ return(-1);
+}
+
+/*
+ * Attempt to read a disk label from a device
+ * using the indicated stategy routine.
+ * The label must be partly set up before this:
+ * secpercyl and anything required in the strategy routine
+ * (e.g., sector size) must be filled in before calling us.
+ * Returns null on success and an error string on failure.
+ */
+char *
+readdisklabel(dev, strat, lp, clp)
+ dev_t dev;
+ void (*strat)();
+ struct disklabel *lp;
+ struct cpu_disklabel *clp;
+{
+ struct buf *bp;
+ char *msg = NULL;
+
+ /* obtain buffer to probe drive with */
+ bp = geteblk((int)lp->d_secsize);
+
+ /* request no partition relocation by driver on I/O operations */
+ bp->b_dev = dev;
+ bp->b_blkno = 0; /* contained in block 0 */
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylin = 0; /* contained in block 0 */
+ (*strat)(bp);
+
+ if (biowait(bp)) {
+ msg = "cpu_disklabel read error\n";
+ }else {
+ bcopy(bp->b_data, clp, sizeof (struct cpu_disklabel));
+ }
+
+ bp->b_flags = B_INVAL | B_AGE | B_READ;
+ brelse(bp);
+
+ if (msg || clp->magic1 != DISKMAGIC || clp->magic2 != DISKMAGIC) {
+ return (msg);
+ }
+
+ cputobsdlabel(lp, clp);
+#ifdef DEBUG
+ if(disksubr_debug > 0) {
+ printlp(lp, "readdisklabel:bsd label");
+ printclp(clp, "readdisklabel:cpu label");
+ }
+#endif
+ return (msg);
+}
+
+/*
+ * Check new disk label for sensibility
+ * before setting it.
+ */
+int
+setdisklabel(olp, nlp, openmask, clp)
+ register struct disklabel *olp, *nlp;
+ u_long openmask;
+ struct cpu_disklabel *clp;
+{
+ register i;
+ register struct partition *opp, *npp;
+
+#ifdef DEBUG
+ if(disksubr_debug > 0) {
+ printlp(nlp, "setdisklabel:new disklabel");
+ printlp(olp, "setdisklabel:old disklabel");
+ printclp(clp, "setdisklabel:cpu disklabel");
+ }
+#endif
+
+
+ /* sanity clause */
+ if (nlp->d_secpercyl == 0 || nlp->d_secsize == 0 ||
+ (nlp->d_secsize % DEV_BSIZE) != 0)
+ return (EINVAL);
+
+ /* special case to allow disklabel to be invalidated */
+ if (nlp->d_magic == 0xffffffff) {
+ *olp = *nlp;
+ return (0);
+ }
+
+ if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC ||
+ dkcksum(nlp) != 0)
+ return (EINVAL);
+
+ while ((i = ffs((long)openmask)) != 0) {
+ i--;
+ openmask &= ~(1 << i);
+ if (nlp->d_npartitions <= i)
+ return (EBUSY);
+ opp = &olp->d_partitions[i];
+ npp = &nlp->d_partitions[i];
+ if (npp->p_offset != opp->p_offset || npp->p_size < opp->p_size)
+ return (EBUSY);
+ /*
+ * Copy internally-set partition information
+ * if new label doesn't include it. XXX
+ */
+ if (npp->p_fstype == FS_UNUSED && opp->p_fstype != FS_UNUSED) {
+ npp->p_fstype = opp->p_fstype;
+ npp->p_fsize = opp->p_fsize;
+ npp->p_frag = opp->p_frag;
+ npp->p_cpg = opp->p_cpg;
+ }
+ }
+
+ nlp->d_checksum = 0;
+ nlp->d_checksum = dkcksum(nlp);
+ *olp = *nlp;
+#ifdef DEBUG
+ if(disksubr_debug > 0) {
+ printlp(olp, "setdisklabel:old->new disklabel");
+ }
+#endif
+ return (0);
+}
+
+/*
+ * Write disk label back to device after modification.
+ */
+writedisklabel(dev, strat, lp, clp)
+ dev_t dev;
+ void (*strat)();
+ register struct disklabel *lp;
+ struct cpu_disklabel *clp;
+{
+ struct buf *bp;
+ int error;
+
+#ifdef DEBUG
+ if(disksubr_debug > 0) {
+ printlp(lp, "writedisklabel: bsd label");
+ }
+#endif
+
+ /* obtain buffer to read initial cpu_disklabel, for bootloader size :-) */
+ bp = geteblk((int)lp->d_secsize);
+
+ /* request no partition relocation by driver on I/O operations */
+ bp->b_dev = dev;
+ bp->b_blkno = 0; /* contained in block 0 */
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylin = 0; /* contained in block 0 */
+ (*strat)(bp);
+
+ if (error = biowait(bp)) {
+ /* nothing */
+ } else {
+ bcopy(bp->b_data, clp, sizeof(struct cpu_disklabel));
+ }
+
+ bp->b_flags = B_INVAL | B_AGE | B_READ;
+ brelse(bp);
+
+ if (error) {
+ return (error);
+ }
+
+ bsdtocpulabel(lp, clp);
+
+#ifdef DEBUG
+ if (disksubr_debug > 0) {
+ printclp(clp, "writedisklabel: cpu label");
+ }
+#endif
+
+ if (lp->d_magic == DISKMAGIC && lp->d_magic2 == DISKMAGIC &&
+ dkcksum(lp) == 0) {
+ /* obtain buffer to scrozz drive with */
+ bp = geteblk((int)lp->d_secsize);
+
+ bcopy(clp, bp->b_data, sizeof(struct cpu_disklabel));
+
+ /* request no partition relocation by driver on I/O operations */
+ bp->b_dev = dev;
+ bp->b_blkno = 0; /* contained in block 0 */
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_WRITE;
+ bp->b_cylin = 0; /* contained in block 0 */
+ (*strat)(bp);
+
+ error = biowait(bp);
+
+ bp->b_flags = B_INVAL | B_AGE | B_READ;
+ brelse(bp);
+ }
+ return (error);
+}
+
+
+int
+bounds_check_with_label(bp, lp, wlabel)
+ struct buf *bp;
+ struct disklabel *lp;
+ int wlabel;
+{
+ struct partition *p = lp->d_partitions + DISKPART(bp->b_dev);
+ int labelsect = lp->d_partitions[0].p_offset;
+ int maxsz = p->p_size;
+ int sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
+
+ /* overwriting disk label ? */
+ /* XXX should also protect bootstrap in first 8K */
+ if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect &&
+#if LABELSECTOR != 0
+ bp->b_blkno + p->p_offset + sz > LABELSECTOR + labelsect &&
+#endif
+ (bp->b_flags & B_READ) == 0 && wlabel == 0) {
+ bp->b_error = EROFS;
+ goto bad;
+ }
+
+ /* beyond partition? */
+ if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
+ /* if exactly at end of disk, return an EOF */
+ if (bp->b_blkno == maxsz) {
+ bp->b_resid = bp->b_bcount;
+ return(0);
+ }
+ /* or truncate if part of it fits */
+ sz = maxsz - bp->b_blkno;
+ if (sz <= 0) {
+ bp->b_error = EINVAL;
+ goto bad;
+ }
+ bp->b_bcount = sz << DEV_BSHIFT;
+ }
+
+ /* calculate cylinder for disksort to order transfers with */
+ bp->b_cylin = (bp->b_blkno + p->p_offset) / lp->d_secpercyl;
+ return(1);
+
+bad:
+ bp->b_flags |= B_ERROR;
+ return(-1);
+}
+
+
+static void
+bsdtocpulabel(lp, clp)
+ struct disklabel *lp;
+ struct cpu_disklabel *clp;
+{
+ int i;
+
+ clp->magic1 = lp->d_magic;
+ clp->type = lp->d_type;
+ clp->subtype = lp->d_subtype;
+ strncpy(clp->vid_vd, lp->d_typename, 16);
+ strncpy(clp->packname, lp->d_packname, 16);
+ clp->cfg_psm = lp->d_secsize;
+ clp->cfg_spt = lp->d_nsectors;
+ clp->cfg_trk = lp->d_ncylinders; /* trk is really num of cyl! */
+ clp->cfg_hds = lp->d_ntracks;
+
+ clp->secpercyl = lp->d_secpercyl;
+ clp->secperunit = lp->d_secperunit;
+ clp->sparespertrack = lp->d_sparespertrack;
+ clp->sparespercyl = lp->d_sparespercyl;
+ clp->acylinders = lp->d_acylinders;
+ clp->rpm = lp->d_rpm;
+
+ clp->cfg_ilv = lp->d_interleave;
+ clp->cfg_sof = lp->d_trackskew;
+ clp->cylskew = lp->d_cylskew;
+ clp->headswitch = lp->d_headswitch;
+
+ /* this silly table is for winchester drives */
+ if (lp->d_trkseek < 6) {
+ clp->cfg_ssr = 0;
+ } else if (lp->d_trkseek < 10) {
+ clp->cfg_ssr = 1;
+ } else if (lp->d_trkseek < 15) {
+ clp->cfg_ssr = 2;
+ } else if (lp->d_trkseek < 20) {
+ clp->cfg_ssr = 3;
+ } else {
+ clp->cfg_ssr = 4;
+ }
+
+ clp->flags = lp->d_flags;
+ for (i = 0; i < NDDATA; i++)
+ clp->drivedata[i] = lp->d_drivedata[i];
+ for (i = 0; i < NSPARE; i++)
+ clp->spare[i] = lp->d_spare[i];
+
+ clp->magic2 = lp->d_magic2;
+ clp->checksum = lp->d_checksum;
+ clp->partitions = lp->d_npartitions;
+ clp->bbsize = lp->d_bbsize;
+ clp->sbsize = lp->d_sbsize;
+ clp->checksum = lp->d_checksum;
+ bcopy(&lp->d_partitions[0], clp->vid_4, sizeof(struct partition) * 4);
+ bcopy(&lp->d_partitions[4], clp->cfg_4, sizeof(struct partition) * 12);
+ clp->version = 1;
+}
+
+struct cpu_disklabel_old {
+ /* VID */
+ u_char vid_id[4];
+ u_char vid_0[16];
+ u_int vid_oss;
+ u_short vid_osl;
+ u_char vid_1[4];
+ u_short vid_osa_u;
+ u_short vid_osa_l;
+ u_char vid_2[2];
+ u_short partitions;
+ u_char vid_vd[16];
+ u_long bbsize;
+ u_long magic1; /* 4 */
+ u_short type; /* 2 */
+ u_short subtype; /* 2 */
+ u_char packname[16]; /* 16 */
+ u_long flags; /* 4 */
+ u_long drivedata[5]; /* 4 */
+ u_long spare[5]; /* 4 */
+ u_short checksum; /* 2 */
+
+ u_long secpercyl; /* 4 */
+ u_long secperunit; /* 4 */
+ u_long headswitch; /* 4 */
+
+ u_char vid_3[4];
+ u_int vid_cas;
+ u_char vid_cal;
+ u_char vid_4_0[3];
+ u_char vid_4[64];
+ u_char vid_4_1[28];
+ u_long sbsize;
+ u_char vid_mot[8];
+
+ /* CFG */
+ u_char cfg_0[4];
+ u_short cfg_atm;
+ u_short cfg_prm;
+ u_short cfg_atw;
+ u_short cfg_rec;
+
+ u_short sparespertrack;
+ u_short sparespercyl;
+ u_long acylinders;
+ u_short rpm;
+ u_short cylskew;
+
+ u_char cfg_spt;
+ u_char cfg_hds;
+ u_short cfg_trk;
+ u_char cfg_ilv;
+ u_char cfg_sof;
+ u_short cfg_psm;
+ u_short cfg_shd;
+ u_char cfg_2[2];
+ u_short cfg_pcom;
+ u_char cfg_3;
+ u_char cfg_ssr;
+ u_short cfg_rwcc;
+ u_short cfg_ecc;
+ u_short cfg_eatm;
+ u_short cfg_eprm;
+ u_short cfg_eatw;
+ u_char cfg_gpb1;
+ u_char cfg_gpb2;
+ u_char cfg_gpb3;
+ u_char cfg_gpb4;
+ u_char cfg_ssc;
+ u_char cfg_runit;
+ u_short cfg_rsvc1;
+ u_short cfg_rsvc2;
+ u_long magic2;
+ u_char cfg_4[192];
+};
+
+static void
+cputobsdlabel(lp, clp)
+ struct disklabel *lp;
+ struct cpu_disklabel *clp;
+{
+ int i;
+
+ if (clp->version == 0) {
+ struct cpu_disklabel_old *clpo = (void *) clp;
+ printf("Reading old disklabel\n");
+ lp->d_magic = clp->magic1;
+ lp->d_type = clp->type;
+ lp->d_subtype = clp->subtype;
+ strncpy(lp->d_typename, clp->vid_vd, 16);
+ strncpy(lp->d_packname, clp->packname, 16);
+ lp->d_secsize = clp->cfg_psm;
+ lp->d_nsectors = clp->cfg_spt;
+ lp->d_ncylinders = clp->cfg_trk; /* trk is really num of cyl! */
+ lp->d_ntracks = clp->cfg_hds;
+
+ lp->d_secpercyl = clp->secpercyl;
+ lp->d_secperunit = clp->secperunit;
+ lp->d_secpercyl = clp->secpercyl;
+ lp->d_secperunit = clp->secperunit;
+ lp->d_sparespertrack = clp->sparespertrack;
+ lp->d_sparespercyl = clp->sparespercyl;
+ lp->d_acylinders = clp->acylinders;
+ lp->d_rpm = clp->rpm;
+ lp->d_interleave = clp->cfg_ilv;
+ lp->d_trackskew = clp->cfg_sof;
+ lp->d_cylskew = clp->cylskew;
+ lp->d_headswitch = clp->headswitch;
+
+ /* this silly table is for winchester drives */
+ switch (clp->cfg_ssr) {
+ case 0:
+ lp->d_trkseek = 0;
+ break;
+ case 1:
+ lp->d_trkseek = 6;
+ break;
+ case 2:
+ lp->d_trkseek = 10;
+ break;
+ case 3:
+ lp->d_trkseek = 15;
+ break;
+ case 4:
+ lp->d_trkseek = 20;
+ break;
+ default:
+ lp->d_trkseek = 0;
+ }
+ lp->d_flags = clp->flags;
+ for (i = 0; i < NDDATA; i++)
+ lp->d_drivedata[i] = clp->drivedata[i];
+ for (i = 0; i < NSPARE; i++)
+ lp->d_spare[i] = clp->spare[i];
+
+ lp->d_magic2 = clp->magic2;
+ lp->d_checksum = clp->checksum;
+ lp->d_npartitions = clp->partitions;
+ lp->d_bbsize = clp->bbsize;
+ lp->d_sbsize = clp->sbsize;
+ bcopy(clp->vid_4, &lp->d_partitions[0], sizeof(struct partition) * 4);
+ bcopy(clp->cfg_4, &lp->d_partitions[4], sizeof(struct partition) * 12);
+ lp->d_checksum = 0;
+ lp->d_checksum = dkcksum(lp);
+ } else {
+ printf("Reading new disklabel\n");
+ lp->d_magic = clp->magic1;
+ lp->d_type = clp->type;
+ lp->d_subtype = clp->subtype;
+ strncpy(lp->d_typename, clp->vid_vd, 16);
+ strncpy(lp->d_packname, clp->packname, 16);
+ lp->d_secsize = clp->cfg_psm;
+ lp->d_nsectors = clp->cfg_spt;
+ lp->d_ncylinders = clp->cfg_trk; /* trk is really num of cyl! */
+ lp->d_ntracks = clp->cfg_hds;
+
+ lp->d_secpercyl = clp->secpercyl;
+ lp->d_secperunit = clp->secperunit;
+ lp->d_secpercyl = clp->secpercyl;
+ lp->d_secperunit = clp->secperunit;
+ lp->d_sparespertrack = clp->sparespertrack;
+ lp->d_sparespercyl = clp->sparespercyl;
+ lp->d_acylinders = clp->acylinders;
+ lp->d_rpm = clp->rpm;
+ lp->d_interleave = clp->cfg_ilv;
+ lp->d_trackskew = clp->cfg_sof;
+ lp->d_cylskew = clp->cylskew;
+ lp->d_headswitch = clp->headswitch;
+
+ /* this silly table is for winchester drives */
+ switch (clp->cfg_ssr) {
+ case 0:
+ lp->d_trkseek = 0;
+ break;
+ case 1:
+ lp->d_trkseek = 6;
+ break;
+ case 2:
+ lp->d_trkseek = 10;
+ break;
+ case 3:
+ lp->d_trkseek = 15;
+ break;
+ case 4:
+ lp->d_trkseek = 20;
+ break;
+ default:
+ lp->d_trkseek = 0;
+ }
+ lp->d_flags = clp->flags;
+ for (i = 0; i < NDDATA; i++)
+ lp->d_drivedata[i] = clp->drivedata[i];
+ for (i = 0; i < NSPARE; i++)
+ lp->d_spare[i] = clp->spare[i];
+
+ lp->d_magic2 = clp->magic2;
+ lp->d_checksum = clp->checksum;
+ lp->d_npartitions = clp->partitions;
+ lp->d_bbsize = clp->bbsize;
+ lp->d_sbsize = clp->sbsize;
+ bcopy(clp->vid_4, &lp->d_partitions[0], sizeof(struct partition) * 4);
+ bcopy(clp->cfg_4, &lp->d_partitions[4], sizeof(struct partition) * 12);
+ lp->d_checksum = 0;
+ lp->d_checksum = dkcksum(lp);
+ }
+#if DEBUG
+ if (disksubr_debug > 0) {
+ printlp(lp, "translated label read from disk\n");
+ }
+#endif
+}
+
+#ifdef DEBUG
+static void
+printlp(lp, str)
+ struct disklabel *lp;
+ char *str;
+{
+ int i;
+
+ printf("%s\n", str);
+ printf("magic1 %x\n", lp->d_magic);
+ printf("magic2 %x\n", lp->d_magic2);
+ printf("typename %s\n", lp->d_typename);
+ printf("secsize %x nsect %x ntrack %x ncylinders %x\n",
+ lp->d_secsize, lp->d_nsectors, lp->d_ntracks, lp->d_ncylinders);
+ printf("Num partitions %x\n", lp->d_npartitions);
+ for (i = 0; i < lp->d_npartitions; i++) {
+ struct partition *part = &lp->d_partitions[i];
+ char *fstyp = fstypenames[part->p_fstype];
+
+ printf("%c: size %10x offset %10x type %7s frag %5x cpg %3x\n",
+ 'a' + i, part->p_size, part->p_offset, fstyp,
+ part->p_frag, part->p_cpg);
+ }
+}
+
+static void
+printclp(clp, str)
+ struct cpu_disklabel *clp;
+ char *str;
+{
+ int max, i;
+
+ printf("%s\n", str);
+ printf("magic1 %x\n", clp->magic1);
+ printf("magic2 %x\n", clp->magic2);
+ printf("typename %s\n", clp->vid_vd);
+ printf("secsize %x nsect %x ntrack %x ncylinders %x\n",
+ clp->cfg_psm, clp->cfg_spt, clp->cfg_hds, clp->cfg_trk);
+ printf("Num partitions %x\n", clp->partitions);
+ max = clp->partitions < 16 ? clp->partitions : 16;
+ for (i = 0; i < max; i++) {
+ struct partition *part;
+ char *fstyp;
+
+ if (i < 4) {
+ part = (void *)&clp->vid_4[0];
+ part = &part[i];
+ } else {
+ part = (void *)&clp->cfg_4[0];
+ part = &part[i-4];
+ }
+
+ fstyp = fstypenames[part->p_fstype];
+
+ printf("%c: size %10x offset %10x type %7s frag %5x cpg %3x\n",
+ 'a' + i, part->p_size, part->p_offset, fstyp,
+ part->p_frag, part->p_cpg);
+ }
+}
+#endif
--- /dev/null
+/* $NetBSD: dkbad.c,v 1.4 1994/10/26 07:25:33 cgd Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1990, 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.
+ *
+ * @(#)dkbad.c 8.2 (Berkeley) 1/12/94
+ */
+
+#ifndef NOBADSECT
+#include <sys/param.h>
+#include <sys/buf.h>
+#include <sys/dkbad.h>
+
+/*
+ * Search the bad sector table looking for
+ * the specified sector. Return index if found.
+ * Return -1 if not found.
+ */
+
+isbad(bt, cyl, trk, sec)
+ register struct dkbad *bt;
+ int cyl, trk, sec;
+{
+ register int i;
+ register long blk, bblk;
+
+ blk = ((long)cyl << 16) + (trk << 8) + sec;
+ for (i = 0; i < 126; i++) {
+ bblk = ((long)bt->bt_bad[i].bt_cyl << 16) + bt->bt_bad[i].bt_trksec;
+ if (blk == bblk)
+ return (i);
+ if (blk < bblk || bblk < 0)
+ break;
+ }
+ return (-1);
+}
+#endif
--- /dev/null
+/* $NetBSD: mem.c,v 1.11 1995/05/29 23:57:16 pk Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * 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.
+ *
+ * @(#)mem.c 8.3 (Berkeley) 1/12/94
+ */
+
+/*
+ * Memory special file
+ */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/buf.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+
+#include <machine/board.h>
+
+#include <vm/vm.h>
+
+caddr_t zeropage;
+
+/*ARGSUSED*/
+int
+mmopen(dev, flag, mode)
+ dev_t dev;
+ int flag, mode;
+{
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+mmclose(dev, flag, mode)
+ dev_t dev;
+ int flag, mode;
+{
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+mmrw(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+{
+ register vm_offset_t o, v;
+ register int c;
+ register struct iovec *iov;
+ int error = 0;
+ static int physlock = 0;
+ extern caddr_t vmmap;
+
+ if (minor(dev) == 0) {
+ /* lock against other uses of shared vmmap */
+ while (physlock > 0) {
+ physlock++;
+ error = tsleep((caddr_t)&physlock, PZERO | PCATCH,
+ "mmrw", 0);
+ if (error)
+ return (error);
+ }
+ physlock = 1;
+ }
+ while (uio->uio_resid > 0 && error == 0) {
+ iov = uio->uio_iov;
+ if (iov->iov_len == 0) {
+ uio->uio_iov++;
+ uio->uio_iovcnt--;
+ if (uio->uio_iovcnt < 0)
+ panic("mmrw");
+ continue;
+ }
+ switch (minor(dev)) {
+
+/* minor device 0 is physical memory */
+ case 0:
+ /* move one page at a time */
+ v = uio->uio_offset;
+ if (v > MAXPHYSMEM) {
+ error = EFAULT;
+ goto unlock;
+ }
+ pmap_enter(pmap_kernel(), (vm_offset_t)vmmap,
+ trunc_page(v), uio->uio_rw == UIO_READ ?
+ VM_PROT_READ : VM_PROT_WRITE, TRUE);
+ o = uio->uio_offset & PGOFSET;
+ c = min(uio->uio_resid, (int)(NBPG - o));
+ error = uiomove((caddr_t)vmmap + o, c, uio);
+ pmap_remove(pmap_kernel(), (vm_offset_t)vmmap,
+ (vm_offset_t)vmmap + NBPG);
+ continue;
+
+/* minor device 1 is kernel memory */
+ case 1:
+ v = uio->uio_offset;
+ c = min(iov->iov_len, MAXPHYS);
+ error = uiomove((caddr_t)v, c, uio);
+ continue;
+
+/* minor device 2 is EOF/RATHOLE */
+ case 2:
+ if (uio->uio_rw == UIO_WRITE)
+ uio->uio_resid = 0;
+ return (0);
+
+/* should add vme bus so that we can do user level probes */
+
+/* minor device 12 (/dev/zero) is source of nulls on read, rathole on write */
+ case 12:
+ if (uio->uio_rw == UIO_WRITE) {
+ c = iov->iov_len;
+ break;
+ }
+ if (zeropage == NULL) {
+ zeropage = (caddr_t)
+ malloc(CLBYTES, M_TEMP, M_WAITOK);
+ bzero(zeropage, CLBYTES);
+ }
+ c = min(iov->iov_len, CLBYTES);
+ error = uiomove(zeropage, c, uio);
+ continue;
+
+ default:
+ return (ENXIO);
+ }
+ if (error)
+ break;
+ iov->iov_base += c;
+ iov->iov_len -= c;
+ uio->uio_offset += c;
+ uio->uio_resid -= c;
+ }
+ if (minor(dev) == 0) {
+unlock:
+ if (physlock > 1)
+ wakeup((caddr_t)&physlock);
+ physlock = 0;
+ }
+ return (error);
+}
+
+int
+mmmmap(dev, off, prot)
+ dev_t dev;
+ int off, prot;
+{
+
+ return (EOPNOTSUPP);
+}
--- /dev/null
+# $Id: Makefile.inc,v 1.1.1.1 1997/03/03 19:30:28 rahnds Exp $
+
+MDEC_DIR?=/usr/mdec
--- /dev/null
+# from: @(#)Makefile 8.1 (Berkeley) 6/10/93
+# $Id: Makefile,v 1.1.1.1 1997/03/03 19:30:29 rahnds Exp $
+
+RELOC=0x3F0000
+
+S= ${.CURDIR}/../../../..
+DEFS= -DSTANDALONE -DCOMPAT_NOLABEL # -DROMPRF
+INCPATH=-I${.CURDIR} -I${.CURDIR}/../../include -I${S} -I${S}/lib/libsa
+CFLAGS= ${INCPATH} ${DEFS} ${COPTS}
+CLEANFILES+=sdboot bootsd bootsd.bug
+
+#.PATH: ${S}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
+#.PATH: ${S}/lib/libsa
+
+.include "${S}/arch/${MACHINE}/stand/libsa/Makefile.inc"
+.include "${S}/arch/${MACHINE}/stand/libbug/Makefile.inc"
+.include "${S}/arch/${MACHINE}/stand/bugcrt/Makefile.inc"
+.include "${S}/arch/${MACHINE}/stand/wrtvid/Makefile.inc"
+
+SRCS= boot.c filesystem.c bugdev.c version.c
+
+LIBS= ${LIBSA} ${LIBBUG} libgcc.a
+
+OBJS= ${SRCS:N*.h:R:S/$/.o/g}
+
+BOOTS= bootsd sdboot
+ALL= ${BOOTS}
+
+all: ${ALL}
+
+devopen.o machdep.o: Makefile
+
+bootsd.bug: ${OBJS} ${BUGCRT} ${LIBS}
+ ${LD} -N -T ${RELOC} ${BUGCRT} ${OBJS} ${LIBS} -o $@
+ @size bootsd.bug
+
+bootsd sdboot: bootsd.bug ${WRTVID}
+ cp bootsd.bug bootsd.bin
+ strip bootsd.bin
+ @if [ `size bootsd.bin | awk 'BEGIN {getline} {print $$1+$$2;}'` -gt 7168 ];\
+ then\
+ echo BOOTBLOCKS ARE TOO BIG;\
+ fail;\
+ fi
+ ${WRTVID} bootsd.bin
+
+install:
+ install -c -m 555 -g bin -o bin ${BOOTS} ${DESTDIR}${MDEC_DIR}
+
+.include <bsd.prog.mk>
--- /dev/null
+In short: stick the the bootblocks into a partition with
+something like:
+ cat sdboot bootsd > /dev/rsd0c
--- /dev/null
+/* $Id: boot.c,v 1.1.1.1 1997/03/03 19:30:29 rahnds Exp $ */
+
+/*-
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ *
+ * Copyright (c) 1982, 1986, 1990, 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.
+ *
+ * from: @(#)boot.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/reboot.h>
+#include <a.out.h>
+#include <machine/prom.h>
+#include "stand.h"
+
+void copyunix __P((int io, char *addr));
+void parse_args __P((void));
+
+int debug;
+int netif_debug;
+#define RB_NOSYM 0x400
+
+/*
+ * Boot device is derived from ROM provided information.
+ */
+extern char *version;
+u_long esym;
+char *strtab;
+int strtablen;
+#if 0
+struct nlist *nlp, *enlp;
+#endif
+
+struct kernel {
+ void *entry;
+ void *symtab;
+ void *esym;
+ int bflags;
+ int bdev;
+ char *kname;
+ void *smini;
+ void *emini;
+ u_int end_loaded;
+} kernel;
+
+extern struct mvmeprom_args bugargs;
+
+int
+main()
+{
+ struct exec x;
+ char *file;
+ void *addr;
+ int io, i;
+
+ printf(">> OpenBSD sdboot [%s]\n", version);
+
+ parse_args();
+ file = kernel.kname;
+
+ io = open(file, 0);
+ if (io < 0) {
+ printf("Can't open %s: %s\n", file, strerror(errno));
+ mvmeprom_return();
+ }
+ i = read(io, (char *)&x, sizeof(x));
+ if (i != sizeof(x) || N_BADMAG(x)) {
+ printf("Bad format\n");
+ return (0);
+ }
+ /* Make load address start of page which containes "start" */
+ addr = (void *)(x.a_entry & ~0x0FFF);
+ lseek(io, 0, SEEK_SET);
+
+ printf("load %s to 0x%x\n", file, addr);
+ copyunix(io, addr);
+ return (0);
+}
+
+/*ARGSUSED*/
+void
+copyunix(io, addr)
+ int io;
+ char *addr;
+{
+ void (*entry)() = (void (*)())addr;
+ struct exec x;
+ int i, cnt;
+
+ i = read(io, (char *)&x, sizeof(x));
+ if (i != sizeof(x) || N_BADMAG(x)) {
+ printf("Bad format\n");
+ return;
+ }
+
+ printf("%x", x.a_text);
+ if (N_GETMAGIC(x) == ZMAGIC) {
+ kernel.entry = entry = (void *)x.a_entry;
+ lseek(io, 0, SEEK_SET);
+ }
+ if (read(io, (char *)addr, x.a_text) != x.a_text)
+ goto shread;
+ addr += x.a_text;
+ if (N_GETMAGIC(x) == NMAGIC)
+ while ((int)addr & CLOFSET)
+ *addr++ = 0;
+ printf("+%x", x.a_data);
+ if (read(io, addr, x.a_data) != x.a_data)
+ goto shread;
+ addr += x.a_data;
+ printf("+%x", x.a_bss);
+ for (i = 0; i < x.a_bss; i++)
+ *addr++ = 0;
+ if (x.a_syms != 0 && !(kernel.bflags & RB_NOSYM)) {
+ bcopy(&x.a_syms, addr, sizeof(x.a_syms));
+ addr += sizeof(x.a_syms);
+#if 0
+ nlp = (struct nlist *)addr;
+#endif
+ printf("+[%x+", x.a_syms);
+ if (read(io, addr, x.a_syms) != x.a_syms)
+ goto shread;
+ addr += x.a_syms;
+#if 0
+ enlp = (struct nlist *)(strtab = addr);
+#endif
+
+ if (read(io, &strtablen, sizeof(int)) != sizeof(int))
+ goto shread;
+
+ bcopy(&strtablen, addr, sizeof(int));
+ if (i = strtablen) {
+ i -= sizeof(int);
+ addr += sizeof(int);
+ cnt = read(io, addr, i);
+ if (cnt != i)
+ printf("symwarn"); /* goto shread; */
+ addr += i;
+ }
+ printf("%x]", i);
+ esym = KERNBASE +
+ (((int)addr + sizeof(int) - 1) & ~(sizeof(int) - 1));
+ kernel.symtab = (void *) x.a_syms;
+ kernel.esym = addr;
+ } else {
+ kernel.symtab = 0;
+ kernel.esym = 0;
+ }
+
+#if 0
+ while (nlp < enlp) {
+ register int strx = nlp->n_un.n_strx;
+ if (strx > strtablen)
+ continue;
+ if (strcmp(strtab+strx, "_esym") == 0) {
+ *(int*)(nlp->n_value - KERNBASE) = esym;
+ break;
+ }
+ nlp++;
+ }
+#endif
+
+ kernel.bdev = 0;
+ kernel.end_loaded = (u_int)addr;
+ kernel.smini = 0;
+ kernel.emini = 0;
+ kernel.kname = 0;
+
+ printf("=%x\n", (u_int)addr - (u_int)entry); /* XXX wrong? */
+
+#if 0
+printf("entry %x\n",kernel.entry);
+printf("symtab %x\n",kernel.symtab);
+printf("esym %x\n",kernel.esym);
+printf("bflags %x\n",kernel.bflags);
+printf("bdev %x\n",kernel.bdev);
+printf("kname %x\n",kernel.kname);
+printf("smini %x\n",kernel.smini);
+printf("emini %x\n",kernel.emini);
+printf("end_loaded %x\n",kernel.end_loaded);
+#endif
+
+ printf("start at 0x%x\n", (int)entry);
+ if (((u_long)entry &0xf) == 0x2) {
+ (entry)(&bugargs, &kernel);
+ } else {
+ /* is type fixing anything like price fixing? */
+ typedef (* kernel_start) __P((int, int, void *,void *, void *));
+ kernel_start addr;
+ addr = (void *)entry;
+ (addr)(kernel.bflags, 0, kernel.esym, kernel.smini, kernel.emini);
+ }
+ return;
+
+shread:
+ printf("short read\n");
+}
+
+struct flags {
+ char c;
+ short bit;
+} bf[] = {
+ { 'a', RB_ASKNAME },
+ { 'b', RB_HALT },
+ { 'y', RB_NOSYM },
+ { 'd', RB_KDB },
+ { 'm', RB_MINIROOT },
+ { 'r', RB_DFLTROOT },
+ { 's', RB_SINGLE },
+};
+
+void
+parse_args()
+{
+ char *name = "/netbsd", *ptr;
+ int i, howto = 0;
+ char c;
+
+ if (bugargs.arg_start != bugargs.arg_end) {
+ ptr = bugargs.arg_start;
+ while (c = *ptr) {
+ while (c == ' ')
+ c = *++ptr;
+ if (c == '\0')
+ return;
+ if (c != '-') {
+ name = ptr;
+ while ((c = *++ptr) && c != ' ')
+ ;
+ if (c)
+ *ptr++ = 0;
+ continue;
+ }
+ while ((c = *++ptr) && c != ' ') {
+ for (i = 0; i < sizeof(bf)/sizeof(bf[0]); i++)
+ if (bf[i].c == c) {
+ howto |= bf[i].bit;
+ }
+ }
+ }
+ }
+ kernel.bflags = howto;
+ kernel.kname = name;
+}
--- /dev/null
+/* $Id: bugdev.c,v 1.1.1.1 1997/03/03 19:30:29 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1993 Paul Kranenburg
+ * 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 Paul Kranenburg.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include <machine/prom.h>
+#include "stand.h"
+
+int bugscopen __P((struct open_file *, ...));
+int bugscclose __P((struct open_file *));
+int bugscioctl __P((struct open_file *, u_long, void *));
+int bugscstrategy __P((void *, int, daddr_t, size_t, void *, size_t *));
+
+void cputobsdlabel __P((struct disklabel *lp, struct cpu_disklabel *clp));
+
+struct devsw devsw[] = {
+ { "bugsc", bugscstrategy, bugscopen, bugscclose, bugscioctl },
+};
+int ndevs = (sizeof(devsw)/sizeof(devsw[0]));
+
+extern struct mvmeprom_args bugargs;
+int errno;
+
+struct bugsc_softc {
+ int fd; /* Prom file descriptor */
+ int poff; /* Partition offset */
+ int psize; /* Partition size */
+ short ctrl;
+ short dev;
+} bugsc_softc[1];
+
+int
+devopen(f, fname, file)
+ struct open_file *f;
+ const char *fname;
+ char **file;
+{
+ register struct bugsc_softc *pp = &bugsc_softc[0];
+ int error, i, dn = 0, pn = 0;
+ char *dev, *cp;
+ static char iobuf[MAXBSIZE];
+ struct disklabel sdlabel;
+
+ dev = bugargs.arg_start;
+
+ /*
+ * Extract partition # from boot device string.
+ */
+ for (cp = dev; *cp; cp++) /* void */;
+ while (*cp != '/' && cp > dev) {
+ if (*cp == ':')
+ pn = *(cp+1) - 'a';
+ --cp;
+ }
+
+ pp->fd = bugscopen(f);
+
+ if (pp->fd < 0) {
+ printf("Can't open device `%s'\n", dev);
+ return (ENXIO);
+ }
+ error = bugscstrategy(pp, F_READ, LABELSECTOR, DEV_BSIZE, iobuf, &i);
+ if (error)
+ return (error);
+ if (i != DEV_BSIZE)
+ return (EINVAL);
+
+ cputobsdlabel(&sdlabel, (struct cpu_disklabel *)iobuf);
+ pp->poff = sdlabel.d_partitions[pn].p_offset;
+ pp->psize = sdlabel.d_partitions[pn].p_size;
+
+ f->f_dev = devsw;
+ f->f_devdata = (void *)pp;
+ *file = (char *)fname;
+ return (0);
+}
+
+/* silly block scale factor */
+#define BUG_BLOCK_SIZE 256
+#define BUG_SCALE (512/BUG_BLOCK_SIZE)
+int
+bugscstrategy(devdata, func, dblk, size, buf, rsize)
+ void *devdata;
+ int func;
+ daddr_t dblk;
+ size_t size;
+ void *buf;
+ size_t *rsize;
+{
+ struct mvmeprom_dskio dio;
+ register struct bugsc_softc *pp = (struct bugsc_softc *)devdata;
+ daddr_t blk = dblk + pp->poff;
+
+ twiddle();
+
+ dio.ctrl_lun = pp->ctrl;
+ dio.dev_lun = pp->dev;
+ dio.status = 0;
+ dio.pbuffer = buf;
+ dio.blk_num = blk * BUG_SCALE;
+ dio.blk_cnt = size / BUG_BLOCK_SIZE; /* assumed size in bytes */
+ dio.flag = 0;
+ dio.addr_mod = 0;
+#ifdef 0
+ printf("bugscstrategy: size=%d blk=%d buf=%x\n", size, blk, buf);
+ printf("ctrl %d dev %d\n", dio.ctrl_lun, dio.dev_lun);
+#endif
+ mvmeprom_diskrd(&dio);
+
+ *rsize = dio.blk_cnt * BUG_BLOCK_SIZE;
+#ifdef 0
+printf("rsize %d status %x\n", *rsize, dio.status);
+#endif
+
+ if (dio.status)
+ return (EIO);
+ return (0);
+}
+
+int
+bugscopen(f)
+ struct open_file *f;
+{
+#ifdef DEBUG
+ printf("bugscopen:\n");
+#endif
+
+ f->f_devdata = (void *)bugsc_softc;
+ bugsc_softc[0].ctrl = (short)bugargs.ctrl_lun;
+ bugsc_softc[0].dev = (short)bugargs.dev_lun;
+ printf("using mvmebug ctrl %d dev %d\n",
+ bugsc_softc[0].ctrl, bugsc_softc[0].dev);
+ return (0);
+}
+
+int
+bugscclose(f)
+ struct open_file *f;
+{
+ return (EIO);
+}
+
+int
+bugscioctl(f, cmd, data)
+ struct open_file *f;
+ u_long cmd;
+ void *data;
+{
+ return (EIO);
+}
+
+void
+cputobsdlabel(lp, clp)
+ struct disklabel *lp;
+ struct cpu_disklabel *clp;
+{
+ int i;
+
+ lp->d_magic = clp->magic1;
+ lp->d_type = clp->type;
+ lp->d_subtype = clp->subtype;
+ bcopy(clp->vid_vd, lp->d_typename, 16);
+ bcopy(clp->packname, lp->d_packname, 16);
+ lp->d_secsize = clp->cfg_psm;
+ lp->d_nsectors = clp->cfg_spt;
+ lp->d_ncylinders = clp->cfg_trk; /* trk is really num of cyl! */
+ lp->d_ntracks = clp->cfg_hds;
+
+ lp->d_secpercyl = clp->secpercyl;
+ lp->d_secperunit = clp->secperunit;
+ lp->d_secpercyl = clp->secpercyl;
+ lp->d_secperunit = clp->secperunit;
+ lp->d_sparespertrack = clp->sparespertrack;
+ lp->d_sparespercyl = clp->sparespercyl;
+ lp->d_acylinders = clp->acylinders;
+ lp->d_rpm = clp->rpm;
+ lp->d_interleave = clp->cfg_ilv;
+ lp->d_trackskew = clp->cfg_sof;
+ lp->d_cylskew = clp->cylskew;
+ lp->d_headswitch = clp->headswitch;
+
+ /* this silly table is for winchester drives */
+ switch (clp->cfg_ssr) {
+ case 0:
+ lp->d_trkseek = 0;
+ break;
+ case 1:
+ lp->d_trkseek = 6;
+ break;
+ case 2:
+ lp->d_trkseek = 10;
+ break;
+ case 3:
+ lp->d_trkseek = 15;
+ break;
+ case 4:
+ lp->d_trkseek = 20;
+ break;
+ default:
+ lp->d_trkseek = 0;
+ break;
+ }
+ lp->d_flags = clp->flags;
+ for (i = 0; i < NDDATA; i++)
+ lp->d_drivedata[i] = clp->drivedata[i];
+ for (i = 0; i < NSPARE; i++)
+ lp->d_spare[i] = clp->spare[i];
+ lp->d_magic2 = clp->magic2;
+ lp->d_checksum = clp->checksum;
+ lp->d_npartitions = clp->partitions;
+ lp->d_bbsize = clp->bbsize;
+ lp->d_sbsize = clp->sbsize;
+ bcopy(clp->vid_4, &(lp->d_partitions[0]), sizeof (struct partition) * 4);
+ bcopy(clp->cfg_4, &(lp->d_partitions[4]), sizeof (struct partition) * 12);
+}
--- /dev/null
+/* $Id: filesystem.c,v 1.1.1.1 1997/03/03 19:30:29 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1993 Philip A. Nelson.
+ * 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 Philip A. Nelson.
+ * 4. The name of Philip A. Nelson may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY PHILIP NELSON ``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 PHILIP NELSON 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 <stand.h>
+#include <ufs.h>
+
+struct fs_ops file_system[] = {
+ { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat },
+};
+
+int nfsys = sizeof(file_system)/sizeof(struct fs_ops);
+
--- /dev/null
+/* $Id: version.c,v 1.1.1.1 1997/03/03 19:30:29 rahnds Exp $ */
+
+/*
+ * make a random change to this file when you want the bootblock
+ * revision to increase. like change this x to a y, or something.
+ */
+
+char *version = "$Revision: 1.1.1.1 $";
--- /dev/null
+# from: @(#)Makefile 8.1 (Berkeley) 6/10/93
+# $Id: Makefile,v 1.1.1.1 1997/03/03 19:30:30 rahnds Exp $
+
+RELOC=0x3F0000
+
+S= ${.CURDIR}/../../../..
+DEFS= -DSTANDALONE -DCOMPAT_NOLABEL # -DROMPRF
+INCPATH=-I${.CURDIR} -I${.CURDIR}/../../include -I${S} -I${S}/lib/libsa
+CFLAGS= -O2 ${INCPATH} ${DEFS} ${COPTS}
+CLEANFILES+=sdboot bootst bootst.bug
+
+#.PATH: ${S}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
+#.PATH: ${S}/lib/libsa
+
+.include "${S}/arch/${MACHINE}/stand/libsa/Makefile.inc"
+.include "${S}/arch/${MACHINE}/stand/libbug/Makefile.inc"
+.include "${S}/arch/${MACHINE}/stand/bugcrt/Makefile.inc"
+.include "${S}/arch/${MACHINE}/stand/wrtvid/Makefile.inc"
+
+SRCS= bootst.c
+
+LIBS= ${LIBSA} ${LIBBUG}
+
+OBJS= ${SRCS:N*.h:R:S/$/.o/g}
+
+BOOTS= bootst stboot
+ALL= ${BOOTS}
+
+all: ${ALL}
+
+bootst.bug: ${OBJS} ${BUGCRT} ${LIBS}
+ ${LD} -s -N -T ${RELOC} ${BUGCRT} ${OBJS} ${LIBS} -o $@
+ @size bootst.bug
+
+bootst stboot: bootst.bug ${WRTVID}
+ ${WRTVID} bootst.bug
+
+install:
+ install -c -m 555 -g bin -o bin ${BOOTS} ${DESTDIR}${MDEC_DIR}
+
+.include <bsd.prog.mk>
--- /dev/null
+#include "bug.h"
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/exec.h>
+/*
+#include <sys/exec_aout.h>
+*/
+
+#define KERNEL_LOAD_ADDRESS ((void *)0x4000)
+#define BUG_BLOCK_SIZE 512
+#define VERSION 0x0000
+
+#define RB_NOSYM 0x400
+
+
+
+void memset(void *,char,size_t);
+void printf(char *,...);
+void parse_args(struct bugargs *pbugargs);
+int read_tape_block(short ctrl, short dev, short *status, void *addr,
+ int *cnt, int blk_num, unsigned char *flags,int verbose);
+int load_kern();
+
+struct kernel {
+ void *entry;
+ void *symtab;
+ void *esym;
+ int bflags;
+ int bdev;
+ char *kname;
+ void *smini;
+ void *emini;
+ u_int end_loaded;
+} kernel;
+
+typedef (* kernel_entry)(struct bugargs *,struct kernel *);
+
+void main(struct bugargs *pbugargs)
+{
+ kernel_entry addr;
+
+ /*
+ print_bugargs(pbugargs);
+ print_time();
+ print_brdid();
+ print_memory();
+ */
+ parse_args(pbugargs);
+ if (1 == load_kern(pbugargs)) {
+ printf("unsuccessful in loading kernel\n\r");
+ } else {
+ addr = kernel.entry;
+ printf("kernel loaded at %x\n\r",addr);
+ printf("kernel.entry %x\n\r",kernel.entry);
+ printf("kernel.symtab %x\n\r",kernel.symtab);
+ printf("kernel.esym %x\n\r",kernel.esym);
+ printf("kernel.bflags %x\n\r",kernel.bflags);
+ printf("kernel.bdev %x\n\r",kernel.bdev);
+ if (kernel.kname) {
+ printf("kernel.kname <%s>\n\r",kernel.kname);
+ } else {
+ printf("kernel.kname <null>\n\r");
+ }
+ printf("kernel.end_loaded %x\n\r",kernel.end_loaded);
+
+ if (kernel.bflags & RB_MINIROOT) {
+ loadmini(kernel.end_loaded,pbugargs);
+ }
+
+ printf("kernel.smini %x\n\r",kernel.smini);
+ printf("kernel.emini %x\n\r",kernel.emini);
+ printf("kernel.end_loaded %x\n\r",kernel.end_loaded);
+ if (kernel.bflags & RB_HALT)
+ bug_return();
+ (addr)(pbugargs,&kernel);
+ }
+
+ return;
+}
+#define BUG_SCALE (512/BUG_BLOCK_SIZE)
+int
+read_tape_block(short ctrl, short dev, short *status, void *addr,
+ int *cnt, int blk_num, unsigned char *flags,int verbose)
+{
+ struct bug_dskio dio;
+ int ret;
+ int len, len1;
+
+ len = *cnt;
+ do {
+ if (len > 16 * 1024) {
+ len1 = 16 * 1024;
+ }else{
+ len1 = len;
+ }
+ dio.ctrl_lun = ctrl;
+ dio.dev_lun = dev;
+ dio.status = *status;
+ dio.pbuffer = addr;
+ dio.blk_num = blk_num;
+ dio.blk_cnt = len1 /(512/BUG_SCALE);
+ dio.flag = *flags;
+ dio.addr_mod = 0;
+
+ if (verbose){
+ printf("saddr %x eaddr %x", dio.pbuffer,
+ (int)dio.pbuffer + (dio.blk_cnt * BUG_BLOCK_SIZE));
+ }
+
+ ret = bug_diskrd(&dio);
+
+ *status = dio.status;
+ *cnt += (dio.blk_cnt/BUG_SCALE)*512;
+ if (verbose) {
+ printf("status %x ret %d ",*status, ret);
+ printf("flags %x\n\r",*flags);
+ }
+ len -= len1;
+ addr += len1;
+ blk_num += len1 /(512/BUG_SCALE);
+ } while (len > 0);
+ return ret;
+}
+int verbose = 1;
+int
+load_kern(struct bugargs *pbugargs)
+{
+ int ret;
+ char *addr;
+ unsigned char flags;
+ short status = 0;
+ int blk_num;
+ struct exec *pexec;
+ int magic;
+ int *esym;
+ int *symtab;
+ int cnt, len;
+ char buf[512];
+
+ blk_num = 2;
+ /* flags = IGNORE_FILENUM ; */
+ flags = 0;
+ cnt = 512 ;
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, &status, buf,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0) {
+ printf("unable to load kernel 1\n\r");
+ return 1;
+ }
+ pexec = (struct exec *) buf;
+ if ((N_GETMID(*pexec) != MID_M68K) &&
+ ( N_GETMID(*pexec) != MID_M68K4K ))
+ {
+ printf("invalid mid on kernel\n\r");
+ return 1;
+ }
+ {
+ short *pversion = (void *)(KERNEL_LOAD_ADDRESS+0x20);
+ if (VERSION != *pversion) {
+ printf("invalid version of kernel/loader\n\r");
+ bug_return();
+ }
+ }
+ magic = N_GETMAGIC(*pexec);
+ switch (magic) {
+ case ZMAGIC:
+ break;
+ case NMAGIC:
+ printf ("NMAGIC not yet supported");
+ case OMAGIC:
+ case QMAGIC:
+ default:
+ printf("Unknown or unsupported magic type <%x>\n\r",
+ magic);
+ return 1;
+ break;
+ }
+ if ( magic == ZMAGIC ) {
+
+ status = 0;
+ addr = pexec->a_entry & ~0x0FFF;
+ bcopy(&buf, addr, 512);
+ /* 2nd block of exe */
+ addr += 512;
+
+ if ((int)pexec->a_entry != (int)KERNEL_LOAD_ADDRESS + 0x22) {
+ printf ("warning kernel start address not %x, %x\n\r",
+ (int)KERNEL_LOAD_ADDRESS + 0x22,pexec->a_entry);
+ printf ("kernel loaded at %x\n\r",KERNEL_LOAD_ADDRESS);
+
+ }
+ printf ("text 0x%x data 0x%x bss 0x%x\n\r",
+ pexec->a_text, pexec->a_data, pexec->a_bss);
+
+ len = (pexec->a_text - 512) ; /* XXX */
+ len += (pexec->a_data );
+
+ printf ("loading [ %x + %x ",pexec->a_text,pexec->a_data);
+
+ cnt = len;
+ flags = IGNORE_FILENUM ;
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun,
+ &status, addr, &cnt, blk_num, &flags, verbose);
+ if (ret != 0 || cnt != len) {
+ printf("unable to load kernel 2\n\r");
+ return 1;
+ }
+ addr += len;
+
+ /* Skip over text and data and zero bss. */
+ len = pexec->a_bss;
+ printf ("+ %x",len);
+ memset (KERNEL_LOAD_ADDRESS + (pexec->a_text + pexec->a_data),
+ 0, pexec->a_bss);
+ addr +=len;
+
+ if (pexec->a_syms != 0 && !(kernel.bflags & RB_NOSYM)) {
+ printf (" + [ %x",pexec->a_syms);
+ addr += 4; /* skip over _end symbol */
+ symtab = (void *)pexec->a_syms;
+ len = pexec->a_syms;
+ cnt = len;
+ flags = IGNORE_FILENUM ;
+ ret = read_tape_block(pbugargs->ctrl_lun,
+ pbugargs->dev_lun, &status, addr,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0 || cnt != len)
+ {
+ printf("unable to load kernel 3\n\r");
+ return 1;
+ }
+
+ /* this value should have already been loaded XXX */
+ esym = (void *) ((u_int)addr + pexec->a_syms);
+ if ((int)addr +cnt <= (int) esym) {
+ printf("missed loading count of symbols\n\r");
+ return 1;
+ }
+ addr +=cnt ;
+
+
+ len = *esym;
+#if 0
+ printf("start load %x end load %x %x\n\r", addr,
+ len, addr +len);
+ printf("esym %x *esym %x\n\r",esym, len);
+#endif
+ /* dont load tail of already loaded */
+ len -= (u_int)addr - (u_int)esym;
+
+ if (len > 0) {
+ printf(" + %x",*esym);
+ esym = (void *)(addr + len);
+ cnt = len;
+ flags = IGNORE_FILENUM ;
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, &status, addr,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0 || cnt != len)
+ {
+ printf("unable to load kernel 4\n\r");
+ return 1;
+ }
+ addr += len;
+ printf(" ]");
+ } else {
+ printf("+ %x ]",*esym);
+ }
+ esym = (int *)(((int)esym) + *esym);
+
+ kernel.symtab = symtab;
+ kernel.esym = esym;
+ } else {
+ kernel.symtab = 0;
+ kernel.esym = 0;
+ }
+ kernel.end_loaded = (int)addr;
+ flags = IGNORE_FILENUM | END_OF_FILE;
+ cnt = 8192;
+ printf ("removing pad [");
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, &status, addr,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0) {
+ printf("unable to load kernel 5\n\r");
+ return 1;
+ }
+ printf (" %d ]",cnt);
+
+ printf("]\n\r");
+ }
+
+
+ kernel.entry = (void *)pexec->a_entry;
+ return 0;
+}
+loadmini(u_int addr,struct bugargs *pbugargs)
+{
+ int ret;
+ unsigned char flags;
+ short status = 0;
+ int verbose = 0;
+ int blk_num;
+ int cnt;
+ blk_num = 3;
+ /* align addr to some boundary */
+#define ALIGN_F 0x4
+ addr = (u_int)((((int)addr + ALIGN_F -1)/ALIGN_F) * ALIGN_F);
+#undef ALIGN_F
+ flags = END_OF_FILE;
+ cnt = 6144 * 512 ; /* some abserdly large value. (3meg) */
+ printf("loading miniroot[ ");
+ ret = read_tape_block(4, pbugargs->dev_lun, &status, (void*)addr,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0) {
+ printf("unable to load miniroot\n\r");
+ return 1;
+ }
+ kernel.smini = (void *)addr;
+ printf("%d ]\n\r",(BUG_BLOCK_SIZE * cnt));
+ kernel.emini = (void*)((u_int)addr + (BUG_BLOCK_SIZE * cnt));
+ kernel.end_loaded = (u_int)kernel.emini;
+}
+void
+parse_args(struct bugargs *pargs)
+{
+ char * ptr = pargs->arg_start;
+ char c, *name;
+ int howto;
+ howto = ( 0 | RB_DFLTROOT );
+ name = NULL;
+
+ if (pargs->arg_start != pargs->arg_end) {
+ while (c = *ptr) {
+ while (c == ' ')
+ c = *++ptr;
+ if (!c)
+ return;
+ if (c == '-')
+ while ((c = *++ptr) && c != ' ') {
+ if (c == 'a')
+ howto |= RB_ASKNAME;
+ else if (c == 'b')
+ howto |= RB_HALT;
+ else if (c == 'y')
+ howto |= RB_NOSYM;
+#ifdef CHECKSUM
+ else if (c == 'c')
+ cflag = 1;
+#endif
+ else if (c == 'd')
+ howto |= RB_KDB;
+ else if (c == 'm')
+ howto |= RB_MINIROOT;
+ else if (c == 'r')
+/* change logic to have force root to config device UNLESS arg given */
+ howto &= ~RB_DFLTROOT;
+ else if (c == 's')
+ howto |= RB_SINGLE;
+ }
+ else {
+ name = ptr;
+ while ((c = *++ptr) && c != ' ');
+ if (c)
+ *ptr++ = 0;
+ }
+ }
+ if (RB_NOSYM & howto) printf("RB_NOSYM\n\r");
+ if (RB_AUTOBOOT & howto) printf("RB_AUTOBOOT\n\r");
+ if (RB_SINGLE & howto) printf("RB_SINGLE\n\r");
+ if (RB_NOSYNC & howto) printf("RB_NOSYNC\n\r");
+ if (RB_HALT & howto) printf("RB_HALT\n\r");
+ if (RB_DFLTROOT & howto) printf("RB_DFLTROOT\n\r");
+ if (RB_KDB & howto) printf("RB_KDB\n\r");
+ if (RB_RDONLY & howto) printf("RB_RDONLY\n\r");
+ if (RB_DUMP & howto) printf("RB_DUMP\n\r");
+ if (RB_MINIROOT & howto) printf("RB_MINIROOT\n\r");
+
+ }
+ kernel.bflags = howto;
+ kernel.kname = name;
+}
+
--- /dev/null
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/exec.h>
+#include <machine/prom.h>
+
+#define RB_NOSYM 0x400
+
+void parse_args __P((struct mvmeprom_args *pbugargs));
+int load_kern();
+int read_tape_block __P((short ctrl, short dev, short *status,
+ void *addr, int *cnt, int blk_num, u_char *flags, int verbose));
+
+struct kernel {
+ void *entry;
+ void *symtab;
+ void *esym;
+ int bflags;
+ int bdev;
+ char *kname;
+ void *smini;
+ void *emini;
+ u_int end_loaded;
+} kernel;
+
+typedef(*kernel_entry) __P((struct mvmeprom_args *, struct kernel *));
+
+int
+main(pbugargs)
+ struct mvmeprom_args *pbugargs;
+{
+ kernel_entry addr;
+
+ /*
+ print_bugargs(pbugargs);
+ print_time();
+ print_brdid();
+ print_memory();
+ */
+ parse_args(pbugargs);
+ if (load_kern(pbugargs) == 1) {
+ printf("unsuccessful in loading kernel\n");
+ } else {
+ addr = kernel.entry;
+
+ printf("kernel loaded at %x\n", addr);
+ printf("kernel.entry %x\n", kernel.entry);
+ printf("kernel.symtab %x\n", kernel.symtab);
+ printf("kernel.esym %x\n", kernel.esym);
+ printf("kernel.bflags %x\n", kernel.bflags);
+ printf("kernel.bdev %x\n", kernel.bdev);
+ if (kernel.kname)
+ printf("kernel.kname <%s>\n", kernel.kname);
+ else
+ printf("kernel.kname <null>\n");
+ printf("kernel.end_loaded %x\n", kernel.end_loaded);
+
+ if (kernel.bflags & RB_MINIROOT)
+ loadmini(kernel.end_loaded, pbugargs);
+
+ printf("kernel.smini %x\n", kernel.smini);
+ printf("kernel.emini %x\n", kernel.emini);
+ printf("kernel.end_loaded %x\n", kernel.end_loaded);
+ if (kernel.bflags & RB_HALT)
+ mvmeprom_return();
+ if (((u_long)addr &0xf) == 0x2) {
+ (addr)(pbugargs, &kernel);
+ } else {
+ /* is type fixing anything like price fixing? */
+ typedef (* kernel_start) __P((int, int, void *,void *, void *));
+ kernel_start addr1;
+ addr1 = (void *)addr;
+ (addr1)(kernel.bflags, 0, kernel.esym, kernel.smini, kernel.emini
+ );
+ }
+
+ }
+ return (0);
+}
+
+#define MVMEPROM_SCALE (512/MVMEPROM_BLOCK_SIZE)
+
+int
+read_tape_block(ctrl, dev, status, addr, cnt, blk_num, flags, verbose)
+ short ctrl;
+ short dev;
+ short *status;
+ void *addr;
+ int *cnt;
+ int blk_num;
+ u_char *flags;
+ int verbose;
+{
+ struct mvmeprom_dskio dio;
+ int ret;
+
+ dio.ctrl_lun = ctrl;
+ dio.dev_lun = dev;
+ dio.status = *status;
+ dio.pbuffer = addr;
+ dio.blk_num = blk_num;
+ dio.blk_cnt = *cnt / (512 / MVMEPROM_SCALE);
+ dio.flag = *flags;
+ dio.addr_mod = 0;
+
+ if (verbose)
+ printf("saddr %x eaddr %x", dio.pbuffer,
+ (int) dio.pbuffer + (dio.blk_cnt * MVMEPROM_BLOCK_SIZE));
+ ret = mvmeprom_diskrd(&dio);
+
+ *status = dio.status;
+ *cnt = (dio.blk_cnt / MVMEPROM_SCALE) * 512;
+ if (verbose) {
+ printf("status %x ret %d ", *status, ret);
+ printf("flags %x blocks read %x cnt %x\n",
+ *flags, dio.blk_cnt, *cnt);
+ }
+ return (ret);
+}
+#ifdef DEBUG
+int verbose = 1;
+#else
+int verbose = 0;
+#endif
+
+int
+load_kern(pbugargs)
+ struct mvmeprom_args *pbugargs;
+{
+ int ret;
+ char *addr;
+ u_char flags;
+ short status = 0;
+ int blk_num;
+ struct exec *pexec;
+ int magic;
+ int *esym;
+ int *symtab;
+ int cnt, len;
+ char buf[512];
+
+ blk_num = 2;
+ /* flags = IGNORE_FILENUM; */
+ flags = 0;
+ cnt = 512;
+printf("ctrl %x dev %x\n",pbugargs->ctrl_lun, pbugargs->dev_lun);
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, &status,
+ buf, &cnt, blk_num, &flags, verbose);
+ if (ret != 0) {
+ printf("unable to load kernel 1 status %x\n", status);
+ return (1);
+ }
+ pexec = (struct exec *) buf;
+ if (N_GETMID(*pexec) != MID_M68K &&
+ N_GETMID(*pexec) != MID_M68K4K) {
+ printf("invalid mid on kernel\n");
+ return (1);
+ }
+
+ magic = N_GETMAGIC(*pexec);
+ switch (magic) {
+ case ZMAGIC:
+ break;
+ case NMAGIC:
+ printf("NMAGIC not yet supported");
+ case OMAGIC:
+ case QMAGIC:
+ default:
+ printf("Unknown or unsupported magic type <%x>\n", magic);
+ return (1);
+ }
+ if (magic == ZMAGIC) {
+ status = 0;
+ addr = (char *) (pexec->a_entry & ~0x0FFF);
+
+ if ((int) pexec->a_entry != (int) addr + 0x22) {
+ printf("warning kernel start address not %x, %x\n",
+ (int) addr + 0x22, pexec->a_entry);
+ printf("kernel loaded at %x\n", addr);
+ }
+ bcopy(&buf, addr, 512);
+ /* 2nd block of exe */
+ addr += 512;
+
+ printf("text 0x%x data 0x%x bss 0x%x\n",
+ pexec->a_text, pexec->a_data, pexec->a_bss);
+
+ len = (pexec->a_text - 512); /* XXX */
+ len += (pexec->a_data);
+
+ printf("loading [ %x + %x ", pexec->a_text, pexec->a_data);
+
+ cnt = len;
+ flags = IGNORE_FILENUM;
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun,
+ &status, addr, &cnt, blk_num, &flags, verbose);
+ if (ret != 0 || cnt != len) {
+ printf("unable to load kernel 2 status %x\n", status);
+ return 1;
+ }
+ addr += len;
+
+ /* Skip over text and data and zero bss. */
+ len = pexec->a_bss;
+ printf("+ %x", len);
+#ifdef DEBUG
+ printf("bss %x - %x\n", addr, addr + pexec->a_bss);
+#endif
+ bzero(addr, pexec->a_bss);
+ addr += len;
+
+ if (pexec->a_syms != 0 && !(kernel.bflags & RB_NOSYM)) {
+ printf(" + [ %x", pexec->a_syms);
+ addr += 4; /* skip over _end symbol */
+ symtab = (void *) pexec->a_syms;
+ len = pexec->a_syms;
+ cnt = ((len + (512 - 1)) / 512) * 512;
+ flags = IGNORE_FILENUM;
+ ret = read_tape_block(pbugargs->ctrl_lun,
+ pbugargs->dev_lun, &status, addr,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0 || cnt != ((len + (512 - 1)) / 512) * 512) {
+ printf("unable to load kernel 3\n");
+ return 1;
+ }
+ /* this value should have already been loaded XXX */
+ esym = (void *) ((u_int) addr + pexec->a_syms);
+ if ((int) addr + cnt <= (int) esym) {
+ printf("missed loading count of symbols\n");
+ return 1;
+ }
+ addr += cnt;
+
+
+ len = *esym;
+#if 0
+ printf("start load %x end load %x %x\n", addr,
+ len, addr + len);
+ printf("esym %x *esym %x\n", esym, len);
+#endif
+ /* dont load tail of already loaded */
+ len -= (u_int) addr - (u_int) esym;
+
+ if (len > 0) {
+ printf(" + %x", *esym);
+ esym = (void *) (addr + len);
+ cnt = ((len + (512 - 1)) / 512) * 512;
+ flags = IGNORE_FILENUM;
+ ret = read_tape_block(pbugargs->ctrl_lun,
+ pbugargs->dev_lun, &status, addr,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0 || cnt != ((len + (512-1)) / 512)*512) {
+ printf("unable to load kernel 4\n");
+ return (1);
+ }
+ addr += len;
+ printf(" ]");
+ } else {
+ printf("+ %x ]", *esym);
+ }
+ esym = (int *) (((int) esym) + *esym);
+
+ kernel.symtab = symtab;
+ kernel.esym = esym;
+ } else {
+ kernel.symtab = 0;
+ kernel.esym = 0;
+ }
+ kernel.end_loaded = (int) addr;
+ flags = IGNORE_FILENUM | END_OF_FILE;
+ cnt = 8192;
+ printf("removing pad [");
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun,
+ &status, addr, &cnt, blk_num, &flags, verbose);
+ if (ret != 0) {
+ printf("unable to load kernel 5\n");
+ return (1);
+ }
+ printf(" %d ]", cnt);
+
+ printf("]\n");
+ }
+ kernel.entry = (void *) pexec->a_entry;
+ return (0);
+}
+
+int
+loadmini(addr, pbugargs)
+ u_int addr;
+ struct mvmeprom_args *pbugargs;
+{
+ int cnt, ret, blk_num = 3;
+ short status = 0;
+ u_char flags;
+
+ /* align addr to some boundary */
+#define ALIGN_F 0x4
+ addr = (u_int) ((((int) addr + ALIGN_F - 1) / ALIGN_F) * ALIGN_F);
+#undef ALIGN_F
+ flags = END_OF_FILE;
+ cnt = 6144 * 512; /* some abserdly large value. (3meg) */
+ printf("loading miniroot[ ");
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun,
+ &status, (void *) addr, &cnt, blk_num, &flags, verbose);
+ if (ret != 0) {
+ printf("unable to load miniroot\n");
+ return (1);
+ }
+ kernel.smini = (void *)addr;
+ printf("%d ]\n", cnt);
+ kernel.emini = (void *) ((u_int) addr + cnt);
+ kernel.end_loaded = (u_int) kernel.emini;
+ return (0);
+}
+
+void
+parse_args(pargs)
+ struct mvmeprom_args *pargs;
+{
+ char *ptr = pargs->arg_start;
+ char c, *name = NULL;
+ int howto = 0;
+
+ if (pargs->arg_start != pargs->arg_end) {
+ while (c = *ptr) {
+ while (c == ' ')
+ c = *++ptr;
+ if (!c)
+ return;
+ if (c != '-') {
+ name = ptr;
+ while ((c = *++ptr) && c != ' ');
+ if (c)
+ *ptr++ = 0;
+ continue;
+ }
+ while ((c = *++ptr) && c != ' ') {
+ if (c == 'a')
+ howto |= RB_ASKNAME;
+ else if (c == 'b')
+ howto |= RB_HALT;
+ else if (c == 'y')
+ howto |= RB_NOSYM;
+ else if (c == 'd')
+ howto |= RB_KDB;
+ else if (c == 'm')
+ howto |= RB_MINIROOT;
+ else if (c == 'r')
+ howto |= RB_DFLTROOT;
+ else if (c == 's')
+ howto |= RB_SINGLE;
+ }
+ }
+ }
+ kernel.bflags = howto;
+ kernel.kname = name;
+}
--- /dev/null
+BUG_CRT_DIR=${S}/arch/${MACHINE}/stand/bugcrt
+
+BUGCRT_DIR!= cd ${BUG_CRT_DIR}; \
+ printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx
+
+BUGCRT=${BUGCRT_DIR}/bugcrt.o
+
+$(BUGCRT): .NOTMAIN __always_make_bugcrt
+ @echo making sure the bugcrt is up to date...
+ @(cd ${BUG_CRT_DIR}; ${MAKE})
+
+__always_make_bugcrt: .NOTMAIN
--- /dev/null
+#include <sys/types.h>
+#include <machine/prom.h>
+
+struct mvmeprom_args bugargs = { 1 }; /* not BSS */
+
+ asm (".text");
+ asm (".long 0x003ffff8");
+ asm (".long _start");
+start()
+{
+ register int dev_lun asm ("r2");
+ register int ctrl_lun asm ("r3");
+ register int flags asm ("r4");
+ register int ctrl_addr asm ("r5");
+ register int entry asm ("r6");
+ register int conf_blk asm ("r7");
+ register char *arg_start asm ("r8");
+ register char *arg_end asm ("r9");
+ extern int edata, end;
+
+asm ("# enable SFU1");
+asm (" ldcr r10,cr1");
+asm (" xor r10,r10,0x8");
+asm (" stcr r10,cr1");
+
+ bugargs.dev_lun = dev_lun;
+ bugargs.ctrl_lun = ctrl_lun;
+ bugargs.flags = flags;
+ bugargs.ctrl_addr = ctrl_addr;
+ bugargs.entry = entry;
+ bugargs.conf_blk = conf_blk;
+ bugargs.arg_start = arg_start;
+ bugargs.arg_end = arg_end;
+ *arg_end = 0;
+
+ bzero(&edata, (int)&end - (int)&edata);
+ main();
+ mvmeprom_return();
+ /* NOTREACHED */
+}
+
+__main()
+{
+}
--- /dev/null
+LIB_BUG_DIR=${S}/arch/${MACHINE}/stand/libbug
+
+LIBBUG_DIR!= cd ${LIB_BUG_DIR}; \
+ printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx
+
+LIBBUG=${LIBBUG_DIR}/libbug.a
+
+$(LIBBUG): .NOTMAIN __always_make_libbug
+ @echo making sure the libbug is up to date...
+ @(cd ${LIB_BUG_DIR}; ${MAKE})
+
+__always_make_libbug: .NOTMAIN
--- /dev/null
+delay.o delay.o
+diskrd.o diskrd.o
+diskwr.o diskwr.o
+getbrdid.o getbrdid.o
+instat.o instat.o
+outln.o outln.o
+outstr.o outstr.o
+return.o return.o
+rtc_rd.o rtc_rd.o
--- /dev/null
+rtc_rd.o
+return.o
+outstr.o
+outln.o
+instat.o
+getbrdid.o
+diskwr.o
+diskrd.o
+delay.o
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* BUG - timing routine */
+void
+mvmeprom_delay(msec)
+ int msec;
+{
+ asm volatile ("or r2,r0,%0": : "r" (msec));
+ MVMEPROM_CALL(MVMEPROM_DELAY);
+}
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_diskrd(arg)
+ struct mvmeprom_dskio *arg;
+{
+ int ret;
+
+ asm volatile ("or r2,r0,%0": : "r" (arg));
+ MVMEPROM_CALL(MVMEPROM_DSKRD);
+ asm volatile ("or %0,r0,r2" : "=r" (ret));
+ return (!(ret & 0x4));
+}
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_diskwr(arg)
+ struct mvmeprom_dskio *arg;
+{
+ int ret;
+
+ asm volatile ("or r2,r0,%0": : "r" (arg) );
+ MVMEPROM_CALL(MVMEPROM_DSKWR);
+ asm volatile ("or %0,r0,r2" : "=r" (ret));
+ return (!(ret & 0x4));
+}
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* BUG - query board routines */
+struct mvmeprom_brdid *
+mvmeprom_brdid()
+{
+ struct mvmeprom_brdid *id;
+
+ MVMEPROM_CALL(MVMEPROM_GETBRDID);
+ asm volatile ("or %0,r0,r2": "=r" (id):);
+ return (id);
+}
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* returns 0 if no characters ready to read */
+int
+mvmeprom_instat()
+{
+ short ret;
+
+ MVMEPROM_CALL(MVMEPROM_INSTAT);
+ asm volatile ("or %0,r0,r2" : "=r" (ret));
+ return (!(ret & 0x4));
+}
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+void
+mvmeprom_outchr(a)
+ char a;
+{
+ asm volatile ("or r2, r0, %0" : :"r" (a));
+ BUG_CALL(_OUTCHR);
+}
+
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+void
+mvmeprom_outln(start, end)
+ char *start, *end;
+{
+ asm volatile ("or r2,r0,%0": : "r" (start));
+ asm volatile ("or r3,r0,%0": : "r" (end));
+ MVMEPROM_CALL(MVMEPROM_OUTSTRCRLF);
+}
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+void
+mvmeprom_outstr(start, end)
+ char *start, *end;
+{
+ asm volatile ("or r2,r0,%0": : "r" (start));
+ asm volatile ("or r3,r0,%0": : "r" (end));
+ MVMEPROM_CALL(MVMEPROM_OUTSTR);
+}
--- /dev/null
+#define MVMEPROM_CALL(x) \
+ asm volatile ( __CONCAT("or r9,r0," __STRING(x)) ); \
+ asm volatile ("tb0 0,r0,496");
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* BUG - return to bug routine */
+void
+mvmeprom_return()
+{
+ MVMEPROM_CALL(MVMEPROM_EXIT);
+ /*NOTREACHED*/
+}
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+void
+mvmeprom_rtc_rd(ptime)
+ struct mvmeprom_time *ptime;
+{
+ asm volatile ("or r2,r0,%0": : "r" (ptime));
+ MVMEPROM_CALL(MVMEPROM_RTC_RD);
+}
--- /dev/null
+# $Id: Makefile,v 1.1.1.1 1997/03/03 19:30:35 rahnds Exp $
+
+LIB=sa
+
+CLEANFILES+=SRT0.o SRT1.o
+
+NOPIC=nopic
+NOPROFILE=noprofile
+
+# Logically src/sys
+S=${.CURDIR}/../../../..
+DIR_SA=$S/lib/libsa
+DIR_KERN=$S/lib/libkern
+
+SRC_net= nfs.c rpc.c net.c ether.c arp.c in_cksum.c netif.c \
+ bootparam.c rarp.c
+
+
+#SRC_sa = alloc.c bcopy.c memcpy.c close.c getfile.c open.c \
+# printf.c read.c strerror.c ufs.c globals.c lseek.c \
+# closeall.c dev.c dkcksum.c nullfs.c fstat.c
+
+SRC_sa = alloc.c bcopy.c close.c getfile.c open.c \
+ printf.c read.c strerror.c ufs.c globals.c lseek.c \
+ dev.c
+
+SRC_kern= ashrdi3.c bcmp.c bzero.c strcmp.c strlen.c
+
+SRC_here= clock.c devopen.c dvma.c \
+ gets.c panic.c \
+ promboot.c promcons.c
+
+SRCS= ${SRC_net} ${SRC_sa} ${SRC_kern} ${SRC_here}
+
+# DBG= -DDEBUG -DNETIF_DEBUG -DNFS_DEBUG -DRPC_DEBUG \
+# -DNET_DEBUG -DRARP_DEBUG -DETHER_DEBUG
+
+#DEFS= -DCOMPAT_UFS
+INCL= -I. -I${S}/lib/libsa -I${S}
+COPTS= #-fno-defer-pop
+CFLAGS= ${COPTS} ${DEFS} ${DBG} ${INCL}
+
+.PATH: ${DIR_SA} ${DIR_KERN} ../../sun3
+
+all: libsa.a SRT0.o SRT1.o
+
+install:
+
+.include <bsd.lib.mk>
--- /dev/null
+head 1.1;
+access;
+symbols;
+locks
+ build:1.1; strict;
+comment @# @;
+
+
+1.1
+date 96.02.03.01.43.48; author build; state Exp;
+branches;
+next ;
+
+
+desc
+@back up
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@# $Id: Makefile,v,v 1.1.1.1 1997/03/03 19:30:37 rahnds Exp $
+
+LIB=sa
+
+CLEANFILES+=SRT0.o SRT1.o
+
+NOPIC=nopic
+NOPROFILE=noprofile
+
+# Logically src/sys
+S=${.CURDIR}/../../../..
+DIR_SA=$S/lib/libsa
+DIR_KERN=$S/lib/libkern
+
+SRC_net= nfs.c rpc.c net.c ether.c arp.c in_cksum.c netif.c \
+ bootparam.c rarp.c
+
+
+SRC_sa = alloc.c bcopy.c memcpy.c close.c getfile.c open.c \
+ printf.c read.c strerror.c ufs.c globals.c lseek.c \
+ closeall.c dev.c dkcksum.c nullfs.c fstat.c
+
+SRC_kern= ashrdi3.c bcmp.c bzero.c strcmp.c strlen.c
+
+SRC_sun3= exec_sun.c
+
+SRC_here= clock.c devopen.c dvma.c \
+ gets.c panic.c \
+ promboot.c promcons.c
+
+SRCS= ${SRC_net} ${SRC_sa} ${SRC_kern} ${SRC_sun3} ${SRC_here}
+
+# DBG= -DDEBUG -DNETIF_DEBUG -DNFS_DEBUG -DRPC_DEBUG \
+# -DNET_DEBUG -DRARP_DEBUG -DETHER_DEBUG
+
+#DEFS= -DCOMPAT_UFS
+INCL= -I. -I${S}/lib/libsa -I${S}
+COPTS= #-fno-defer-pop
+CFLAGS= -O2 ${COPTS} ${DEFS} ${DBG} ${INCL}
+
+.PATH: ${DIR_SA} ${DIR_KERN} ../../sun3
+
+all: libsa.a SRT0.o SRT1.o
+
+install:
+
+.include <bsd.lib.mk>
+@
--- /dev/null
+LIB_SA_DIR=${S}/arch/${MACHINE}/stand/libsa
+
+LIBSA_DIR!= cd ${LIB_SA_DIR}; \
+ printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx
+
+LIBSA=${LIBSA_DIR}/libsa.a
+
+$(LIBSA): .NOTMAIN __always_make_libsa
+ @echo making sure the libsa is up to date...
+ @(cd ${LIB_SA_DIR}; ${MAKE})
+
+__always_make_libsa: .NOTMAIN
--- /dev/null
+| $Id: SRT0.S,v 1.1.1.1 1997/03/03 19:30:35 rahnds Exp $
+
+| Copyright (c) 1996 Nivas Madhur
+| Copyright (c) 1995 Theo de Raadt
+|
+| 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 under OpenBSD by
+| Theo de Raadt for Willowglen Singapore.
+| 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.
+|
+| Copyright (c) 1995 Gordon W. Ross
+| 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. The name of the author may not be used to endorse or promote products
+| derived from this software without specific prior written permission.
+| 4. All advertising materials mentioning features or use of this software
+| must display the following acknowledgement:
+| This product includes software developed by Gordon Ross
+|
+| 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.
+
+; SRT0.S - Stand-alone Run-Time startup code, part 0
+ .file "SRT0.S"
+ .text
+ .globl _stack
+_stack:
+ .globl _start
+_start:
+ .word __estack
+ .word _start
+
+ align 8
+ or.u r10, r0, hi16(_devlun)
+ st r2, r0, lo16(_devlun)
+ or.u r10, r0, hi16(_ctrlun)
+ st r3, r0, lo16(_ctrlun)
+ or.u r10, r0, hi16(_oparg)
+ st r8, r0, lo16(_oparg)
+ or.u r10, r0, hi16(_opargend)
+ st r9, r0, lo16(_opargend)
+; enable SFU1 - 88k disables SFU1 on a reset
+ ldcr r10, cr1
+ xor r10, r10, 0x8
+ stcr r10, cr1
+
+; Call the run-time startup C code, which will:
+; call main & call exit - exit passes control back to
+; to the Bug.
+ bsr __start
+
+; The end.
--- /dev/null
+/* $Id: SRT1.c,v 1.1.1.1 1997/03/03 19:30:35 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ *
+ * Copyright (c) 1995 Gordon W. Ross
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * 4. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Gordon Ross
+ *
+ * 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.
+ */
+
+/* SRT1.c - Stand-alone Run-time startup code, part 1 */
+
+#include <stdarg.h>
+#include <sys/types.h>
+
+#include "config.h"
+
+extern char *edata, *end;
+
+int devlun = 0;
+int ctrlun = 0;
+int oparg = 0;
+int opargend = 0;
+
+getvbr()
+{
+ asm volatile ("ldcr r2, cr7");
+}
+
+void
+exit()
+{
+ /*
+ * Return to the Bug
+ */
+
+ asm volatile ("or r9, r0, 0x63; tb0 0, r0, 496");
+ /* NOTREACHED */
+}
+
+struct brdid brdid;
+int cputyp;
+
+/*
+ * This is called by SRT0.S
+ * to do final prep for main
+ */
+_start()
+{
+ struct brdid *p;
+
+ /* Clear BSS */
+
+ bzero(edata, end - edata);
+
+ asm volatile("or r9, r0, 0x70\n
+ tb0 0, r0, 496\n
+ st r2, %0" : "=m" (p));
+
+ bcopy(p, &brdid, sizeof brdid);
+ cputyp = brdid.model;
+
+ main(0);
+ exit();
+}
+
+/*
+ * Boot programs in C++ ? Not likely!
+ */
+__main()
+{}
--- /dev/null
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 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.
+ *
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+#define MVMEPROM_CALL(x) \
+ asm volatile (__CONCAT("trap #15; .short ", __STRING(x)) )
+
+/* returns 0 if no characters ready to read */
+int
+mvmeprom_instat()
+{
+ u_short ret;
+
+ MVMEPROM_CALL(MVMEPROM_INSTAT);
+ asm volatile ("movew ccr,%0": "=d" (ret));
+ return (!(ret & 0x4));
+}
+
+void
+mvmeprom_outstr(start, end)
+ char *start, *end;
+{
+ asm volatile ("movl %0, sp@-" : "=a" (start));
+ asm volatile ("movl %0, sp@-" : "=a" (end));
+ MVMEPROM_CALL(MVMEPROM_OUTSTR);
+}
+
+void
+mvmeprom_outln(start, end)
+ char *start, *end;
+{
+ asm volatile ("movl %0, sp@-" : "=a" (start));
+ asm volatile ("movl %0, sp@-" : "=a" (end));
+ MVMEPROM_CALL(MVMEPROM_OUTSTRCRLF);
+}
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_diskrd(arg)
+ struct mvmeprom_dskio *arg;
+{
+ int ret;
+
+ asm volatile ("movel %0, sp@-"::"d" (arg));
+ MVMEPROM_CALL(MVMEPROM_DSKRD);
+ asm volatile ("movew ccr,%0": "=d" (ret));
+ return (!(ret & 0x4));
+}
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_diskwr(arg)
+ struct mvmeprom_dskio *arg;
+{
+ int ret;
+
+ asm volatile ("movel %0, sp@-"::"d" (arg));
+ MVMEPROM_CALL(MVMEPROM_DSKWR);
+ asm volatile ("movew ccr,%0": "=d" (ret));
+ return (!(ret & 0x4));
+}
+
+#ifdef NOTYET
+mvmeprom_diskcfig() {}
+mvmeprom_diskfmt(){}
+mvmeprom_diskctrl(){}
+#endif
+
+/* BUG - timing routine */
+void
+mvmeprom_delay(msec)
+ int msec;
+{
+ asm volatile ("movel %0,sp@-" : :"d" (msec));
+ MVMEPROM_CALL(MVMEPROM_DELAY);
+}
+
+/* BUG - return to bug routine */
+void
+mvmeprom_return()
+{
+ MVMEPROM_CALL(MVMEPROM_EXIT);
+ /*NOTREACHED*/
+}
+
+/* BUG - query board routines */
+struct mvmeprom_brdid *
+mvmeprom_getbrdid()
+{
+ struct mvmeprom_brdid *id;
+
+ asm volatile ("clrl sp@-");
+ MVMEPROM_CALL(MVMEPROM_GETBRDID);
+ asm volatile ("movel sp@+,%0": "=d" (id):);
+ return (id);
+}
+
+void
+mvmeprom_rtc_rd(ptime)
+ struct mvmeprom_time *ptime;
+{
+ asm volatile ("movel %0,sp@-" : :"a" (ptime));
+ MVMEPROM_CALL(MVMEPROM_RTC_RD);
+}
--- /dev/null
+#include <sys/types.h>
+
+#include "clockreg.h"
+#include "config.h"
+#include "clock.h"
+
+/*
+ * 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);
+}
+
+time_t
+getsecs()
+{
+ extern int cputyp;
+ register struct clockreg *cl;
+ int sec, min, hour, day, mon, year;
+
+ if (cputyp == CPU_147)
+ cl = (struct clockreg *) CLOCK_ADDR_147;
+ else
+ cl = (struct clockreg *) CLOCK_ADDR_16x;
+
+ 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));
+}
+
+int
+getticks()
+{
+ return getsecs() * 100;
+}
--- /dev/null
+
+extern int hz;
+
+time_t getsecs();
+int getticks();
+
--- /dev/null
+/* $Id: clockreg.h,v 1.1.1.1 1997/03/03 19:30:37 rahnds 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
+
+#define CLOCK_ADDR_147 (0xfffe07f8) /* PA of clock */
+#define CLOCK_ADDR_16x (0xfffc1ff8) /* PA of clock */
--- /dev/null
+/* $Id: config.h,v 1.1.1.1 1997/03/03 19:30:37 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 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.
+ */
+
+/* configuration information for base-line code */
+
+#define ETHER_ADDR_147 (0xfffe0778)
+#define ETHER_ADDR_16X (0xfffc0000+7980)
+#define ERAM_ADDR (0xfffe0774)
+#define LANCE_REG_ADDR (0xfffe1800)
+#define INTEL_REG_ADDR (0xfff46000)
+
+#define CPU_147 0x147
+#define CPU_162 0x162
+#define CPU_167 0x167
+#define CPU_172 0x172
+#define CPU_177 0x177
+
+struct brdid {
+ u_long eye_catcher;
+ u_char rev;
+ u_char month;
+ u_char day;
+ u_char year;
+ u_short size;
+ u_short rsv1;
+ u_short model;
+ u_short suffix;
+ u_short options;
+ u_char family;
+ u_char cpu;
+ u_short ctrlun;
+ u_short devlun;
+ u_short devtype;
+ u_short devnum;
+ u_long bug;
+};
--- /dev/null
+/* $Id: dev_disk.c,v 1.1.1.1 1997/03/03 19:30:36 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1993 Paul Kranenburg
+ * 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 Paul Kranenburg.
+ * 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.
+ */
+
+/*
+ * This module implements a "raw device" interface suitable for
+ * use by the stand-alone I/O library UFS file-system code, and
+ * possibly for direct access (i.e. boot from tape).
+ *
+ * The implementation is deceptively simple because it uses the
+ * drivers provided by the Sun PROM monitor. Note that only the
+ * PROM driver used to load the boot program is available here.
+ */
+
+#include <sys/types.h>
+#include <machine/mon.h>
+#include <machine/saio.h>
+
+#include "stand.h"
+
+#include "dvma.h"
+#include "promdev.h"
+
+int
+disk_open(f, devname)
+ struct open_file *f;
+ char *devname; /* Device part of file name (or NULL). */
+{
+ struct saioreq *sip;
+ int error;
+
+#ifdef DEBUG_PROM
+ printf("disk_open: %s\n", devname);
+#endif
+
+ if ((error = prom_iopen(&sip)) != 0)
+ return (error);
+
+ f->f_devdata = sip;
+ return 0;
+}
+
+int
+disk_close(f)
+ struct open_file *f;
+{
+ struct saioreq *sip;
+
+ sip = f->f_devdata;
+ prom_iclose(sip);
+ f->f_devdata = NULL;
+ return 0;
+}
+
+int
+disk_strategy(devdata, flag, dblk, size, buf, rsize)
+ void *devdata;
+ int flag;
+ daddr_t dblk;
+ u_int size;
+ char *buf;
+ u_int *rsize;
+{
+ struct saioreq *si;
+ struct boottab *ops;
+ char *dmabuf;
+ int si_flag, xcnt;
+
+ si = devdata;
+ ops = si->si_boottab;
+
+#ifdef DEBUG_PROM
+ printf("disk_strategy: size=%d dblk=%d\n", size, dblk);
+#else
+ twiddle();
+#endif
+
+ dmabuf = dvma_mapin(buf, size);
+
+ si->si_bn = dblk;
+ si->si_ma = dmabuf;
+ si->si_cc = size;
+
+ si_flag = (flag == F_READ) ? SAIO_F_READ : SAIO_F_WRITE;
+ xcnt = (*ops->b_strategy)(si, si_flag);
+ dvma_mapout(dmabuf, size);
+
+#ifdef DEBUG_PROM
+ printf("disk_strategy: xcnt = %x\n", xcnt);
+#endif
+
+ if (xcnt <= 0)
+ return (EIO);
+
+ *rsize = xcnt;
+ return (0);
+}
+
+int
+disk_ioctl()
+{
+ return EIO;
+}
+
--- /dev/null
+
+int disk_open __P((struct open_file *, ...));
+int disk_close __P((struct open_file *));
+int disk_strategy __P((void *, int, daddr_t, u_int, char *, u_int *));
+int disk_ioctl();
+
--- /dev/null
+
+#include <sys/param.h>
+#include <stand.h>
+#include "promboot.h"
+
+/*
+ * Open the device named by the combined device/file name
+ * given as the "fname" arg, something like: "sd()bsd"
+ *
+ * However, Sun PROMs don't really let you choose which
+ * device you will talk to. You can only open the device
+ * that was used to load the boot program. Therefore, we
+ * do not accept a "device" part in the "fname" string.
+ * Pass the PROM device name to open in case it needs it.
+ */
+int
+devopen(f, fname, file)
+ struct open_file *f;
+ const char *fname;
+ char **file;
+{
+ struct devsw *dp;
+ char *cp, *path, *devname;
+ int error;
+
+ *file = (char*)fname;
+ dp = &devsw[0];
+ f->f_dev = dp;
+ error = (*dp->dv_open)(f, prom_bootdev);
+
+ return (error);
+}
--- /dev/null
+
+/*
+ * The easiest way to deal with the need for DVMA mappings is
+ * to just map the first four megabytes of RAM into DVMA space.
+ * That way, dvma_mapin can just compute the DVMA alias address,
+ * and dvma_mapout does nothing.
+ */
+
+#include <sys/param.h>
+
+#define DVMA_BASE 0x00000000
+#define DVMA_MASK 0x00ffFFff
+#define DVMA_MAPLEN 0x400000 /* 4 MB */
+
+void
+dvma_init()
+{
+#if 0
+ int segva, sme;
+
+ for (segva = 0; segva < DVMA_MAPLEN; segva += NBSG) {
+ sme = get_segmap(segva);
+ set_segmap((DVMA_BASE | segva), sme);
+ }
+#endif
+}
+
+/* Convert a local address to a DVMA address. */
+char *
+dvma_mapin(char *addr, int len)
+{
+ int va = (int)addr;
+
+ va |= DVMA_BASE;
+ return ((char *) va);
+}
+
+/* Convert a DVMA address to a local address. */
+char *
+dvma_mapout(char *dmabuf, int len)
+{
+ if (dmabuf < (char*)DVMA_BASE)
+ panic("dvma_mapout");
+ return (dmabuf - DVMA_BASE);
+}
+
+extern char *alloc(int len);
+char *
+dvma_alloc(int len)
+{
+ char *mem;
+
+ mem = alloc(len);
+ if (!mem)
+ return(mem);
+ return(dvma_mapin(mem, len));
+}
+
+extern void free(void *ptr, int len);
+void
+dvma_free(char *dvma, int len)
+{
+ char *mem;
+
+ mem = dvma_mapout(dvma, len);
+ if (mem)
+ free(mem, len);
+}
--- /dev/null
+
+char * dvma_mapin(char *pkt, int len);
+void dvma_mapout(char *dmabuf, int len);
+
+char * dvma_alloc(int len);
+
--- /dev/null
+/* $Id: exec_sun.c,v 1.1.1.1 1997/03/03 19:30:36 rahnds Exp $ */
+
+/*-
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 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.
+ *
+ * Copyright (c) 1982, 1986, 1990, 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.
+ *
+ * @(#)boot.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <a.out.h>
+
+#include "stand.h"
+
+extern int debug;
+
+extern u_int bootdev;
+
+/*ARGSUSED*/
+exec_sun(file, loadaddr, howto)
+ char *file;
+ char *loadaddr;
+ int howto;
+{
+ register int io;
+ struct exec x;
+ int cc, magic;
+ void (*entry)();
+ register char *cp;
+ register int *ip;
+ int textlen;
+
+#ifdef DEBUG
+ printf("exec_sun: file=%s loadaddr=0x%x\n", file, loadaddr);
+#endif
+
+ io = open(file, 0);
+ if (io < 0)
+ return(-1);
+
+ /*
+ * Read in the exec header, and validate it.
+ */
+ if (read(io, (char *)&x, sizeof(x)) != sizeof(x))
+ goto shread;
+ if (N_BADMAG(x)) {
+ errno = EFTYPE;
+ goto closeout;
+ }
+
+ cp = loadaddr;
+ textlen = x.a_text;
+ magic = N_GETMAGIC(x);
+ if (magic == ZMAGIC) {
+ cp += sizeof(x);
+ textlen -= sizeof(x);
+ }
+ entry = (void (*)())cp;
+
+ /*
+ * Leave a copy of the exec header before the text.
+ * The sun3 kernel uses this to verify that the
+ * symbols were loaded by this boot program.
+ */
+ bcopy(&x, cp - sizeof(x), sizeof(x));
+
+ /*
+ * Read in the text segment.
+ */
+ printf("%x", x.a_text);
+ if (read(io, cp, textlen) != textlen)
+ goto shread;
+ cp += textlen;
+
+ /*
+ * NMAGIC may have a gap between text and data.
+ */
+ if (magic == NMAGIC) {
+ register int mask = N_PAGSIZ(x) - 1;
+ while ((int)cp & mask)
+ *cp++ = 0;
+ }
+
+ /*
+ * Read in the data segment.
+ */
+ printf("+%x", x.a_data);
+ if (read(io, cp, x.a_data) != x.a_data)
+ goto shread;
+ cp += x.a_data;
+
+ /*
+ * Zero out the BSS section.
+ * (Kernel does not do it itself)
+ */
+ printf("+%x", x.a_bss);
+ cc = x.a_bss;
+ while ((int)cp & 3) {
+ *cp++ = 0;
+ --cc;
+ }
+ ip = (int *)cp;
+ cp += cc;
+ while ((char *)ip < cp)
+ *ip++ = 0;
+
+ /*
+ * Read in the symbol table and strings.
+ * (Always set the symtab size word.)
+ */
+ *ip++ = x.a_syms;
+ cp = (char *)ip;
+
+ if (x.a_syms > 0) {
+
+ /* Symbol table and string table length word. */
+ cc = x.a_syms;
+ printf("+[%x", cc);
+ cc += sizeof(int); /* strtab length too */
+ if (read(io, cp, cc) != cc)
+ goto shread;
+ cp += x.a_syms;
+ ip = (int *)cp; /* points to strtab length */
+ cp += sizeof(int);
+
+ /* String table. Length word includes itself. */
+ cc = *ip;
+ printf("+%x]", cc);
+ cc -= sizeof(int);
+ if (cc <= 0)
+ goto shread;
+ if (read(io, cp, cc) != cc)
+ goto shread;
+ cp += cc;
+ }
+ printf("=%x\n", cp - loadaddr);
+ close(io);
+
+ if (debug) {
+ printf("Debug mode - enter c to continue\n");
+ asm(" trap #0");
+ }
+
+ printf("Starting program at 0x%x\n", (int)entry);
+ (*entry)(howto, bootdev, cp, 0, 0);
+ panic("exec returned");
+
+shread:
+ printf("exec: short read\n");
+ errno = EIO;
+closeout:
+ close(io);
+ return(-1);
+}
--- /dev/null
+/* $Id: gets.c,v 1.1.1.1 1997/03/03 19:30:35 rahnds Exp $ */
+
+/*-
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 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.
+ *
+ * Copyright (c) 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.
+ *
+ * @(#)gets.c 8.1 (Berkeley) 6/11/93
+ */
+
+#include "stand.h"
+
+/*
+ * This implementation assumes that getchar() does echo, because
+ * on some machines, it is hard to keep echo from being done.
+ * Those that need it can do echo in their getchar() function.
+ *
+ * Yes, the code below will echo CR, DEL, and other control chars,
+ * but sending CR or DEL here is harmless. All the other editing
+ * characters will be followed by a newline, so it doesn't matter.
+ * (Most terminals will not show them anyway.)
+ */
+
+void
+gets(buf)
+ char *buf;
+{
+ register int c;
+ register char *lp;
+
+top:
+ lp = buf;
+
+ for (;;) {
+ c = getchar() & 0177;
+
+ putchar(c);
+
+ switch (c) {
+
+ default:
+ *lp++ = c;
+ continue;
+
+ case '\177':
+ putchar('\b');
+ /* fall through */
+ case '\b':
+ putchar(' ');
+ putchar('\b');
+ /* fall through */
+ case '#':
+ if (lp > buf)
+ lp--;
+ continue;
+
+ /*
+ * This is not very useful in a boot program.
+ * (It costs you 52 bytes on m68k, gcc -O3).
+ */
+ case 'r'&037: {
+ register char *p;
+ putchar('\n');
+ for (p = buf; p < lp; ++p)
+ putchar(*p);
+ continue;
+ }
+
+ case '@':
+ case 'u'&037:
+ case 'w'&037:
+ putchar('\n');
+ goto top;
+
+ case '\r':
+ putchar('\n');
+ /* fall through */
+ case '\n':
+ *lp = '\0';
+ return;
+
+ } /* switch */
+ }
+ /*NOTREACHED*/
+}
--- /dev/null
+nfs.o nfs.o
+rpc.o rpc.o
+net.o net.o
+ether.o ether.o
+arp.o arp.o
+in_cksum.o in_cksum.o
+netif.o netif.o
+bootparam.o bootparam.o
+rarp.o rarp.o
+alloc.o alloc.o
+bcopy.o bcopy.o
+memcpy.o memcpy.o
+close.o close.o
+getfile.o getfile.o
+open.o open.o
+printf.o printf.o
+read.o read.o
+strerror.o strerror.o
+ufs.o ufs.o
+globals.o globals.o
+lseek.o lseek.o
+closeall.o closeall.o
+dev.o dev.o
+dkcksum.o dkcksum.o
+nullfs.o nullfs.o
+fstat.o fstat.o
+ashrdi3.o ashrdi3.o
+bcmp.o bcmp.o
+bzero.o bzero.o
+strcmp.o strcmp.o
+strlen.o strlen.o
+exec_sun.o exec_sun.o
+clock.o clock.o
+devopen.o devopen.o
+dvma.o dvma.o
+gets.o gets.o
+panic.o panic.o
+promboot.o promboot.o
+promcons.o promcons.o
+ufs.o ashrdi3.o
+dvma.o alloc.o
+nfs.o alloc.o
+ufs.o alloc.o
+net.o arp.o
+net.o arp.o
+arp.o globals.o
+ether.o globals.o
+rarp.o globals.o
+arp.o bcmp.o
+ether.o bcmp.o
+rarp.o bcmp.o
+arp.o bcopy.o
+bootparam.o bcopy.o
+ether.o bcopy.o
+exec_sun.o bcopy.o
+memcpy.o bcopy.o
+net.o bcopy.o
+nfs.o bcopy.o
+rarp.o bcopy.o
+ufs.o bcopy.o
+arp.o bzero.o
+net.o bzero.o
+netif.o bzero.o
+nfs.o bzero.o
+rarp.o bzero.o
+rpc.o bzero.o
+ufs.o bzero.o
+closeall.o close.o
+exec_sun.o close.o
+open.o devopen.o
+dvma.o alloc.o
+nfs.o alloc.o
+ufs.o alloc.o
+gets.o promcons.o
+getfile.o gets.o
+net.o clock.o
+net.o in_cksum.o
+arp.o net.o
+ether.o netif.o
+ether.o netif.o
+net.o globals.o
+rarp.o globals.o
+exec_sun.o open.o
+getfile.o open.o
+arp.o panic.o
+exec_sun.o panic.o
+net.o panic.o
+netif.o panic.o
+arp.o printf.o
+bootparam.o printf.o
+exec_sun.o printf.o
+getfile.o printf.o
+net.o printf.o
+netif.o printf.o
+nfs.o printf.o
+panic.o printf.o
+rarp.o printf.o
+rpc.o printf.o
+gets.o promcons.o
+printf.o promcons.o
+exec_sun.o read.o
+arp.o ether.o
+net.o ether.o
+rarp.o ether.o
+rpc.o net.o
+bootparam.o rpc.o
+nfs.o rpc.o
+bootparam.o rpc.o
+bootparam.o rpc.o
+bootparam.o rpc.o
+nfs.o rpc.o
+arp.o ether.o
+net.o ether.o
+rarp.o ether.o
+arp.o net.o
+rarp.o net.o
+rpc.o net.o
+rpc.o net.o
+bootparam.o netif.o
+nfs.o netif.o
+rarp.o netif.o
+strerror.o printf.o
+ufs.o strcmp.o
+rpc.o strerror.o
+bootparam.o strlen.o
+nfs.o strlen.o
+ufs.o strlen.o
+nfs.o printf.o
+read.o printf.o
+ufs.o printf.o
--- /dev/null
+promboot.o
+dvma.o
+exec_sun.o
+fstat.o
+nullfs.o
+dkcksum.o
+dev.o
+closeall.o
+lseek.o
+ufs.o
+read.o
+getfile.o
+close.o
+memcpy.o
+rarp.o
+bootparam.o
+nfs.o
+gets.o
+strlen.o
+strcmp.o
+ashrdi3.o
+open.o
+alloc.o
+rpc.o
+devopen.o
+strerror.o
+arp.o
+net.o
+clock.o
+in_cksum.o
+ether.o
+bcmp.o
+globals.o
+bcopy.o
+netif.o
+panic.o
+bzero.o
+printf.o
+promcons.o
--- /dev/null
+/* $Id: netif_sun.c,v 1.1.1.1 1997/03/03 19:30:36 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Gordon W. Ross
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * 4. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Gordon W. Ross
+ *
+ * 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.
+ */
+
+/*
+ * The Sun PROM has a fairly general set of network drivers,
+ * so it is easiest to just replace the netif module with
+ * this adaptation to the PROM network interface.
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <time.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+
+#include <machine/control.h>
+#include <machine/idprom.h>
+#include <machine/mon.h>
+#include <machine/saio.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+
+#include "clock.h"
+#include "dvma.h"
+#include "promdev.h"
+
+static struct netif netif_prom;
+
+#ifdef NETIF_DEBUG
+int netif_debug;
+#endif
+
+struct iodesc sockets[SOPEN_MAX];
+
+struct iodesc *
+socktodesc(sock)
+ int sock;
+{
+ if (sock != 0) {
+ return(NULL);
+ }
+ return (sockets);
+}
+
+int
+netif_open(machdep_hint)
+ void *machdep_hint;
+{
+ struct saioreq *si;
+ struct iodesc *io;
+ int fd, error;
+
+ /* find a free socket */
+ io = sockets;
+ if (io->io_netif) {
+#ifdef DEBUG
+ printf("netif_open: device busy\n");
+#endif
+ return (-1);
+ }
+ bzero(io, sizeof(*io));
+
+ /*
+ * Note: Sun PROMs will do RARP on open, but does not tell
+ * you the IP address it gets, so it is just noise to us...
+ */
+ if ((error = prom_iopen(&si)) != 0) {
+#ifdef DEBUG
+ printf("netif_open: prom_iopen, error=%d\n", error);
+#endif
+ return (-1);
+ }
+ if (si->si_sif == NULL) {
+#ifdef DEBUG
+ printf("netif_open: not a network device\n");
+#endif
+ prom_iclose(si);
+ return (-1);
+ }
+
+ netif_prom.devdata = si;
+ io->io_netif = &netif_prom;
+
+ /* Put our ethernet address in io->myea */
+ sun3_getether(io->myea);
+
+ return(0);
+}
+
+int
+netif_close(fd)
+ int fd;
+{
+ struct iodesc *io;
+ struct netif *ni;
+
+ if (fd != 0) {
+ errno = EBADF;
+ return(-1);
+ }
+
+ io = sockets;
+ ni = io->io_netif;
+ if (ni != NULL) {
+ prom_iclose(ni->devdata);
+ ni->devdata = NULL;
+ io->io_netif = NULL;
+ }
+ return(0);
+}
+
+/*
+ * Send a packet. The ether header is already there.
+ * Return the length sent (or -1 on error).
+ */
+int
+netif_put(desc, pkt, len)
+ struct iodesc *desc;
+ void *pkt;
+ int len;
+{
+ struct saioreq *si;
+ struct saif *sif;
+ char *dmabuf;
+ int rv, sendlen;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug) {
+ struct ether_header *eh;
+
+ printf("netif_put: desc=0x%x pkt=0x%x len=%d\n",
+ desc, pkt, len);
+ eh = pkt;
+ printf("dst: %s ", ether_sprintf(eh->ether_dhost));
+ printf("src: %s ", ether_sprintf(eh->ether_shost));
+ printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
+ }
+#endif
+
+ si = desc->io_netif->devdata;
+ sif = si->si_sif;
+ sendlen = len;
+ if (sendlen < 60) {
+ sendlen = 60;
+#ifdef NETIF_DEBUG
+ printf("netif_put: length padded to %d\n", sendlen);
+#endif
+ }
+
+#ifdef PARANOID
+ if (sif == NULL)
+ panic("netif_put: no saif ptr\n");
+#endif
+
+ dmabuf = dvma_mapin(pkt, sendlen);
+ rv = sif->sif_xmit(si->si_devdata, dmabuf, sendlen);
+ dvma_mapout(dmabuf, sendlen);
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("netif_put: xmit returned %d\n", rv);
+#endif
+ if (rv == 0) rv = len;
+ else rv = -1;
+
+ return rv;
+}
+
+/*
+ * Receive a packet, including the ether header.
+ * Return the total length received (or -1 on error).
+ */
+int
+netif_get(desc, pkt, maxlen, timo)
+ struct iodesc *desc;
+ void *pkt;
+ int maxlen;
+ time_t timo;
+{
+ struct saioreq *si;
+ struct saif *sif;
+ char *dmabuf;
+ int tick0, tmo_ticks;
+ int len;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("netif_get: pkt=0x%x, maxlen=%d, tmo=%d\n",
+ pkt, maxlen, timo);
+#endif
+
+ si = desc->io_netif->devdata;
+ sif = si->si_sif;
+
+#ifdef PARANOID
+ if (sif == NULL)
+ panic("netif_get: no saif ptr\n");
+#endif
+
+ tmo_ticks = timo * hz;
+ tick0 = getticks();
+
+ dmabuf = dvma_mapin(pkt, maxlen);
+ do len = sif->sif_poll(si->si_devdata, dmabuf);
+ while ((len == 0) && ((getticks() - tick0) < tmo_ticks));
+ dvma_mapout(dmabuf, maxlen);
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("netif_get: received len=%d\n", len);
+#endif
+
+ if (len < 12)
+ return -1;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug) {
+ struct ether_header *eh = pkt;
+
+ printf("dst: %s ", ether_sprintf(eh->ether_dhost));
+ printf("src: %s ", ether_sprintf(eh->ether_shost));
+ printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
+ }
+#endif
+
+ return len;
+}
+
+static struct idprom sun3_idprom;
+
+sun3_getether(ea)
+ u_char *ea;
+{
+ u_char *src, *dst;
+ int len, x;
+
+ if (sun3_idprom.idp_format == 0) {
+ dst = (char*)&sun3_idprom;
+ src = (char*)IDPROM_BASE;
+ len = IDPROM_SIZE;
+ do {
+ x = get_control_byte(src++);
+ *dst++ = x;
+ } while (--len > 0);
+ }
+ MACPY(sun3_idprom.idp_etheraddr, ea);
+}
+
--- /dev/null
+
+#include <stdarg.h>
+#include "stand.h"
+
+extern volatile void abort();
+extern int _estack[];
+
+__dead void
+panic(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ printf(fmt, ap);
+ printf("\n");
+ va_end(ap);
+ stackdump(0);
+ abort();
+}
+
+stackdump(dummy)
+ int dummy;
+{
+ int *ip;
+
+ printf("stackdump:\n");
+ for (ip = &dummy; ip < _estack; ip += 4) {
+ printf("%x: %x %x %x %x\n",
+ (int)ip, ip[0], ip[1], ip[2], ip[3]);
+ }
+}
--- /dev/null
+/* $Id: promboot.c,v 1.1.1.1 1997/03/03 19:30:36 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 4. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include "stand.h"
+#include "promboot.h"
+
+char prom_bootdev[32];
+char prom_bootfile[32];
+int prom_boothow;
+int debug;
+
+void
+prom_get_boot_info()
+{
+ char c, *src, *dst;
+ extern int devlun, ctrlun;
+ extern char *oparg, *opargend;
+
+#ifdef DEBUG
+ printf("prom_get_boot_info\n");
+#endif
+
+ /* Get kernel filename */
+ src = oparg;
+ while (src && (*src == ' ' || *src == '\t'))
+ src++;
+
+ dst = prom_bootfile;
+ if (src && *src != '-') {
+ while (src && *src) {
+ if (*src == ' ' || *src == '\t')
+ break;
+ *dst++ = *src++;
+ }
+ }
+ *dst = '\0';
+
+ /* Get boothowto flags */
+ while (src && (*src == ' ' || *src == '\t'))
+ src++;
+ if (src && (*src == '-')) {
+ while (*src) {
+ switch (*src++) {
+ case 'a':
+ prom_boothow |= RB_ASKNAME;
+ break;
+ case 's':
+ prom_boothow |= RB_SINGLE;
+ break;
+ case 'd':
+ prom_boothow |= RB_KDB;
+ debug = 1;
+ break;
+ }
+ }
+ }
+#ifdef DEBUG
+ printf("promboot: device=\"%s\" file=\"%s\" how=0x%x\n",
+ prom_bootdev, prom_bootfile, prom_boothow);
+#endif
+}
--- /dev/null
+
+extern char prom_bootdev[];
+extern char prom_bootfile[];
+extern int prom_boothow;
+
--- /dev/null
+/* $Id: promcons.c,v 1.1.1.1 1997/03/03 19:30:36 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 4. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdarg.h>
+#include <sys/types.h>
+
+int
+getchar()
+{
+ char c;
+
+ __asm volatile("or r9, r0, 0\n
+ tb0 0, r0, 496\n
+ st.b r2, %0" : "=m" (c));
+ return (c);
+}
+
+peekchar()
+{
+ int have = 0;
+
+ __asm volatile("or r9, r0, 1\n
+ tb0 0, r0, 496\n
+ bb1 2, r2, 1f\n
+ or r2,r0, 1\n
+ st r2, %0\n1:" : "=m" (have) :);
+ return (have);
+}
+
+void
+putchar(c)
+ int c;
+{
+ if (c == '\n')
+ putchar('\r');
+ __asm volatile("or r9, r0, 0x20\n
+ or r2, r0, %0\n
+ tb0 0, r0, 496\n" : : "r" (c));
+}
+
--- /dev/null
+/* $Id: promdev.c,v 1.1.1.1 1997/03/03 19:30:36 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Gordon W. Ross
+ * Copyright (c) 1993 Paul Kranenburg
+ * 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 Paul Kranenburg.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <machine/mon.h>
+#include <machine/pte.h>
+#include <machine/saio.h>
+
+#include <dvma.h>
+#include <stand.h>
+
+struct saioreq prom_si;
+static int promdev_inuse;
+
+static char *
+prom_mapin(u_long physaddr, int length, int maptype);
+
+int
+prom_iopen(void **devdatap)
+{
+ struct bootparam *bp;
+ struct boottab *ops;
+ struct devinfo *dip;
+ struct saioreq *si;
+ char *p;
+ int error;
+
+ if (promdev_inuse)
+ return(EMFILE);
+
+ bp = *romp->bootParam;
+ ops = bp->bootDevice;
+ dip = ops->b_devinfo;
+
+#ifdef DEBUG_PROM
+ printf("Boot device type: %s\n", ops->b_desc);
+#endif
+
+ dvma_init();
+
+ si = &prom_si;
+ bzero((caddr_t)si, sizeof(*si));
+ si->si_boottab = ops;
+ si->si_ctlr = bp->ctlrNum;
+ si->si_unit = bp->unitNum;
+ si->si_boff = bp->partNum;
+
+ if (si->si_ctlr > dip->d_stdcount) {
+ printf("Invalid controller number\n");
+ return(ENXIO);
+ }
+
+ if (dip->d_devbytes) {
+ si->si_devaddr = prom_mapin(dip->d_stdaddrs[si->si_ctlr],
+ dip->d_devbytes, dip->d_devtype);
+#ifdef DEBUG_PROM
+ printf("prom_iopen: devaddr=0x%x pte=0x%x\n",
+ si->si_devaddr, get_pte(si->si_devaddr));
+#endif
+ }
+
+ if (dip->d_dmabytes) {
+ si->si_dmaaddr = dvma_alloc(dip->d_dmabytes);
+#ifdef DEBUG_PROM
+ printf("prom_iopen: dmaaddr=0x%x\n", si->si_dmaaddr);
+#endif
+ }
+
+ /* OK, call the PROM device open routine. */
+ error = (*ops->b_open)(si);
+ if (error != 0) {
+ printf("prom_iopen: \"%s\" error=%d\n",
+ ops->b_desc, error);
+ return (ENXIO);
+ }
+#ifdef DEBUG_PROM
+ printf("prom_iopen: succeeded, error=%d\n", error);
+#endif
+
+ *devdatap = si;
+ promdev_inuse++;
+ return (0);
+}
+
+void
+prom_iclose(void *devdata)
+{
+ struct boottab *ops;
+ struct devinfo *dip;
+ struct saioreq *si;
+
+ if (promdev_inuse == 0)
+ return;
+
+ si = devdata;
+ ops = si->si_boottab;
+ dip = ops->b_devinfo;
+
+ (*ops->b_close)(si);
+
+ if (si->si_dmaaddr) {
+ dvma_free(si->si_dmaaddr, dip->d_dmabytes);
+ si->si_dmaaddr = NULL;
+ }
+
+ promdev_inuse = 0;
+}
+
+struct mapinfo {
+ int maptype;
+ int pgtype;
+ int base;
+};
+
+static struct mapinfo
+prom_mapinfo[] = {
+ { MAP_MAINMEM, PGT_OBMEM, 0 },
+ { MAP_OBIO, PGT_OBIO, 0 },
+ { MAP_MBMEM, PGT_OBMEM, 0 }, /* XXX - Sun2 Multibus? */
+ { MAP_MBIO, PGT_OBIO, 0 }, /* XXX - Sun2 Multibus? */
+ { MAP_VME16A16D, PGT_VME_D16, 0xFFFF0000 },
+ { MAP_VME16A32D, PGT_VME_D32, 0xFFFF0000 },
+ { MAP_VME24A16D, PGT_VME_D16, 0xFF000000 },
+ { MAP_VME24A32D, PGT_VME_D32, 0xFF000000 },
+ { MAP_VME32A16D, PGT_VME_D16, 0 },
+ { MAP_VME32A32D, PGT_VME_D32, 0 },
+};
+static prom_mapinfo_cnt = sizeof(prom_mapinfo) / sizeof(prom_mapinfo[0]);
+
+/* The virtual address we will use for PROM device mappings. */
+static int prom_devmap = MONSHORTSEG;
+
+static char *
+prom_mapin(physaddr, length, maptype)
+ u_long physaddr;
+ int length, maptype;
+{
+ int i, pa, pte, va;
+
+ if (length > (4*NBPG))
+ panic("prom_mapin: length=%d\n", length);
+
+ for (i = 0; i < prom_mapinfo_cnt; i++)
+ if (prom_mapinfo[i].maptype == maptype)
+ goto found;
+ panic("prom_mapin: invalid maptype %d\n", maptype);
+found:
+
+ pte = prom_mapinfo[i].pgtype;
+ pte |= PG_PERM;
+ pa = prom_mapinfo[i].base;
+ pa += physaddr;
+ pte |= PA_PGNUM(pa);
+
+ va = prom_devmap;
+ do {
+ set_pte(va, pte);
+ va += NBPG;
+ pte += 1;
+ length -= NBPG;
+ } while (length > 0);
+ return ((char*)prom_devmap);
+}
--- /dev/null
+
+int prom_iopen(struct saioreq **sipp);
+void prom_iclose(struct saioreq *sip);
+
--- /dev/null
+# $Id: Makefile,v 1.1.1.1 1997/03/03 19:30:39 rahnds Exp $
+
+RELOC=0x3F0000
+
+S= ${.CURDIR}/../../../..
+DEFS= -DSTANDALONE -DSUN_BOOTPARAMS
+INCPATH=-I${.CURDIR} -I${.CURDIR}/../libsa -I${S} -I${S}/lib/libsa
+CFLAGS= -O2 ${INCPATH} ${DEFS} ${COPTS}
+
+.include "${S}/arch/${MACHINE}/stand/libsa/Makefile.inc"
+.PATH: ${S}/arch/${MACHINE}/stand/libsa
+SRTOBJ= SRT0.o SRT1.o
+
+SRCS= boot.c conf.c version.c dev_net.c
+SRCS+= if_ie.c if_le.c
+OBJS= ${SRTOBJ} ${SRCS:S/.c/.o/g}
+
+all: netboot.bin
+
+netboot: ${OBJS} ${LIBSA}
+ ${LD} -s -N -T ${RELOC} -e start -o $@ ${OBJS} ${LIBSA}
+ @size $@
+
+netboot.bin: netboot
+ dd ibs=32 skip=1 if=netboot of=$@
+
+install:
+ install ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
+ netboot.bin ${DESTDIR}${MDEC_DIR}/netboot
+
+.include <bsd.prog.mk>
--- /dev/null
+/* $Id: boot.c,v 1.1.1.1 1997/03/03 19:30:38 rahnds Exp $ */
+
+/*-
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 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.
+ *
+ * Copyright (c) 1982, 1986, 1990, 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.
+ *
+ * @(#)boot.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+
+#include "stand.h"
+#include "promboot.h"
+
+/*
+ * Boot device is derived from ROM provided information.
+ */
+#define LOADADDR 0x10000
+
+extern char *version;
+char defname[32] = "bsd";
+char line[80];
+
+#if 0
+u_int bootdev = MAKEBOOTDEV(0, sdmajor, 0, 0, 0); /* disk boot */
+#endif
+u_int bootdev = MAKEBOOTDEV(1, 0, 0, 0, 0); /* network boot */
+
+main()
+{
+ char *cp, *file;
+ int io;
+ extern int cputyp;
+ extern char *oparg, *opargend;
+ int ask = 0;
+
+ printf(">> OpenBSD netboot [%s]\n", version);
+ printf("model MVME%x\n", cputyp);
+
+ *opargend = '\0';
+ prom_get_boot_info();
+ file = defname;
+
+ cp = prom_bootfile;
+ if (cp && *cp)
+ file = cp;
+
+ for (;;) {
+ if (ask) {
+ printf("boot: ");
+ gets(line);
+ if (line[0]) {
+ oparg = line;
+ prom_get_boot_info();
+ }
+ }
+ exec_sun(file, (char *)LOADADDR, prom_boothow);
+ printf("boot: %s\n", strerror(errno));
+ ask = 1;
+ }
+}
--- /dev/null
+/* $Id: conf.c,v 1.1.1.1 1997/03/03 19:30:38 rahnds Exp $ */
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <stand.h>
+#include <nfs.h>
+#include <dev_net.h>
+
+struct fs_ops file_system[] = {
+ { nfs_open, nfs_close, nfs_read, nfs_write, nfs_seek, nfs_stat },
+};
+int nfsys = sizeof(file_system) / sizeof(file_system[0]);
+
+struct devsw devsw[] = {
+ { "net", net_strategy, net_open, net_close, net_ioctl },
+};
+int ndevs = sizeof(devsw) / sizeof(devsw[0]);
+
+extern struct netif_driver le_driver;
+extern struct netif_driver ie_driver;
+
+struct netif_driver *netif_drivers[] = {
+ &le_driver,
+ &ie_driver,
+};
+int n_netif_drivers = sizeof(netif_drivers) / sizeof(netif_drivers[0]);
+
+
+/* XXX */
+int netif_debug;
+int debug;
+int errno;
--- /dev/null
+/* $Id: dev_net.c,v 1.1.1.1 1997/03/03 19:30:38 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Gordon W. Ross
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * 4. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Gordon W. Ross
+ *
+ * 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.
+ */
+
+/*
+ * This module implements a "raw device" interface suitable for
+ * use by the stand-alone I/O library NFS code. This interface
+ * does not support any "block" access, and exists only for the
+ * purpose of initializing the network interface, getting boot
+ * parameters, and performing the NFS mount.
+ *
+ * At open time, this does:
+ *
+ * find interface - netif_open()
+ * RARP for IP address - rarp_getipaddress()
+ * RPC/bootparams - callrpc(d, RPC_BOOTPARAMS, ...)
+ * RPC/mountd - nfs_mount(sock, ip, path)
+ *
+ * the root file handle from mountd is saved in a global
+ * for use by the NFS open code (NFS/lookup).
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+#include "config.h"
+#include "bootparam.h"
+
+extern int nfs_root_node[]; /* XXX - get from nfs_mount() */
+
+struct in_addr myip, rootip, gateip, mask;
+char rootpath[FNAME_SIZE];
+
+int netdev_sock = -1;
+static int open_count;
+
+/*
+ * Called by devopen after it sets f->f_dev to our devsw entry.
+ * This opens the low-level device and sets f->f_devdata.
+ */
+int
+net_open(f, devname)
+ struct open_file *f;
+ char *devname; /* Device part of file name (or NULL). */
+{
+ int error = 0;
+
+ /* On first open, do netif open, mount, etc. */
+ if (open_count == 0) {
+ /* Find network interface. */
+ if ((netdev_sock = netif_open(devname)) < 0)
+ return (error=ENXIO);
+ if ((error = net_mountroot(f, devname)) != 0)
+ return (error);
+ }
+ open_count++;
+ f->f_devdata = nfs_root_node;
+ return (error);
+}
+
+int
+net_close(f)
+ struct open_file *f;
+{
+ /* On last close, do netif close, etc. */
+ if (open_count > 0)
+ if (--open_count == 0)
+ netif_close(netdev_sock);
+ f->f_devdata = NULL;
+}
+
+int
+net_ioctl()
+{
+ return EIO;
+}
+
+int
+net_strategy()
+{
+ return EIO;
+}
+
+int
+net_mountroot(f, devname)
+ struct open_file *f;
+ char *devname; /* Device part of file name (or NULL). */
+{
+ int error;
+
+#ifdef DEBUG
+ printf("net_mountroot: %s\n", devname);
+#endif
+
+ /*
+ * Get info for NFS boot: our IP address, our hostname,
+ * server IP address, and our root path on the server.
+ * There are two ways to do this: The old, Sun way,
+ * and the more modern, BOOTP way. (RFC951, RFC1048)
+ */
+
+#ifdef SUN_BOOTPARAMS
+ /* Get boot info using RARP and Sun bootparams. */
+
+ /* Get our IP address. (rarp.c) */
+ if (rarp_getipaddress(netdev_sock) == -1)
+ return (EIO);
+ printf("boot: client IP address: %s\n", intoa(myip.s_addr));
+
+ /* Get our hostname, server IP address. */
+ if (bp_whoami(netdev_sock))
+ return (EIO);
+ printf("boot: client name: %s\n", hostname);
+
+ /* Get the root pathname. */
+ if (bp_getfile(netdev_sock, "root", &rootip, rootpath))
+ return (EIO);
+
+#else
+
+ /* Get boot info using BOOTP way. (RFC951, RFC1048) */
+ bootp(netdev_sock);
+
+ printf("Using IP address: %s\n", intoa(myip.s_addr));
+
+ printf("myip: %s (%s)", hostname, intoa(myip));
+ if (gateip)
+ printf(", gateip: %s", intoa(gateip));
+ if (mask)
+ printf(", mask: %s", intoa(mask));
+ printf("\n");
+
+#endif
+
+ printf("root addr=%s path=%s\n", intoa(rootip.s_addr), rootpath);
+
+ /* Get the NFS file handle (mount). */
+ error = nfs_mount(netdev_sock, rootip, rootpath);
+
+ return (error);
+}
+
+/*
+ * machdep_common_ether: get ethernet address
+ */
+void
+machdep_common_ether(ether)
+ u_char *ether;
+{
+ u_char *ea;
+ extern int cputyp;
+
+ if (cputyp == CPU_147) {
+ ea = (u_char *) ETHER_ADDR_147;
+
+ if ((*(int *) ea & 0x2fffff00) == 0x2fffff00)
+ panic("ERROR: ethernet address not set!\r\n");
+ ether[0] = 0x08;
+ ether[1] = 0x00;
+ ether[2] = 0x3e;
+ ether[3] = ea[0];
+ ether[4] = ea[1];
+ ether[5] = ea[2];
+ } else {
+ ea = (u_char *) ETHER_ADDR_16X;
+
+ if (ea[0] + ea[1] + ea[2] + ea[3] + ea[4] + ea[5] == 0)
+ panic("ERROR: ethernet address not set!\r\n");
+ ether[0] = ea[0];
+ ether[1] = ea[1];
+ ether[2] = ea[2];
+ ether[3] = ea[3];
+ ether[4] = ea[4];
+ ether[5] = ea[5];
+ }
+}
--- /dev/null
+
+int net_open __P((struct open_file *, ...));
+int net_close __P((struct open_file *));
+int net_ioctl();
+int net_strategy();
+
--- /dev/null
+/* $Id: i82586.h,v 1.1.1.1 1997/03/03 19:30:38 rahnds Exp $ */
+
+/*-
+ * Copyright (c) 1995 Theo de Raadt
+ * Copyright (c) 1992, University of Vermont and State Agricultural College.
+ * Copyright (c) 1992, Garrett A. Wollman.
+ * 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
+ * Vermont and State Agricultural College and Garrett A. Wollman.
+ * 4. Neither the name of the University nor the name of the author
+ * 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 UNIVERSITY OR 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.
+ */
+
+/*
+ * Intel 82586 Ethernet chip
+ * Register, bit, and structure definitions.
+ *
+ * Written by GAW with reference to the Clarkson Packet Driver code for this
+ * chip written by Russ Nelson and others.
+ */
+
+struct ie_en_addr {
+ u_char data[6];
+};
+/*
+ * the only actual IE registers.
+ */
+struct iereg {
+ u_short ie_porthigh;
+ u_short ie_portlow;
+ u_long ie_attention;
+};
+#define IE_PORT_NEWSCP 0x00000002
+#define IE_PORT_RESET 0x00000000
+
+/*
+ * This is the master configuration block. It tells the hardware where
+ * all the rest of the stuff is.
+ */
+struct ie_scp {
+ u_char mbz1[3]; /* must be zero */
+ u_char scp_sysbus; /* true if 8-bit only */
+ u_char mbz2[4]; /* must be zero */
+ u_short scp_iscp_low; /* 24-bit physaddr of ISCP */
+ u_char mbz3[1];
+ u_char scp_iscp_high; /* the rest of the physaddr.. */
+};
+/*
+ * The tells the hardware where all the rest of the stuff is, too.
+ * FIXME: some of these should be re-commented after we figure out their
+ * REAL function.
+ */
+struct ie_iscp {
+ u_char mbz1[1];
+ u_char iscp_busy; /* zeroed after init */
+ u_short iscp_scboffset; /* 16-bit physaddr of next struct */
+ u_short iscp_base_low; /* 24-bit physaddr for all 16-bit vars */
+ u_char mbz2[1];
+ u_char iscp_base_high; /* rest of physaddr ... */
+};
+/*
+ * This FINALLY tells the hardware what to do and where to put it.
+ */
+struct ie_scb {
+ u_short ie_status; /* status word */
+ u_short ie_command; /* command word */
+ u_short ie_command_list;/* 16-pointer to command block list */
+ u_short ie_recv_list; /* 16-pointer to receive frame list */
+ u_short ie_err_crc; /* CRC errors */
+ u_short ie_err_align; /* Alignment errors */
+ u_short ie_err_resource;/* Resource errors */
+ u_short ie_err_overrun; /* Overrun errors */
+};
+/* Command values */
+#define IE_RU_COMMAND 0x0070 /* mask for RU command */
+#define IE_RU_NOP 0 /* for completeness */
+#define IE_RU_START 0x0010 /* start receive unit command */
+#define IE_RU_ENABLE 0x0020 /* enable receiver command */
+#define IE_RU_DISABLE 0x0030 /* disable receiver command */
+#define IE_RU_ABORT 0x0040 /* abort current receive operation */
+
+#define IE_CU_COMMAND 0x0700 /* mask for CU command */
+#define IE_CU_NOP 0 /* included for completeness */
+#define IE_CU_START 0x0100 /* do-command command */
+#define IE_CU_RESUME 0x0200 /* resume a suspended cmd list */
+#define IE_CU_STOP 0x0300 /* SUSPEND was already taken */
+#define IE_CU_ABORT 0x0400 /* abort current command */
+
+#define IE_ACK_COMMAND 0xf000 /* mask for ACK command */
+#define IE_ACK_CX 0x8000 /* ack IE_ST_DONE */
+#define IE_ACK_FR 0x4000 /* ack IE_ST_RECV */
+#define IE_ACK_CNA 0x2000 /* ack IE_ST_ALLDONE */
+#define IE_ACK_RNR 0x1000 /* ack IE_ST_RNR */
+
+#define IE_ACTION_COMMAND(x) (((x) & IE_CU_COMMAND) == IE_CU_START)
+ /* is this command an action command? */
+
+/* Status values */
+#define IE_ST_WHENCE 0xf000 /* mask for cause of interrupt */
+#define IE_ST_DONE 0x8000 /* command with I bit completed */
+#define IE_ST_RECV 0x4000 /* frame received */
+#define IE_ST_ALLDONE 0x2000 /* all commands completed */
+#define IE_ST_RNR 0x1000 /* receive not ready */
+
+#define IE_CU_STATUS 0x700 /* mask for command unit status */
+#define IE_CU_ACTIVE 0x200 /* command unit is active */
+#define IE_CU_SUSPEND 0x100 /* command unit is suspended */
+
+#define IE_RU_STATUS 0x70 /* mask for receiver unit status */
+#define IE_RU_SUSPEND 0x10 /* receiver is suspended */
+#define IE_RU_NOSPACE 0x20 /* receiver has no resources */
+#define IE_RU_READY 0x40 /* receiver is ready */
+
+/*
+ * This is filled in partially by the chip, partially by us.
+ */
+struct ie_recv_frame_desc {
+ u_short ie_fd_status; /* status for this frame */
+ u_short ie_fd_last; /* end of frame list flag */
+ u_short ie_fd_next; /* 16-pointer to next RFD */
+ u_short ie_fd_buf_desc; /* 16-pointer to list of buffer desc's */
+ struct ie_en_addr dest; /* destination ether */
+ struct ie_en_addr src; /* source ether */
+ u_short ie_length; /* 802 length/Ether type */
+ u_short mbz; /* must be zero */
+};
+#define IE_FD_LAST 0x8000 /* last rfd in list */
+#define IE_FD_SUSP 0x4000 /* suspend RU after receipt */
+
+#define IE_FD_COMPLETE 0x8000 /* frame is complete */
+#define IE_FD_BUSY 0x4000 /* frame is busy */
+#define IE_FD_OK 0x2000 /* frame is bad */
+#define IE_FD_RNR 0x0200 /* receiver out of resources here */
+
+/*
+ * linked list of buffers...
+ */
+struct ie_recv_buf_desc {
+ u_short ie_rbd_actual; /* status for this buffer */
+ u_short ie_rbd_next; /* 16-pointer to next RBD */
+ u_short ie_rbd_buffer_low; /* 24-pointer to buffer for this RBD */
+ u_short ie_rbd_buffer_high; /* 24-pointer to buffer for this RBD */
+ u_short ie_rbd_length; /* length of the buffer */
+ u_short mbz; /* must be zero */
+};
+#define IE_RBD_LAST 0x8000 /* last buffer */
+#define IE_RBD_USED 0x4000 /* this buffer has data */
+/*
+ * All commands share this in common.
+ */
+struct ie_cmd_common {
+ u_short ie_cmd_status; /* status of this command */
+ u_short ie_cmd_cmd; /* command word */
+ u_short ie_cmd_link; /* link to next command */
+};
+#define IE_STAT_COMPL 0x8000 /* command is completed */
+#define IE_STAT_BUSY 0x4000 /* command is running now */
+#define IE_STAT_OK 0x2000 /* command completed successfully */
+#define IE_STAT_ABORT 0x1000 /* command was aborted */
+
+
+#define IE_CMD_NOP 0x0000 /* NOP */
+#define IE_CMD_IASETUP 0x0001 /* initial address setup */
+#define IE_CMD_CONFIG 0x0002 /* configure command */
+#define IE_CMD_MCAST 0x0003 /* multicast setup command */
+#define IE_CMD_XMIT 0x0004 /* transmit command */
+#define IE_CMD_TDR 0x0005 /* time-domain reflectometer command */
+#define IE_CMD_DUMP 0x0006 /* dump command */
+#define IE_CMD_DIAGNOSE 0x0007 /* diagnostics command */
+
+#define IE_CMD_LAST 0x8000 /* this is the last command in the list */
+#define IE_CMD_SUSPEND 0x4000 /* suspend CU after this command */
+#define IE_CMD_INTR 0x2000 /* post an interrupt after completion */
+
+/*
+ * This is the command to transmit a frame.
+ */
+struct ie_xmit_cmd {
+ struct ie_cmd_common com; /* common part */
+#define ie_xmit_status com.ie_cmd_status
+
+ u_short ie_xmit_desc; /* 16-pointer to buffer descriptor */
+ struct ie_en_addr ie_xmit_addr; /* destination address */
+
+ u_short ie_xmit_length; /* 802.3 length/Ether type field */
+};
+#define IE_XS_MAXCOLL 0x000f /* number of collisions during transmit */
+#define IE_XS_EXCMAX 0x0020 /* exceeded maximum number of collisions */
+#define IE_XS_SQE 0x0040 /* SQE positive */
+#define IE_XS_DEFERRED 0x0080 /* transmission deferred */
+#define IE_XS_UNDERRUN 0x0100 /* DMA underrun */
+#define IE_XS_LOSTCTS 0x0200 /* Lost CTS */
+#define IE_XS_NOCARRIER 0x0400 /* No Carrier */
+
+/*
+ * This is a buffer descriptor for a frame to be transmitted.
+ */
+
+struct ie_xmit_buf {
+ u_short ie_xmit_flags; /* see below */
+ u_short ie_xmit_next; /* 16-pointer to next desc. */
+ u_short ie_xmit_buf_low;/* 24-pointer to the actual buffer */
+ u_short ie_xmit_buf_high; /* 24-pointer to the actual buffer */
+};
+#define IE_XMIT_LAST 0x8000 /* this TBD is the last one */
+/* The rest of the `flags' word is actually the length. */
+
+/*
+ * Multicast setup command.
+ */
+
+#define MAXMCAST 250 /* must fit in transmit buffer */
+
+struct ie_mcast_cmd {
+ struct ie_cmd_common com; /* common part */
+#define ie_mcast_status com.ie_cmd_status
+
+ u_short ie_mcast_bytes; /* size (in bytes) of multicast addresses */
+ struct ie_en_addr ie_mcast_addrs[MAXMCAST + 1]; /* space for them */
+};
+/*
+ * Time Domain Reflectometer command.
+ */
+
+struct ie_tdr_cmd {
+ struct ie_cmd_common com; /* common part */
+#define ie_tdr_status com.ie_cmd_status
+
+ u_short ie_tdr_time; /* error bits and time */
+};
+#define IE_TDR_SUCCESS 0x8000 /* TDR succeeded without error */
+#define IE_TDR_XCVR 0x4000 /* detected a transceiver problem */
+#define IE_TDR_OPEN 0x2000 /* detected an open */
+#define IE_TDR_SHORT 0x1000 /* TDR detected a short */
+#define IE_TDR_TIME 0x07ff /* mask for reflection time */
+
+/*
+ * Initial Address Setup command
+ */
+struct ie_iasetup_cmd {
+ struct ie_cmd_common com;
+#define ie_iasetup_status com.ie_cmd_status
+
+ struct ie_en_addr ie_address;
+};
+/*
+ * Configuration command
+ */
+struct ie_config_cmd {
+ struct ie_cmd_common com; /* common part */
+#define ie_config_status com.ie_cmd_status
+
+ u_char ie_config_count;/* byte count (0x0c) */
+ u_char ie_fifo; /* fifo (8) */
+ u_char ie_save_bad; /* save bad frames (0x40) */
+ u_char ie_addr_len; /* address length (0x2e) (AL-LOC == 1) */
+ u_char ie_priority; /* priority and backoff (0x0) */
+ u_char ie_ifs; /* inter-frame spacing (0x60) */
+ u_char ie_slot_low; /* slot time, LSB (0x0) */
+ u_char ie_slot_high; /* slot time, MSN, and retries (0xf2) */
+ u_char ie_promisc; /* 1 if promiscuous, else 0 */
+ u_char ie_crs_cdt; /* CSMA/CD parameters (0x0) */
+ u_char ie_min_len; /* min frame length (0x40) */
+ u_char ie_junk; /* stuff for 82596 (0xff) */
+};
+
+struct iemem {
+ volatile struct ie_scp im_scp;
+ u_char xx1[4];
+ volatile struct ie_iscp im_iscp;
+
+ volatile struct ie_scb im_scb;
+ volatile struct ie_config_cmd im_cc;
+ volatile struct ie_iasetup_cmd im_ic;
+ volatile struct ie_recv_frame_desc im_rfd[NRXBUF];
+ volatile struct ie_recv_buf_desc im_rbd[NRXBUF];
+ volatile struct ie_xmit_cmd im_xc[NTXBUF];
+ volatile struct ie_xmit_buf im_xd[NTXBUF];
+ volatile u_char im_rxbuf[NRXBUF * IE_RBUF_SIZE];
+ volatile u_char im_txbuf[NTXBUF * ETHER_MAX_LEN];
+
+};
--- /dev/null
+/* $Id: if_ie.c,v 1.1.1.1 1997/03/03 19:30:38 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#define ETHER_MIN_LEN 64
+#define ETHER_MAX_LEN 1518
+
+#define NTXBUF 1
+#define NRXBUF 16
+#define IE_RBUF_SIZE ETHER_MAX_LEN
+
+#include "stand.h"
+#include "netif.h"
+#include "config.h"
+
+#include "i82586.h"
+#include "if_iereg.h"
+
+int ie_debug = 0;
+
+void ie_stop __P((struct netif *));
+void ie_end __P((struct netif *));
+void ie_error __P((struct netif *, char *, volatile struct iereg *));
+int ie_get __P((struct iodesc *, void *, size_t, time_t));
+void ie_init __P((struct iodesc *, void *));
+int ie_match __P((struct netif *, void *));
+int ie_poll __P((struct iodesc *, void *, int));
+int ie_probe __P((struct netif *, void *));
+int ie_put __P((struct iodesc *, void *, size_t));
+void ie_reset __P((struct netif *, u_char *));
+
+struct netif_stats ie_stats;
+
+struct netif_dif ie0_dif = {
+ 0, /* unit */
+ 1, /* nsel */
+ &ie_stats,
+ 0,
+ 0,
+};
+
+struct netif_driver ie_driver = {
+ "ie", /* netif_bname */
+ ie_match, /* match */
+ ie_probe, /* probe */
+ ie_init, /* init */
+ ie_get, /* get */
+ ie_put, /* put */
+ ie_end, /* end */
+ &ie0_dif, /* netif_ifs */
+ 1, /* netif_nifs */
+};
+
+struct ie_configuration {
+ u_int phys_addr;
+ int used;
+} ie_config[] = {
+ { INTEL_REG_ADDR, 0 }
+};
+
+int nie_config = sizeof(ie_config) / (sizeof(ie_config[0]));
+
+struct {
+ struct iereg *sc_reg; /* IE registers */
+ struct iemem *sc_mem; /* RAM */
+} ie_softc;
+
+int
+ie_match(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+ char *name;
+ int i, val = 0;
+ extern int cputyp;
+
+ if (cputyp == CPU_147)
+ return (0);
+ name = machdep_hint;
+ if (name && !bcmp(ie_driver.netif_bname, name, 2))
+ val += 10;
+ for (i = 0; i < nie_config; i++) {
+ if (ie_config[i].used)
+ continue;
+ if (ie_debug)
+ printf("ie%d: ie_match --> %d\n", i, val + 1);
+ ie_config[i].used++;
+ return (val + 1);
+ }
+ if (ie_debug)
+ printf("ie%d: ie_match --> 0\n", i);
+ return (0);
+}
+
+int
+ie_probe(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+ extern int cputyp;
+
+ /* the set unit is the current unit */
+ if (ie_debug)
+ printf("ie%d: ie_probe called\n", nif->nif_unit);
+
+ if (cputyp != CPU_147)
+ return (0);
+ return (1);
+}
+
+void
+ie_error(nif, str, ier)
+ struct netif *nif;
+ char *str;
+ volatile struct iereg *ier;
+{
+ panic("ie%d: unknown error\n", nif->nif_unit);
+}
+
+ieack(ier, iem)
+ volatile struct iereg *ier;
+ struct iemem *iem;
+{
+ /* ack the `interrupt' */
+ iem->im_scb.ie_command = iem->im_scb.ie_status & IE_ST_WHENCE;
+ ier->ie_attention = 1; /* chan attention! */
+ while (iem->im_scb.ie_command)
+ ;
+}
+
+void
+ie_reset(nif, myea)
+ struct netif *nif;
+ u_char *myea;
+{
+ volatile struct iereg *ier = ie_softc.sc_reg;
+ struct iemem *iem = ie_softc.sc_mem;
+ int timo = 10000, stat, i;
+ volatile int t;
+ u_int a;
+
+ if (ie_debug)
+ printf("ie%d: ie_reset called\n", nif->nif_unit);
+
+ /*printf("ier %x iem %x\n", ier, iem);*/
+
+ *(u_char *)0xfff4202a = 0x40;
+
+ bzero(iem, sizeof(*iem));
+ iem->im_scp.scp_sysbus = 0;
+ iem->im_scp.scp_iscp_low = (int) &iem->im_iscp & 0xffff;
+ iem->im_scp.scp_iscp_high = (int) &iem->im_iscp >> 16;
+
+ iem->im_iscp.iscp_scboffset = (int) &iem->im_scb - (int) iem;
+ iem->im_iscp.iscp_busy = 1;
+ iem->im_iscp.iscp_base_low = (int) iem & 0xffff;
+ iem->im_iscp.iscp_base_high = (int) iem >> 16;
+
+ /*
+ * completely and utterly unlike what i expected, the
+ * "write" order is:
+ * 1st: d15-d0 -> high address
+ * 2nd: d31-d16 -> low address
+ */
+
+ /* reset chip */
+ a = IE_PORT_RESET;
+ ier->ie_porthigh = a & 0xffff;
+ t = 0;
+ t = 1;
+ ier->ie_portlow = a >> 16;
+ for (t = timo; t--;)
+ ;
+
+ /* set new SCP pointer */
+ a = (int) &iem->im_scp | IE_PORT_NEWSCP;
+ ier->ie_porthigh = a & 0xffff;
+ t = 0;
+ t = 1;
+ ier->ie_portlow = a >> 16;
+ for (t = timo; t--;)
+ ;
+
+ ier->ie_attention = 1; /* chan attention! */
+ for (t = timo * 10; t--;)
+ ;
+
+ /* send CONFIGURE command */
+ iem->im_scb.ie_command = IE_CU_START;
+ iem->im_scb.ie_command_list = (int) &iem->im_cc - (int) iem;
+ iem->im_cc.com.ie_cmd_status = 0;
+ iem->im_cc.com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
+ iem->im_cc.com.ie_cmd_link = 0xffff;
+ iem->im_cc.ie_config_count = 0x0c;
+ iem->im_cc.ie_fifo = 8;
+ iem->im_cc.ie_save_bad = 0x40;
+ iem->im_cc.ie_addr_len = 0x2e;
+ iem->im_cc.ie_priority = 0;
+ iem->im_cc.ie_ifs = 0x60;
+ iem->im_cc.ie_slot_low = 0;
+ iem->im_cc.ie_slot_high = 0xf2;
+ iem->im_cc.ie_promisc = 0;
+ iem->im_cc.ie_crs_cdt = 0;
+ iem->im_cc.ie_min_len = 64;
+ iem->im_cc.ie_junk = 0xff;
+
+ ier->ie_attention = 1; /* chan attention! */
+ for (t = timo * 10; t--;)
+ ;
+
+ ieack(ier, iem);
+
+ /*printf("ic %x\n", &iem->im_ic);*/
+ /* send IASETUP command */
+ iem->im_scb.ie_command = IE_CU_START;
+ iem->im_scb.ie_command_list = (int) &iem->im_ic - (int) iem;
+ iem->im_ic.com.ie_cmd_status = 0;
+ iem->im_ic.com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
+ iem->im_ic.com.ie_cmd_link = 0xffff;
+ bcopy(myea, (void *)&iem->im_ic.ie_address, sizeof iem->im_ic.ie_address);
+
+ ier->ie_attention = 1; /* chan attention! */
+ for (t = timo * 10; t--;)
+ ;
+
+ ieack(ier, iem);
+
+ /* setup buffers */
+
+ for (i = 0; i < NRXBUF; i++) {
+ iem->im_rfd[i].ie_fd_next = (int) &iem->im_rfd[(i+1) % NRXBUF] -
+ (int) iem;
+ iem->im_rbd[i].ie_rbd_next = (int) &iem->im_rbd[(i+1) % NRXBUF] -
+ (int) iem;
+ a = (int) &iem->im_rxbuf[i * IE_RBUF_SIZE];
+ iem->im_rbd[i].ie_rbd_buffer_low = a & 0xffff;
+ iem->im_rbd[i].ie_rbd_buffer_high = a >> 16;
+ iem->im_rbd[i].ie_rbd_length = IE_RBUF_SIZE;
+ }
+ iem->im_rfd[NRXBUF-1].ie_fd_last |= IE_FD_LAST;
+ iem->im_rbd[NRXBUF-1].ie_rbd_length |= IE_RBD_LAST;
+ iem->im_rfd[0].ie_fd_buf_desc = (int) &iem->im_rbd[0] - (int) iem;
+
+ /*printf("rfd[0] %x rbd[0] %x buf[0] %x\n", &iem->im_rfd, &iem->im_rbd,
+ &iem->im_rxbuf);*/
+
+ /* send receiver start command */
+ iem->im_scb.ie_command = IE_RU_START;
+ iem->im_scb.ie_command_list = 0;
+ iem->im_scb.ie_recv_list = (int) &iem->im_rfd[0] - (int) iem;
+ ier->ie_attention = 1; /* chan attention! */
+ while (iem->im_scb.ie_command)
+ ;
+
+ ieack(ier, iem);
+}
+
+int
+ie_poll(desc, pkt, len)
+ struct iodesc *desc;
+ void *pkt;
+ int len;
+{
+ volatile struct iereg *ier = ie_softc.sc_reg;
+ struct iemem *iem = ie_softc.sc_mem;
+ u_char *p = pkt;
+ static int slot;
+ int length = 0;
+ u_int a;
+ u_short status;
+
+ asm(".word 0xf518\n");
+ status = iem->im_rfd[slot].ie_fd_status;
+ if (status & IE_FD_BUSY)
+ return (0);
+
+ /* printf("slot %d: %x\n", slot, status); */
+ if ((status & (IE_FD_COMPLETE | IE_FD_OK)) == (IE_FD_COMPLETE | IE_FD_OK)) {
+ if (status & IE_FD_OK) {
+ length = iem->im_rbd[slot].ie_rbd_actual & 0x3fff;
+ if (length > len)
+ length = len;
+ bcopy((void *)&iem->im_rxbuf[slot * IE_RBUF_SIZE],
+ pkt, length);
+
+ iem->im_rfd[slot].ie_fd_status = 0;
+ iem->im_rfd[slot].ie_fd_last |= IE_FD_LAST;
+ iem->im_rfd[(slot+NRXBUF-1)%NRXBUF].ie_fd_last &=
+ ~IE_FD_LAST;
+ iem->im_rbd[slot].ie_rbd_actual = 0;
+ iem->im_rbd[slot].ie_rbd_length |= IE_RBD_LAST;
+ iem->im_rbd[(slot+NRXBUF-1)%NRXBUF].ie_rbd_length &=
+ ~IE_RBD_LAST;
+ /*printf("S%d\n", slot);*/
+
+ } else {
+ printf("shit\n");
+ }
+ slot++;
+ /* should move descriptor onto end of queue... */
+ }
+ if ((iem->im_scb.ie_status & IE_RU_READY) == 0) {
+ printf("RR\n");
+
+ for (slot = 0; slot < NRXBUF; slot++) {
+ iem->im_rbd[slot].ie_rbd_length &= ~IE_RBD_LAST;
+ iem->im_rfd[slot].ie_fd_last &= ~IE_FD_LAST;
+ }
+ iem->im_rbd[NRXBUF-1].ie_rbd_length |= IE_RBD_LAST;
+ iem->im_rfd[NRXBUF-1].ie_fd_last |= IE_FD_LAST;
+
+ iem->im_rfd[0].ie_fd_buf_desc = (int)&iem->im_rbd[0] - (int)iem;
+
+ iem->im_scb.ie_command = IE_RU_START;
+ iem->im_scb.ie_command_list = 0;
+ iem->im_scb.ie_recv_list = (int)&iem->im_rfd[0] - (int)iem;
+ ier->ie_attention = 1; /* chan attention! */
+ while (iem->im_scb.ie_command)
+ ;
+ slot = 0;
+ }
+ slot = slot % NRXBUF;
+ return (length);
+}
+
+int
+ie_put(desc, pkt, len)
+ struct iodesc *desc;
+ void *pkt;
+ size_t len;
+{
+ volatile struct iereg *ier = ie_softc.sc_reg;
+ struct iemem *iem = ie_softc.sc_mem;
+ u_char *p = pkt;
+ int timo = 10000, stat, i;
+ volatile int t;
+ u_int a;
+ int xx = 0;
+
+ /* send transmit command */
+
+ while (iem->im_scb.ie_command)
+ ;
+
+ /* copy data */
+ bcopy(p, (void *)&iem->im_txbuf[xx], len);
+
+ len = MAX(len, ETHER_MIN_LEN);
+
+ /* build transmit descriptor */
+ iem->im_xd[xx].ie_xmit_flags = len | IE_XMIT_LAST;
+ iem->im_xd[xx].ie_xmit_next = 0xffff;
+ a = (int) &iem->im_txbuf[xx];
+ iem->im_xd[xx].ie_xmit_buf_low = a & 0xffff;
+ iem->im_xd[xx].ie_xmit_buf_high = a >> 16;
+
+ /* transmit command */
+ iem->im_xc[xx].com.ie_cmd_status = 0;
+ iem->im_xc[xx].com.ie_cmd_cmd = IE_CMD_XMIT | IE_CMD_LAST;
+ iem->im_xc[xx].com.ie_cmd_link = 0xffff;
+ iem->im_xc[xx].ie_xmit_desc = (int) &iem->im_xd[xx] - (int) iem;
+ iem->im_xc[xx].ie_xmit_length = len;
+ bcopy(p, (void *)&iem->im_xc[xx].ie_xmit_addr,
+ sizeof iem->im_xc[xx].ie_xmit_addr);
+
+ iem->im_scb.ie_command = IE_CU_START;
+ iem->im_scb.ie_command_list = (int) &iem->im_xc[xx] - (int) iem;
+
+ ier->ie_attention = 1; /* chan attention! */
+
+ if (ie_debug) {
+ printf("ie%d: send %d to %x:%x:%x:%x:%x:%x\n",
+ desc->io_netif->nif_unit, len,
+ p[0], p[1], p[2], p[3], p[4], p[5]);
+ }
+ return (len);
+}
+
+int
+ie_get(desc, pkt, len, timeout)
+ struct iodesc *desc;
+ void *pkt;
+ size_t len;
+ time_t timeout;
+{
+ time_t t;
+ int cc;
+
+ t = getsecs();
+ cc = 0;
+ while (((getsecs() - t) < timeout) && !cc) {
+ cc = ie_poll(desc, pkt, len);
+ }
+ return (cc);
+}
+/*
+ * init ie device. return 0 on failure, 1 if ok.
+ */
+void
+ie_init(desc, machdep_hint)
+ struct iodesc *desc;
+ void *machdep_hint;
+{
+ struct netif *nif = desc->io_netif;
+
+ if (ie_debug)
+ printf("ie%d: ie_init called\n", desc->io_netif->nif_unit);
+ machdep_common_ether(desc->myea);
+ bzero(&ie_softc, sizeof(ie_softc));
+ ie_softc.sc_reg =
+ (struct iereg *) ie_config[desc->io_netif->nif_unit].phys_addr;
+ ie_softc.sc_mem = (struct iemem *) 0x1e0000;
+ ie_reset(desc->io_netif, desc->myea);
+ printf("device: %s%d attached to %s\n", nif->nif_driver->netif_bname,
+ nif->nif_unit, ether_sprintf(desc->myea));
+}
+
+void
+ie_stop(nif)
+ struct netif *nif;
+{
+ volatile struct iereg *ier = ie_softc.sc_reg;
+ struct iemem *iem = ie_softc.sc_mem;
+ int timo = 10000;
+ volatile int t;
+ u_int a;
+
+ iem->im_iscp.iscp_busy = 1;
+ /* reset chip */
+ a = IE_PORT_RESET;
+ ier->ie_porthigh = a & 0xffff;
+ t = 0;
+ t = 1;
+ ier->ie_portlow = a >> 16;
+ for (t = timo; t--;)
+ ;
+
+ /* reset chip again */
+ a = IE_PORT_RESET;
+ ier->ie_porthigh = a & 0xffff;
+ t = 0;
+ t = 1;
+ ier->ie_portlow = a >> 16;
+ for (t = timo; t--;)
+ ;
+
+ /*printf("status %x busy %x\n", iem->im_scb.ie_status,
+ iem->im_iscp.iscp_busy);*/
+}
+
+void
+ie_end(nif)
+ struct netif *nif;
+{
+ if (ie_debug)
+ printf("ie%d: ie_end called\n", nif->nif_unit);
+
+ ie_stop(nif);
+
+ /* *(u_char *) 0xfff42002 = 0; */
+}
--- /dev/null
+/* $Id: if_iereg.h,v 1.1.1.1 1997/03/03 19:30:38 rahnds Exp $ */
+
+/*
+ * if_sunie.h
+ *
+ * sun's ie interface
+ */
+
+/*
+ * programming notes:
+ *
+ * the ie chip operates in a 24 bit address space.
+ *
+ * most ie interfaces appear to be divided into two parts:
+ * - generic 586 stuff
+ * - board specific
+ *
+ * generic:
+ * the generic stuff of the ie chip is all done with data structures
+ * that live in the chip's memory address space. the chip expects
+ * its main data structure (the sys conf ptr -- SCP) to be at a fixed
+ * address in its 24 bit space: 0xfffff4
+ *
+ * the SCP points to another structure called the ISCP.
+ * the ISCP points to another structure called the SCB.
+ * the SCB has a status field, a linked list of "commands", and
+ * a linked list of "receive buffers". these are data structures that
+ * live in memory, not registers.
+ *
+ * board:
+ * to get the chip to do anything, you first put a command in the
+ * command data structure list. then you have to signal "attention"
+ * to the chip to get it to look at the command. how you
+ * signal attention depends on what board you have... on PC's
+ * there is an i/o port number to do this, on sun's there is a
+ * register bit you toggle.
+ *
+ * to get data from the chip you program it to interrupt...
+ *
+ *
+ * sun issues:
+ *
+ * there are 3 kinds of sun "ie" interfaces:
+ * 1 - a VME/multibus card
+ * 2 - an on-board interface (sun3's, sun-4/100's, and sun-4/200's)
+ * 3 - another VME board called the 3E
+ *
+ * the VME boards lives in vme16 space. only 16 and 8 bit accesses
+ * are allowed, so functions that copy data must be aware of this.
+ *
+ * the chip is an intel chip. this means that the byte order
+ * on all the "short"s in the chip's data structures is wrong.
+ * so, constants described in the intel docs are swapped for the sun.
+ * that means that any buffer pointers you give the chip must be
+ * swapped to intel format. yuck.
+ *
+ * VME/multibus interface:
+ * for the multibus interface the board ignores the top 4 bits
+ * of the chip address. the multibus interface seems to have its
+ * own MMU like page map (without protections or valid bits, etc).
+ * there are 256 pages of physical memory on the board (each page
+ * is 1024 bytes). there are 1024 slots in the page map. so,
+ * a 1024 byte page takes up 10 bits of address for the offset,
+ * and if there are 1024 slots in the page that is another 10 bits
+ * of the address. that makes a 20 bit address, and as stated
+ * earlier the board ignores the top 4 bits, so that accounts
+ * for all 24 bits of address.
+ *
+ * note that the last entry of the page map maps the top of the
+ * 24 bit address space and that the SCP is supposed to be at
+ * 0xfffff4 (taking into account allignment). so,
+ * for multibus, that entry in the page map has to be used for the SCP.
+ *
+ * the page map effects BOTH how the ie chip sees the
+ * memory, and how the host sees it.
+ *
+ * the page map is part of the "register" area of the board
+ *
+ * on-board interface:
+ *
+ * <fill in useful info later>
+ *
+ *
+ * VME3E interface:
+ *
+ * <fill in useful info later>
+ *
+ */
+
+/*
+ * PART 1: VME/multibus defs
+ */
+#define IEVME_PAGESIZE 1024 /* bytes */
+#define IEVME_PAGSHIFT 10 /* bits */
+#define IEVME_NPAGES 256 /* number of pages on chip */
+#define IEVME_MAPSZ 1024 /* number of entries in the map */
+
+/*
+ * PTE for the page map
+ */
+#define IEVME_SBORDR 0x8000 /* sun byte order */
+#define IEVME_IBORDR 0x0000 /* intel byte ordr */
+
+#define IEVME_P2MEM 0x2000 /* memory is on P2 */
+#define IEVME_OBMEM 0x0000 /* memory is on board */
+
+#define IEVME_PGMASK 0x0fff /* gives the physical page frame number */
+
+struct ievme {
+ u_short pgmap[IEVME_MAPSZ];
+ u_short xxx[32]; /* prom */
+ u_short status; /* see below for bits */
+ u_short xxx2; /* filler */
+ u_short pectrl; /* parity control (see below) */
+ u_short peaddr; /* low 16 bits of address */
+};
+/*
+ * status bits
+ */
+#define IEVME_RESET 0x8000 /* reset board */
+#define IEVME_ONAIR 0x4000 /* go out of loopback 'on-air' */
+#define IEVME_ATTEN 0x2000 /* attention */
+#define IEVME_IENAB 0x1000 /* interrupt enable */
+#define IEVME_PEINT 0x0800 /* parity error interrupt enable */
+#define IEVME_PERR 0x0200 /* parity error flag */
+#define IEVME_INT 0x0100 /* interrupt flag */
+#define IEVME_P2EN 0x0020 /* enable p2 bus */
+#define IEVME_256K 0x0010 /* 256kb rams */
+#define IEVME_HADDR 0x000f /* mask for bits 17-20 of address */
+
+/*
+ * parity control
+ */
+#define IEVME_PARACK 0x0100 /* parity error ack */
+#define IEVME_PARSRC 0x0080 /* parity error source */
+#define IEVME_PAREND 0x0040 /* which end of the data got the error */
+#define IEVME_PARADR 0x000f /* mask to get bits 17-20 of parity address */
+
+
+/*
+ * PART 2: the on-board interface
+ */
+struct ieob {
+ u_char obctrl;
+};
+#define IEOB_NORSET 0x80 /* don't reset the board */
+#define IEOB_ONAIR 0x40 /* put us on the air */
+#define IEOB_ATTEN 0x20 /* attention! */
+#define IEOB_IENAB 0x10 /* interrupt enable */
+#define IEOB_XXXXX 0x08 /* free bit */
+#define IEOB_XCVRL2 0x04 /* level 2 transceiver? */
+#define IEOB_BUSERR 0x02 /* bus error */
+#define IEOB_INT 0x01 /* interrupt */
+
+#define IEOB_ADBASE 0xff000000 /* KVA base addr of 24 bit address space */
+
+/*
+ * PART 3: the 3E board
+ */
+
+/*
+ * not supported (yet?)
+ */
--- /dev/null
+/* $Id: if_le.c,v 1.1.1.1 1997/03/03 19:30:37 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ *
+ * 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 <sys/param.h>
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include "stand.h"
+#include "netif.h"
+#include "config.h"
+
+#include "if_lereg.h"
+
+int le_debug = 0;
+
+void le_end __P((struct netif *));
+void le_error __P((struct netif *, char *, volatile struct lereg1 *));
+int le_get __P((struct iodesc *, void *, size_t, time_t));
+void le_init __P((struct iodesc *, void *));
+int le_match __P((struct netif *, void *));
+int le_poll __P((struct iodesc *, void *, int));
+int le_probe __P((struct netif *, void *));
+int le_put __P((struct iodesc *, void *, size_t));
+void le_reset __P((struct netif *, u_char *));
+
+struct netif_stats le_stats;
+
+struct netif_dif le0_dif = {
+ 0, /* unit */
+ 1, /* nsel */
+ &le_stats,
+ 0,
+ 0,
+};
+
+struct netif_driver le_driver = {
+ "le", /* netif_bname */
+ le_match, /* match */
+ le_probe, /* probe */
+ le_init, /* init */
+ le_get, /* get */
+ le_put, /* put */
+ le_end, /* end */
+ &le0_dif, /* netif_ifs */
+ 1, /* netif_nifs */
+};
+
+struct le_configuration {
+ unsigned int phys_addr;
+ int used;
+} le_config[] = {
+ { LANCE_REG_ADDR, 0 }
+};
+
+int nle_config = sizeof(le_config) / (sizeof(le_config[0]));
+
+struct {
+ struct lereg1 *sc_r1; /* LANCE registers */
+ struct lereg2 *sc_r2; /* RAM */
+ int next_rmd;
+ int next_tmd;
+} le_softc;
+
+int
+le_match(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+ char *name;
+ int i, val = 0;
+ extern int cputyp;
+
+ if (cputyp != CPU_147)
+ return (0);
+ name = machdep_hint;
+ if (name && !bcmp(le_driver.netif_bname, name, 2))
+ val += 10;
+ for (i = 0; i < nle_config; i++) {
+ if (le_config[i].used)
+ continue;
+ if (le_debug)
+ printf("le%d: le_match --> %d\n", i, val + 1);
+ le_config[i].used++;
+ return val + 1;
+ }
+ if (le_debug)
+ printf("le%d: le_match --> 0\n", i);
+ return 0;
+}
+
+int
+le_probe(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+ extern int cputyp;
+
+ /* the set unit is the current unit */
+ if (le_debug)
+ printf("le%d: le_probe called\n", nif->nif_unit);
+
+ if (cputyp == CPU_147)
+ return 0;
+ return 1;
+}
+
+void
+le_error(nif, str, ler1)
+ struct netif *nif;
+ char *str;
+ volatile struct lereg1 *ler1;
+{
+ /* ler1->ler1_rap = LE_CSRO done in caller */
+ if (ler1->ler1_rdp & LE_C0_BABL)
+ panic("le%d: been babbling, found by '%s'\n", nif->nif_unit, str);
+ if (ler1->ler1_rdp & LE_C0_CERR) {
+ le_stats.collision_error++;
+ ler1->ler1_rdp = LE_C0_CERR;
+ }
+ if (ler1->ler1_rdp & LE_C0_MISS) {
+ le_stats.missed++;
+ ler1->ler1_rdp = LE_C0_MISS;
+ }
+ if (ler1->ler1_rdp & LE_C0_MERR) {
+ printf("le%d: memory error in '%s'\n", nif->nif_unit, str);
+ panic("memory error");
+ }
+}
+
+void
+le_reset(nif, myea)
+ struct netif *nif;
+ 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;
+
+ if (le_debug)
+ printf("le%d: le_reset called\n", nif->nif_unit);
+ 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("le%d: init timeout, stat = 0x%x\n",
+ nif->nif_unit, 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(desc, pkt, len)
+ struct iodesc *desc;
+ 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(desc->io_netif, "le_poll", ler1);
+ if (rmd->rmd1_bits & LE_R1_ERR) {
+ printf("le%d_poll: rmd status 0x%x\n", desc->io_netif->nif_unit,
+ rmd->rmd1_bits);
+ length = 0;
+ goto cleanup;
+ }
+ if ((rmd->rmd1_bits & (LE_R1_STP | LE_R1_ENP)) != (LE_R1_STP | LE_R1_ENP))
+ panic("le_poll: chained packet\n");
+
+ length = rmd->rmd3;
+ if (length >= LEMTU) {
+ length = 0;
+ panic("csr0 when bad things happen: %x\n", ler1->ler1_rdp);
+ goto cleanup;
+ }
+ if (!length)
+ goto cleanup;
+ length -= 4;
+ if (length > 0) {
+
+ /*
+ * if buffer is smaller than the packet truncate it.
+ * (is this wise?)
+ */
+ if (length > len)
+ length = len;
+
+ bcopy((void *)&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(desc, pkt, len)
+ struct iodesc *desc;
+ void *pkt;
+ size_t len;
+{
+ volatile struct lereg1 *ler1 = le_softc.sc_r1;
+ volatile struct lereg2 *ler2 = le_softc.sc_r2;
+ volatile 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(desc->io_netif, "le_put(way before xmit)", ler1);
+ tmd = &ler2->ler2_tmd[le_softc.next_tmd];
+ while (tmd->tmd1_bits & LE_T1_OWN) {
+ printf("le%d: output buffer busy\n", desc->io_netif->nif_unit);
+ }
+ bcopy(pkt, (void *)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(desc->io_netif, "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(desc->io_netif, "le_put(after xmit)", ler1);
+ do {
+ if (--timo == 0) {
+ printf("le%d: transmit timeout, stat = 0x%x\n",
+ desc->io_netif->nif_unit, stat);
+ if (ler1->ler1_rdp & LE_C0_ERR)
+ le_error(desc->io_netif, "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(desc->io_netif, "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_DEF)
+ le_stats.deferred++;
+ if (tmd->tmd1_bits & LE_T1_ONE)
+ le_stats.collisions++;
+ if (tmd->tmd1_bits & LE_T1_MORE)
+ le_stats.collisions += 2;
+ if (tmd->tmd1_bits & LE_T1_ERR) {
+ printf("le%d: transmit error, error = 0x%x\n", desc->io_netif->nif_unit,
+ tmd->tmd3);
+ return -1;
+ }
+ if (le_debug) {
+ printf("le%d: le_put() successful: sent %d\n",
+ desc->io_netif->nif_unit, len);
+ printf("le%d: le_put(): tmd1_bits: %x tmd3: %x\n",
+ desc->io_netif->nif_unit,
+ (unsigned int) tmd->tmd1_bits,
+ (unsigned int) tmd->tmd3);
+ }
+ return len;
+}
+
+int
+le_get(desc, pkt, len, timeout)
+ struct iodesc *desc;
+ void *pkt;
+ size_t len;
+ time_t timeout;
+{
+ time_t t;
+ int cc;
+
+ t = getsecs();
+ cc = 0;
+ while (((getsecs() - t) < timeout) && !cc) {
+ cc = le_poll(desc, pkt, len);
+ }
+ return cc;
+}
+/*
+ * init le device. return 0 on failure, 1 if ok.
+ */
+void
+le_init(desc, machdep_hint)
+ struct iodesc *desc;
+ void *machdep_hint;
+{
+ u_long eram = 4*1024*1024;
+ struct netif *nif = desc->io_netif;
+
+ if (le_debug)
+ printf("le%d: le_init called\n", desc->io_netif->nif_unit);
+ machdep_common_ether(desc->myea);
+ bzero(&le_softc, sizeof(le_softc));
+ le_softc.sc_r1 =
+ (struct lereg1 *) le_config[desc->io_netif->nif_unit].phys_addr;
+ le_softc.sc_r2 = (struct lereg2 *) (eram - (1024 * 1024));
+ le_reset(desc->io_netif, desc->myea);
+ printf("device: %s%d attached to %s\n", nif->nif_driver->netif_bname,
+ nif->nif_unit, ether_sprintf(desc->myea));
+}
+
+void
+le_end(nif)
+ struct netif *nif;
+{
+ struct lereg1 *ler1 = le_softc.sc_r1;
+
+ if (le_debug)
+ printf("le%d: le_end called\n", nif->nif_unit);
+ ler1->ler1_rap = LE_CSR0;
+ ler1->ler1_rdp = LE_C0_STOP;
+}
--- /dev/null
+/* $Id: if_lereg.h,v 1.1.1.1 1997/03/03 19:30:38 rahnds 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)
--- /dev/null
+#NO_APP
+gcc2_compiled.:
+___gnu_compiled_c:
+.text
+ .even
+.globl _nfs_getrootfh
+ .type _nfs_getrootfh,@function
+_nfs_getrootfh:
+ link a6,#-392
+ moveml #0x3038,sp@-
+ movel a6@(12),d3
+ lea a6@(-132),a2
+ lea a6@(-280),a3
+ pea 132:w
+ movel a2,sp@-
+ jbsr _bzero
+ movel d3,sp@-
+ jbsr _strlen
+ movel d0,d2
+ addqw #8,sp
+ addqw #4,sp
+ moveq #120,d0
+ addqw #8,d0
+ cmpl d2,d0
+ jcc L2
+ movel d0,d2
+L2:
+ movel d2,a2@
+ movel d2,sp@-
+ pea a6@(-128)
+ movel d3,sp@-
+ lea _bcopy,a4
+ jbsr a4@
+ movel d2,d0
+ addql #3,d0
+ jpl L3
+ movel d2,d0
+ addql #6,d0
+L3:
+ moveq #-4,d1
+ andl d1,d0
+ pea 36:w
+ movel a3,sp@-
+ movel d0,a0
+ pea a0@(4)
+ movel a2,sp@-
+ pea 1:w
+ pea 1:w
+ movel #100005,sp@-
+ movel a6@(8),sp@-
+ jbsr _rpc_call
+ addw #44,sp
+ moveq #-1,d1
+ cmpl d0,d1
+ jeq L7
+ moveq #3,d1
+ cmpl d0,d1
+ jcs L5
+ moveq #72,d1
+ movel d1,_errno
+ jra L8
+L5:
+ tstl a3@
+ jne L6
+ pea 32:w
+ movel a6@(16),sp@-
+ pea a3@(4)
+ jbsr a4@
+ clrl d0
+ jra L7
+L6:
+ movel a3@,_errno
+L8:
+ moveq #-1,d0
+L7:
+ moveml a6@(-412),#0x1c0c
+ unlk a6
+ rts
+Lfe1:
+ .size _nfs_getrootfh,Lfe1-_nfs_getrootfh
+ .even
+.globl _nfs_lookupfh
+ .type _nfs_lookupfh,@function
+_nfs_lookupfh:
+ link a6,#-492
+ moveml #0x303c,sp@-
+ movel a6@(8),a5
+ movel a6@(12),d3
+ lea a6@(-164),a2
+ lea a6@(-380),a3
+ pea 164:w
+ movel a2,sp@-
+ jbsr _bzero
+ pea 32:w
+ movel a2,sp@-
+ pea a5@(12)
+ lea _bcopy,a4
+ jbsr a4@
+ movel d3,sp@-
+ jbsr _strlen
+ movel d0,d2
+ addw #24,sp
+ moveq #120,d0
+ addqw #8,d0
+ cmpl d2,d0
+ jcc L10
+ movel d0,d2
+L10:
+ movel d2,sp@-
+ pea a6@(-128)
+ movel d3,sp@-
+ jbsr a4@
+ movel d2,a6@(-132)
+ movel d2,d0
+ addql #3,d0
+ jpl L11
+ movel d2,d0
+ addql #6,d0
+L11:
+ moveq #-4,d1
+ andl d1,d0
+ pea 104:w
+ movel a3,sp@-
+ movel d0,a0
+ pea a0@(36)
+ movel a2,sp@-
+ pea 4:w
+ pea 2:w
+ movel #100003,sp@-
+ movel a5@,sp@-
+ jbsr _rpc_call
+ addw #44,sp
+ moveq #-1,d1
+ cmpl d0,d1
+ jne L12
+ movel _errno,d0
+ jra L15
+L12:
+ moveq #3,d1
+ cmpl d0,d1
+ jlt L13
+ moveq #5,d0
+ jra L15
+L13:
+ tstl a3@
+ jne L14
+ pea 32:w
+ movel a6@(16),a0
+ pea a0@(12)
+ pea a3@(4)
+ jbsr a4@
+ pea 68:w
+ movel a6@(16),a0
+ pea a0@(44)
+ pea a3@(36)
+ jbsr a4@
+ clrl d0
+ jra L15
+L14:
+ movel a3@,d0
+L15:
+ moveml a6@(-516),#0x3c0c
+ unlk a6
+ rts
+Lfe2:
+ .size _nfs_lookupfh,Lfe2-_nfs_lookupfh
+LC0:
+ .ascii "nfsread: short packet, %d < %d\12\0"
+ .even
+.globl _nfs_readdata
+ .type _nfs_readdata,@function
+_nfs_readdata:
+ link a6,#-1368
+ moveml #0x383c,sp@-
+ movel a6@(8),a4
+ movel a6@(12),d2
+ movel a6@(16),d3
+ movel a6@(24),d4
+ lea a6@(-44),a3
+ lea a6@(-1256),a2
+ pea 32:w
+ movel a3,sp@-
+ pea a4@(12)
+ lea _bcopy,a5
+ jbsr a5@
+ movel d3,a6@(-12)
+ addqw #8,sp
+ addqw #4,sp
+ movel #1024,d0
+ cmpl d4,d0
+ jcc L17
+ movel d0,d4
+L17:
+ movel d4,a6@(-8)
+ clrl a6@(-4)
+ pea 1100:w
+ movel a2,sp@-
+ pea 44:w
+ movel a3,sp@-
+ pea 6:w
+ pea 2:w
+ movel #100003,sp@-
+ movel a4@,sp@-
+ jbsr _rpc_call
+ movel d0,a0
+ addw #32,sp
+ moveq #-1,d1
+ cmpl a0,d1
+ jeq L22
+ moveq #76,d1
+ cmpl a0,d1
+ jhi L23
+ tstl a2@
+ jeq L20
+ movel a2@,_errno
+ jra L24
+L20:
+ addw #-76,a0
+ movel a6@(-1184),d2
+ cmpl a0,d2
+ jgt L21
+ movel d2,sp@-
+ movel a6@(20),sp@-
+ pea a2@(76)
+ jbsr a5@
+ movel d2,d0
+ jra L22
+L21:
+ movel d2,sp@-
+ movel a0,sp@-
+ pea LC0
+ jbsr _printf
+L23:
+ moveq #72,d1
+ movel d1,_errno
+L24:
+ moveq #-1,d0
+L22:
+ moveml a6@(-1396),#0x3c1c
+ unlk a6
+ rts
+Lfe3:
+ .size _nfs_readdata,Lfe3-_nfs_readdata
+ .even
+.globl _nfs_mount
+ .type _nfs_mount,@function
+_nfs_mount:
+ link a6,#0
+ movel a2,sp@-
+ movel a6@(8),sp@-
+ jbsr _socktodesc
+ movel d0,a2
+ addqw #4,sp
+ tstl a2
+ jeq L26
+ movel _rpc_port,d0
+ subql #1,d0
+ movel d0,_rpc_port
+ movew d0,a2@(10)
+ movel a6@(12),a2@
+ pea _nfs_root_node+12
+ movel a6@(16),sp@-
+ movel a2,sp@-
+ jbsr _nfs_getrootfh
+ tstl d0
+ jne L27
+ movel a2,_nfs_root_node
+ moveq #2,d1
+ movel d1,_nfs_root_node+44
+ movel #493,_nfs_root_node+48
+ movel d1,_nfs_root_node+52
+ clrl d0
+ jra L28
+L26:
+ moveq #22,d1
+ movel d1,_errno
+L27:
+ moveq #-1,d0
+L28:
+ movel a6@(-4),a2
+ unlk a6
+ rts
+Lfe4:
+ .size _nfs_mount,Lfe4-_nfs_mount
+LC1:
+ .ascii "nfs_open: must mount first.\12\0"
+ .even
+.globl _nfs_open
+ .type _nfs_open,@function
+_nfs_open:
+ link a6,#0
+ moveml #0x2038,sp@-
+ movel a6@(12),a4
+ lea _nfs_root_node,a3
+ tstl a3@
+ jne L30
+ pea LC1
+ jbsr _printf
+ moveq #6,d0
+ jra L32
+L30:
+ pea 112:w
+ jbsr _alloc
+ movel d0,a2
+ movel a3@,a2@
+ clrl a2@(4)
+ clrl a2@(8)
+ movel a2,sp@-
+ movel a6@(8),sp@-
+ movel a3,sp@-
+ jbsr _nfs_lookupfh
+ movel d0,d2
+ addqw #8,sp
+ addqw #8,sp
+ jeq L31
+ pea 112:w
+ movel a2,sp@-
+ jbsr _free
+ movel d2,d0
+ jra L32
+L31:
+ movel a2,a4@(16)
+ clrl d0
+L32:
+ moveml a6@(-16),#0x1c04
+ unlk a6
+ rts
+Lfe5:
+ .size _nfs_open,Lfe5-_nfs_open
+ .even
+.globl _nfs_close
+ .type _nfs_close,@function
+_nfs_close:
+ link a6,#0
+ movel a2,sp@-
+ movel a6@(8),a2
+ movel a2@(16),d0
+ jeq L34
+ pea 112:w
+ movel d0,sp@-
+ jbsr _free
+L34:
+ clrl a2@(16)
+ clrl d0
+ movel a6@(-4),a2
+ unlk a6
+ rts
+Lfe6:
+ .size _nfs_close,Lfe6-_nfs_close
+LC2:
+ .ascii "nfs_read: hit EOF unexpectantly\0"
+ .even
+.globl _nfs_read
+ .type _nfs_read,@function
+_nfs_read:
+ link a6,#0
+ moveml #0x3f3c,sp@-
+ movel a6@(8),a0
+ movel a6@(16),a3
+ movel a6@(20),a5
+ movel a0@(16),a2
+ movel a6@(12),a4
+ tstl a3
+ jle L41
+L42:
+ jbsr _twiddle
+ movel a3,sp@-
+ movel a4,sp@-
+ movel a2@(8),sp@-
+ movel a2@(4),sp@-
+ movel a2,sp@-
+ jbsr _nfs_readdata
+ movel d0,d7
+ addw #20,sp
+ moveq #-1,d5
+ cmpl d7,d5
+ jne L38
+ movel _errno,d0
+ jra L44
+L38:
+ tstl d7
+ jne L39
+ tstl _debug
+ jeq L41
+ pea LC2
+ jbsr _printf
+ jra L41
+L39:
+ movel d7,d4
+ movel d7,d3
+ moveq #31,d5
+ asrl d5,d3
+ movel d4,d2
+ addl a2@(8),d2
+ cmpl d2,d4
+ shi d0
+ extbl d0
+ movel d3,d1
+ addl a2@(4),d1
+ subl d0,d1
+ movel d1,a2@(4)
+ movel d2,a2@(8)
+ addl d7,a4
+ subl d7,a3
+ tstl a3
+ jgt L42
+L41:
+ tstl a5
+ jeq L43
+ movel a3,a5@
+L43:
+ clrl d0
+L44:
+ moveml a6@(-40),#0x3cfc
+ unlk a6
+ rts
+Lfe7:
+ .size _nfs_read,Lfe7-_nfs_read
+ .even
+.globl _nfs_write
+ .type _nfs_write,@function
+_nfs_write:
+ link a6,#0
+ moveq #30,d0
+ unlk a6
+ rts
+Lfe8:
+ .size _nfs_write,Lfe8-_nfs_write
+ .even
+.globl _nfs_seek
+ .type _nfs_seek,@function
+_nfs_seek:
+ link a6,#0
+ moveml #0x3f00,sp@-
+ movel a6@(8),a0
+ movel a6@(12),d5
+ movel a6@(16),d6
+ movel a6@(20),d0
+ movel a0@(16),a0
+ movel a0@(64),d1
+ moveq #1,d7
+ cmpl d0,d7
+ jeq L49
+ jlt L53
+ tstl d0
+ jeq L48
+ jra L51
+L53:
+ moveq #2,d7
+ cmpl d0,d7
+ jeq L50
+ jra L51
+L48:
+ movel d5,a0@(4)
+ movel d6,a0@(8)
+ jra L47
+L49:
+ movel a0@(4),d3
+ movel a0@(8),d4
+ movel d6,d2
+ addl d4,d2
+ cmpl d2,d6
+ shi d0
+ extbl d0
+ movel d5,d1
+ addl d3,d1
+ subl d0,d1
+ movel d1,a0@(4)
+ movel d2,a0@(8)
+ jra L47
+L50:
+ movel d1,d4
+ clrl d3
+ movel d4,d2
+ subl d6,d2
+ cmpl d2,d4
+ scs d0
+ extbl d0
+ movel d3,d1
+ subl d5,d1
+ addl d0,d1
+ movel d1,a0@(4)
+ movel d2,a0@(8)
+ jra L47
+L51:
+ moveq #-1,d0
+ moveq #-1,d1
+ jra L54
+L47:
+ movel a0@(4),d0
+ movel a0@(8),d1
+L54:
+ moveml a6@(-24),#0xfc
+ unlk a6
+ rts
+Lfe9:
+ .size _nfs_seek,Lfe9-_nfs_seek
+.globl _nfs_stat_types
+.data
+ .even
+ .type _nfs_stat_types,@object
+ .size _nfs_stat_types,32
+_nfs_stat_types:
+ .long 0
+ .long 32768
+ .long 16384
+ .long 24576
+ .long 8192
+ .long 40960
+ .long 0
+ .skip 4
+.text
+ .even
+.globl _nfs_stat
+ .type _nfs_stat,@function
+_nfs_stat:
+ link a6,#0
+ movel a2,sp@-
+ movel d2,sp@-
+ movel a6@(8),a0
+ movel a6@(12),a2
+ movel a0@(16),a1
+ moveq #7,d0
+ andl a1@(44),d0
+ lea _nfs_stat_types,a0
+ movew a1@(50),d2
+ orw a0@(2,d0:l:4),d2
+ movew d2,a2@(8)
+ movew a1@(54),a2@(10)
+ movel a1@(56),a2@(12)
+ movel a1@(60),a2@(16)
+ movel a1@(64),d1
+ clrl d0
+ movel d0,a2@(48)
+ movel d1,a2@(52)
+ movel a6@(-8),d2
+ movel a6@(-4),a2
+ unlk a6
+ rts
+Lfe10:
+ .size _nfs_stat,Lfe10-_nfs_stat
+.comm _nfs_root_node,112
--- /dev/null
+/* $Id: version.c,v 1.1.1.1 1997/03/03 19:30:38 rahnds Exp $ */
+
+/*
+ * NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.
+ *
+ * 1.1
+ */
+
+char *version = "$Revision: 1.1.1.1 $";
--- /dev/null
+SUBDIRS = libbug kerncrt boot bugexec
+SUBDIR = libbug kerncrt boot bugexec
+
+.include <bsd.prog.mk>
--- /dev/null
+all: boot boot.out
+CFLAGS+=-fwritable-strings -I${.CURDIR}/../include
+CFLAGS+=-I${.CURDIR}/../.. -I${.CURDIR}/../../machine
+CFLAGS+=-I/usr/src/sys
+LDFLAGS+= -L ${.CURDIR}/../libbug -L/usr/local/lib
+BOOT=FC0000
+#BOOT=1000000
+
+LIBBUG!= cd $(.CURDIR)/../libbug; \
+ printf "xxx:\n\techo \$${.OBJDIR}/libbug.a\n" | ${MAKE} -r -s -f - xxx
+
+LDADD+=${LIBBUG} #/usr/local/lib/libgcc.a
+SRCS+=bugcrt.c bugio.c main.c
+
+.PATH: ${.CURDIR}/../bugcrt ${.CURDIR}/../libbug ${.CURDIR}/../../../../lib/libc_sa ${.CURDIR}/${MACHINE_ARCH}
+
+boot: bugcrt.o main.o bcopy.o memset.o printf.o ${LIBBUG}
+# ld -o {.TARGET} -x -n -Ttext ${BOOT} bugcrt.o bugio.o main.o bcopy.o memset.o printf.o /usr/local/lib/libgcc.a
+ ld -o ${.TARGET} -x -N -Ttext ${BOOT} ${.ALLSRC} ${LDADD}
+
+boot.out:
+ ${.CURDIR}/wrtvid ${.OBJDIR}/boot && mv ${.OBJDIR}/boot.? ${.CURDIR}
+
+#main.o: main.c
+# ${CC} ${CFLAGS} -c -O ${.ALLSRC}
+# ${LD} -x -r ${.TARGET}
+# ${LD} -x ${.TARGET}
+# mv a.out ${.TARGET}
+
+.include <bsd.prog.mk>
--- /dev/null
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include "bug.h"
+#include "bugio.h"
+#include "machine/exec.h"
+
+int readblk __P((int, char *));
+int loados __P((void));
+void putchar __P((char));
+void _main __P((void));
+void tapefileseek __P((int));
+
+char Clun, Dlun;
+
+#define DEV_BSIZE 512
+#define KERNEL_LOAD_ADDR 0x10000
+#if !defined(BUG_BLKSIZE)
+#define BUG_BLKSIZE 256
+#endif /* BUG_BLKSIZE */
+#define sec2blk(x) ((x) * (DEV_BSIZE/BUG_BLKSIZE))
+
+struct kernel {
+ void *entry;
+ void *symtab;
+ void *esym;
+ int bflags;
+ int bdev;
+ char *kname;
+ void *smini;
+ void *emini;
+ unsigned int end_loaded;
+} kernel;
+
+int howto = 0;
+int bootdev = 0;
+int *miniroot;
+
+void
+putchar(char c)
+{
+ bugoutchr(c);
+}
+
+main(struct bugenv *env)
+{
+ printf("Clun %x Dlun %x\n", env->clun, env->dlun);
+ Clun = (char)env->clun;
+ Dlun = (char)env->dlun;
+ loados();
+ return;
+}
+
+
+loados(void)
+{
+ int i, size;
+ register char *loadaddr = (char *)KERNEL_LOAD_ADDR; /* load addr 64k*/
+ struct exec *hdr;
+ int (*fptr)();
+ int *esym;
+ int cnt, strtablen, ret;
+ char *addr;
+
+ howto |= RB_SINGLE|RB_KDB;
+
+ tapefileseek(2); /* seek to file 2 - the OS */
+ if (readblk(1, loadaddr) == -1) {
+ printf("Unable to read blk 0\n");
+ return 1;
+ }
+ hdr = (struct exec *)loadaddr;
+
+ /* We only deal with ZMAGIC files */
+ if ((int)hdr->a_entry != (int)(loadaddr + sizeof(struct exec))) {
+ printf("a_entry != loadaddr + exec size\n");
+ }
+ size = hdr->a_text + hdr->a_data;
+ size -= DEV_BSIZE; /* account for the block already read */
+
+ printf("Loading [%x+%x", hdr->a_text, hdr->a_data);
+ if (readblk(size / DEV_BSIZE, loadaddr + DEV_BSIZE) == -1) {
+ printf("Error reading the OS\n");
+ return 1;
+ }
+
+ /* zero out BSS */
+
+ printf("+%x]", hdr->a_bss);
+#if DEBUG
+ printf("zero'd out %x (%x)\n", loadaddr + hdr->a_text + hdr->a_data,
+ hdr->a_bss);
+#endif
+ memset(loadaddr + hdr->a_text + hdr->a_data, 0, hdr->a_bss);
+
+ addr = loadaddr + hdr->a_text + hdr->a_data + hdr->a_bss;
+
+ if (hdr->a_syms != 0 /* && !(kernel.bflags & RB_NOSYM)*/) {
+ /*
+ * DDB expects the following layout:
+ * no. of syms
+ * symbols
+ * size of strtab
+ * entries of strtab
+ * esym->...
+ * Where as size of strtab is part of strtab, we need
+ * to prepend the size of symtab to satisfy ddb.
+ * esym is expected to point past the last byte of
+ * string table, rouded up to an int.
+ */
+ bcopy(&hdr->a_syms, addr, sizeof(hdr->a_syms));
+ addr += 4; /* account for a_syms copied above */
+ printf (" + [ %x",hdr->a_syms);
+
+ cnt = (hdr->a_syms + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1);
+
+ ret = readblk(cnt / DEV_BSIZE, addr);
+ if (ret != 0) {
+ printf("unable to load kernel\n");
+ return 1;
+ }
+
+ esym = (void *) ((int)addr + hdr->a_syms);
+
+ if ((int)addr + cnt <= (int)esym) {
+ printf("missed loading count of symbols\n\r");
+ return 1;
+ }
+
+ addr += cnt;
+
+ strtablen = *esym;
+#if 0
+ printf("start load %x end load %x %x\n", addr,
+ len, addr +len);
+ printf("esym %x *esym %x\n",esym, len);
+#endif
+ /*
+ * If symbol table size is not a sector multiple, we
+ * already read part of the string table. Look at the
+ * part already read, and figure out the string table
+ * size. Also, adjust the size yet to read.
+ */
+ if (hdr->a_syms != cnt) {
+ /* already read part of the string table */
+ strtablen -= (cnt - hdr->a_syms);
+ }
+
+ if (strtablen > 0) {
+ printf(" + %x",*esym);
+
+ cnt = (strtablen + DEV_BSIZE -1) & ~(DEV_BSIZE - 1);
+
+ ret = readblk(cnt / DEV_BSIZE, addr);
+ if (ret != 0) {
+ printf("unable to load kernel\n");
+ return 1;
+ }
+ addr += strtablen;
+ printf(" ]\n");
+ } else {
+ printf("+ %x ]\n", *esym);
+ }
+ esym = (int *)(((int)esym) + *esym);
+ esym = (int *)(((int)esym + 4 - 1) & ~3);
+
+ kernel.symtab = (void *)hdr->a_syms;
+ kernel.esym = esym;
+ } else {
+ kernel.symtab = 0;
+ kernel.esym = 0;
+ }
+
+ kernel.end_loaded = (unsigned int)addr;
+ miniroot = (int *)esym;
+ miniroot = (int *)(((int)miniroot + 0x1000 - 1) & ~0xFFF);
+ tapefileseek(3); /* seek to file 3 - minroot */
+ if (readblk(1000, miniroot) != 0) {
+ printf("miniroot not loaded\n");
+ addr = (char *)miniroot;
+ } else {
+ addr = (char *)((int)miniroot + 1000 * DEV_BSIZE);
+ }
+ printf("esym %x miniroot @ %x (ends @ %x)\n", esym, miniroot, addr);
+#if 0
+ {
+ char *symaddr = (char *)0x01F00000;
+ int i;
+
+ tapefileseek(4); /* seek to file 4 - syms */
+ readblk(1, symaddr);
+ i = *symaddr;
+ i = (i * 0x1C + 4 + DEV_BSIZE) & ~(DEV_BSIZE - 1);
+ printf("loading %d symbols (%d sectors)\n",
+ *symaddr, (i + 1) * DEV_BSIZE);
+ readblk(i / DEV_BSIZE, symaddr + DEV_BSIZE);
+ readblk(100, 0x01F00000);
+ }
+#endif
+
+ fptr = (int (*)())hdr->a_entry;
+ /*
+ * Args are passed as
+ * r2 howto
+ * r3 end addr
+ * r4 (Clun << 8) | Dlun & FF
+ * r5 esym
+ * r6 miniroot
+ */
+ bootdev = ((Clun << 8) & 0xFF00 | Dlun & 0xFF) & 0xFFFF;
+#if 0
+ asm volatile ("or r2, r0, %0\n\tor r3, r0, %1\n\tor r4, r0, %2\n\tor r5, r0, %3\n\tor r6, r0, %4\n\tor r7, r0, %5"
+ : /* no outputs */
+ : "r" (howto), "r" (addr), "r" (Clun), "r" (Dlun), "r" (esym), "r" (miniroot)
+ : "r2", "r3", "r4", "r5", "r6", "r7");
+#endif /* 0 */
+ (*fptr)(howto, addr, bootdev, esym, miniroot);
+ return 0;
+}
+
+int
+readblk(int n, char *addr)
+{
+ struct bugdisk_io io;
+
+ io.clun = Clun;
+ io.dlun = Dlun;
+ io.status = 0;
+ io.addr = (void *)addr;
+ io.fileno = 0; /* for tape reads, start io at current pos */
+ io.nblks = sec2blk(n);
+ io.flag = IGNOREFILENO;
+ io.am = 0;
+ bugdskrd(&io);
+ if (io.status)
+ return -1;
+ return 0;
+}
+
+void
+_main(void)
+{
+ return;
+}
+
+void
+tapefileseek(int i)
+{
+ struct bugdisk_io io;
+ void *addr = (void *)KERNEL_LOAD_ADDR; /* some number - don't care */
+
+ io.clun = Clun;
+ io.dlun = Dlun;
+ io.status = 0;
+ io.addr = addr;
+ io.fileno = i; /* for tape reads, this is the file no. */
+ io.nblks = 0;
+ io.flag = 0; /* we want to turn off IFN and EOF bits */
+ io.am = 0;
+ bugdskrd(&io);
+}
+
+__main()
+{
+}
--- /dev/null
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "vid.h"
+
+#define sec2blk(x) ((x) * 2)
+
+main(int argc, char **argv)
+{
+ struct vid *pvid;
+ struct cfg *pcfg;
+ struct stat stat;
+ int exe_file;
+ int tape_vid;
+ int tape_exe;
+ unsigned int exe_addr;
+ unsigned short exe_addr_u;
+ unsigned short exe_addr_l;
+ char *filename;
+ char fileext[256];
+
+ if (argc == 0){
+ filename = "a.out";
+ } else {
+ filename = argv[1];
+ }
+ exe_file = open(filename, O_RDONLY,0444);
+ if (exe_file == -1)
+ {
+ printf("file %s does not exist\n",filename);
+ exit(2);
+ }
+ sprintf (fileext,"%s%s",filename,".1");
+ tape_vid = open(fileext, O_WRONLY|O_CREAT|O_TRUNC,0644);
+ sprintf (fileext,"%s%s",filename,".2");
+ tape_exe = open(fileext, O_WRONLY|O_CREAT|O_TRUNC,0644);
+
+ pvid = (struct vid *) malloc(sizeof (struct vid));
+
+ memset(pvid,0,sizeof(struct vid));
+
+ strcpy(pvid->vid_id, "NBSD");
+
+ fstat (exe_file,&stat);
+ /* size in 512 byte blocks round up after a.out header removed */
+ /* Actually, blocks == 256 bytes */
+
+ pvid->vid_oss = 1;
+ pvid->vid_osl = (short)sec2blk((stat.st_size - 0x20 + 511) / 512);
+
+ lseek(exe_file,0x14,SEEK_SET);
+ read(exe_file,&exe_addr,4);
+ {
+ union {
+ struct {
+ short osa_u;
+ short osa_l;
+ } osa_u_l;
+ int osa;
+ } u;
+ u.osa = exe_addr;
+ pvid->vid_osa_u = u.osa_u_l.osa_u;
+ pvid->vid_osa_l = u.osa_u_l.osa_l;
+ }
+ pvid->vid_cas = 1;
+ pvid->vid_cal = 1;
+ /* do not want to write past end of structure, not null terminated */
+ strcpy(pvid->vid_mot,"MOTOROL");
+ pvid->vid_mot[7] = 'A';
+
+ write(tape_vid,pvid,sizeof(struct vid));
+
+ free(pvid);
+
+ pcfg = (struct cfg *) malloc (sizeof(struct cfg));
+
+ memset(pcfg,0,sizeof(struct cfg));
+
+ pcfg->cfg_rec = 0x100;
+ pcfg->cfg_psm = 0x200;
+
+ write(tape_vid,pcfg,sizeof(struct cfg));
+
+ free(pcfg);
+
+ copy_exe(exe_file,tape_exe);
+ close (exe_file);
+ close (tape_vid);
+ close (tape_exe);
+}
+
+#define BUF_SIZ 512
+copy_exe(exe_file,tape_exe)
+{
+ char *buf;
+ int cnt = 0;
+
+ buf = (char *)malloc (BUF_SIZ);
+
+ lseek (exe_file,0x20,SEEK_SET);
+ while (BUF_SIZ == (cnt = read(exe_file, buf , BUF_SIZ))) {
+ write (tape_exe,buf,cnt);
+ }
+ memset (&buf[cnt],0,BUF_SIZ-cnt);
+ write (tape_exe,buf,BUF_SIZ);
+}
--- /dev/null
+STRIP_AOUT_HDR=rmaouthdr
+all: bootst.bug
+STRIP=-s
+SRCS=bootst.c
+S=${.CURDIR}/../../../..
+
+CFLAGS+=-I${.CURDIR}/../../include -I${.CURDIR}/${MACHINE_ARCH}
+
+.include "${S}/arch/${MACHINE}/stand/libbug/Makefile.inc"
+.include "${S}/arch/${MACHINE}/stand/bugcrt/Makefile.inc"
+.include "${S}/lib/libsa/Makefile.inc"
+.include "${S}/lib/libc_sa/Makefile.inc"
+.include "${S}/lib/libkern/Makefile.inc"
+
+LDADD+=${LIBBUG} ${SA_LIB} ${C_SA_LIB} ${KERNLIB}
+
+bootst.bug: bootst.o ${LDADD} ${BUGCRT}
+ ${LD} ${STRIP} -N -T 0x3F0000 ${BUGCRT} bootst.o ${LDADD} -o bootst.bug
+ ${.CURDIR}/../wrtvid/wrtvid bootst.bug
+
+clean:
+ rm -f a.out *.core
+ rm -f bootst.o bootst.bug stboot bootst
+
+install:
+ install -c -m 555 -g bin -o bin bootst stboot /usr/mdec/
+
+.include <bsd.prog.mk>
--- /dev/null
+#include "bug.h"
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/exec.h>
+/*
+#include <sys/exec_aout.h>
+*/
+
+#define KERNEL_LOAD_ADDRESS ((void *)0x4000)
+#define BUG_BLOCK_SIZE 512
+#define VERSION 0x0000
+
+#define RB_NOSYM 0x400
+
+
+
+void memset(void *,char,size_t);
+void printf(char *,...);
+void parse_args(struct bugargs *pbugargs);
+int read_tape_block(short ctrl, short dev, short *status, void *addr,
+ int *cnt, int blk_num, unsigned char *flags,int verbose);
+int load_kern();
+
+struct kernel {
+ void *entry;
+ void *symtab;
+ void *esym;
+ int bflags;
+ int bdev;
+ char *kname;
+ void *smini;
+ void *emini;
+ u_int end_loaded;
+} kernel;
+
+typedef (* kernel_entry)(struct bugargs *,struct kernel *);
+
+void main(struct bugargs *pbugargs)
+{
+ kernel_entry addr;
+
+ /*
+ print_bugargs(pbugargs);
+ print_time();
+ print_brdid();
+ print_memory();
+ */
+ parse_args(pbugargs);
+ if (1 == load_kern(pbugargs)) {
+ printf("unsuccessful in loading kernel\n\r");
+ } else {
+ addr = kernel.entry;
+ printf("kernel loaded at %x\n\r",addr);
+ printf("kernel.entry %x\n\r",kernel.entry);
+ printf("kernel.symtab %x\n\r",kernel.symtab);
+ printf("kernel.esym %x\n\r",kernel.esym);
+ printf("kernel.bflags %x\n\r",kernel.bflags);
+ printf("kernel.bdev %x\n\r",kernel.bdev);
+ if (kernel.kname) {
+ printf("kernel.kname <%s>\n\r",kernel.kname);
+ } else {
+ printf("kernel.kname <null>\n\r");
+ }
+ printf("kernel.end_loaded %x\n\r",kernel.end_loaded);
+ if (kernel.bflags & RB_MINIROOT) {
+ loadmini(kernel.end_loaded,pbugargs);
+ }
+ printf("kernel.smini %x\n\r",kernel.smini);
+ printf("kernel.emini %x\n\r",kernel.emini);
+ printf("kernel.end_loaded %x\n\r",kernel.end_loaded);
+ if (*pbugargs->arg_start == 'e')
+ bug_return();
+ (addr)(pbugargs,&kernel);
+ }
+
+ return;
+}
+int
+read_tape_block(short ctrl, short dev, short *status, void *addr,
+ int *cnt, int blk_num, unsigned char *flags,int verbose)
+{
+ struct bug_dskio dio;
+ int ret;
+
+ dio.ctrl_lun = ctrl;
+ dio.dev_lun = dev;
+ dio.status = *status;
+ dio.pbuffer = addr;
+ dio.blk_num = blk_num;
+ dio.blk_cnt = *cnt * 2;
+ dio.flag = *flags;
+ dio.addr_mod = 0;
+
+ if (verbose){
+ printf("saddr %x eaddr %x", dio.pbuffer,
+ (int)dio.pbuffer + (dio.blk_cnt * BUG_BLOCK_SIZE/2 ));
+ }
+
+ ret = bug_diskrd(&dio);
+
+ *status = dio.status;
+ *cnt = dio.blk_cnt/2;
+ if (verbose) {
+ printf("status %x ret %d ",*status, ret);
+ printf("flags %x\n\r",*flags);
+ }
+ return ret;
+}
+int load_kern(struct bugargs *pbugargs)
+{
+ int ret;
+ char *addr;
+ unsigned char flags;
+ short status = 0;
+ int verbose = 0;
+ int blk_num;
+ struct exec *pexec;
+ int magic;
+ int *esym;
+ int *symtab;
+ int cnt, len;
+
+ blk_num = 0;
+ flags = IGNORE_FILENUM ;
+ cnt = 512 / BUG_BLOCK_SIZE;
+ addr = KERNEL_LOAD_ADDRESS;
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, &status, addr,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0) {
+ printf("unable to load kernel\n\r");
+ return 1;
+ }
+ pexec = (struct exec *) addr;
+ if ((N_GETMID(*pexec) != MID_M68K) &&
+ ( N_GETMID(*pexec) != MID_M68K4K ))
+ {
+ printf("invalid mid on kernel\n\r");
+ return 1;
+ }
+ {
+ short *pversion = (void *)0x4020;
+ if (VERSION != *pversion) {
+ printf("invalid version of kernel/loader\n\r");
+ bug_return();
+ }
+ }
+ magic = N_GETMAGIC(*pexec);
+ switch (magic) {
+ case ZMAGIC:
+ break;
+ case NMAGIC:
+ printf ("NMAGIC not yet supported");
+ case OMAGIC:
+ case QMAGIC:
+ default:
+ printf("Unknown or unsupported magic type <%x>\n\r",
+ magic);
+ return 1;
+ break;
+ }
+ if ( magic == ZMAGIC ) {
+
+ status = 0;
+ /* 2nd block of exe */
+ addr += 512;
+
+ if ((int)pexec->a_entry != (int)KERNEL_LOAD_ADDRESS + 0x22) {
+ printf ("warning kernel start address not %x, %x\n\r",
+ (int)KERNEL_LOAD_ADDRESS + 0x22,pexec->a_entry);
+ printf ("kernel loaded at %x\n\r",KERNEL_LOAD_ADDRESS);
+
+ }
+ printf ("text 0x%x data 0x%x bss 0x%x\n\r",
+ pexec->a_text, pexec->a_data, pexec->a_bss);
+
+ len = (pexec->a_text - 512) ; /* XXX */
+ len += (pexec->a_data );
+
+ printf ("loading [ %x + %x ",pexec->a_text,pexec->a_data);
+
+ cnt = (len + BUG_BLOCK_SIZE -1)/ BUG_BLOCK_SIZE;
+ flags = IGNORE_FILENUM ;
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, &status, addr,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0 || cnt != (len + BUG_BLOCK_SIZE -1)/ BUG_BLOCK_SIZE) {
+ printf("unable to load kernel\n\r");
+ return 1;
+ }
+ addr += len;
+
+ /* Skip over text and data and zero bss. */
+ len = pexec->a_bss;
+ printf ("+ %x",len);
+ memset (KERNEL_LOAD_ADDRESS + (pexec->a_text + pexec->a_data),
+ 0, pexec->a_bss);
+ addr +=len;
+
+ if (pexec->a_syms != 0 && !(kernel.bflags & RB_NOSYM)) {
+ printf (" + [ %x",pexec->a_syms);
+ /* align addr */
+#if 0
+#define ALIGN_F 0x200
+ addr = (void *)((((int)addr + ALIGN_F -1)/ALIGN_F) * ALIGN_F);
+#endif
+ addr += 4; /* skip over _end symbol */
+ symtab = (void *)pexec->a_syms;
+ len = pexec->a_syms;
+ cnt = (len+(BUG_BLOCK_SIZE-1)) / BUG_BLOCK_SIZE;
+ flags = IGNORE_FILENUM ;
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, &status, addr,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0 || cnt != (len+(BUG_BLOCK_SIZE-1)) / BUG_BLOCK_SIZE)
+ {
+ printf("unable to load kernel\n\r");
+ return 1;
+ }
+
+ /* this value should have already been loaded XXX */
+ esym = (void *) ((u_int)addr + pexec->a_syms);
+ if ((int)addr +(cnt * BUG_BLOCK_SIZE) <= (int) esym) {
+ printf("missed loading count of symbols\n\r");
+ return 1;
+ }
+ addr +=cnt * BUG_BLOCK_SIZE;
+
+
+ len = *esym;
+#if 0
+ printf("start load %x end load %x %x\n\r", addr,
+ len, addr +len);
+ printf("esym %x *esym %x\n\r",esym, len);
+#endif
+ /* dont load tail of already loaded */
+ len -= (u_int)addr - (u_int)esym;
+
+ if (len > 0) {
+ printf(" + %x",*esym);
+ esym = (void *)(addr + len);
+ cnt = (len+(BUG_BLOCK_SIZE-1)) / BUG_BLOCK_SIZE;
+ flags = IGNORE_FILENUM ;
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, &status, addr,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0 ||
+ cnt != (len+(BUG_BLOCK_SIZE-1)) / BUG_BLOCK_SIZE)
+ {
+ printf("unable to load kernel\n\r");
+ return 1;
+ }
+ addr += len;
+ printf(" ]");
+ } else {
+ printf("+ %x ]",*esym);
+ }
+ esym = (int *)(((int)esym) + *esym);
+
+ kernel.symtab = symtab;
+ kernel.esym = esym;
+ } else {
+ kernel.symtab = 0;
+ kernel.esym = 0;
+ }
+ kernel.end_loaded = (int)addr;
+ flags = IGNORE_FILENUM | END_OF_FILE;
+ cnt = 1000;
+ printf ("removing pad [");
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, &status, addr,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0) {
+ printf("unable to load kernel\n\r");
+ return 1;
+ }
+ printf (" %d ]",cnt * BUG_BLOCK_SIZE);
+
+ printf("]\n\r");
+ }
+
+
+ kernel.entry = (void *)pexec->a_entry;
+ return 0;
+}
+loadmini(u_int addr,struct bugargs *pbugargs)
+{
+ int ret;
+ unsigned char flags;
+ short status = 0;
+ int verbose = 0;
+ int blk_num;
+ int cnt;
+ blk_num = 3;
+ /*
+ flags = IGNORE_FILENUM | END_OF_FILE;
+ */
+ /* align addr to some boundary */
+#define ALIGN_F 0x4
+ addr = (u_int)((((int)addr + ALIGN_F -1)/ALIGN_F) * ALIGN_F);
+#undef ALIGN_F
+ flags = END_OF_FILE;
+ cnt = 6144; /* some abserdly large value. (3meg / 512) */
+ printf("loading miniroot[ ");
+ ret = read_tape_block(4, pbugargs->dev_lun, &status, (void*)addr,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0) {
+ printf("unable to load miniroot\n\r");
+ return 1;
+ }
+ kernel.smini = (void *)addr;
+ printf("%d ]\n\r",(BUG_BLOCK_SIZE * cnt));
+ kernel.emini = (void*)((u_int)addr + (BUG_BLOCK_SIZE * cnt));
+ kernel.end_loaded = (u_int)kernel.emini;
+}
+void
+parse_args(struct bugargs *pargs)
+{
+ char * ptr = pargs->arg_start;
+ char c, *name;
+ int howto;
+ howto = ( 0 | RB_DFLTROOT );
+ name = NULL;
+
+ if (pargs->arg_start != pargs->arg_end) {
+ while (c = *ptr) {
+ while (c == ' ')
+ c = *++ptr;
+ if (!c)
+ return;
+ if (c == '-')
+ while ((c = *++ptr) && c != ' ') {
+ if (c == 'a')
+ howto |= RB_ASKNAME;
+ else if (c == 'b')
+ howto |= RB_HALT;
+ else if (c == 'y')
+ howto |= RB_NOSYM;
+#ifdef CHECKSUM
+ else if (c == 'c')
+ cflag = 1;
+#endif
+ else if (c == 'd')
+ howto |= RB_KDB;
+ else if (c == 'm')
+ howto |= RB_MINIROOT;
+ else if (c == 'r')
+/* change logic to have force root to config device UNLESS arg given */
+ howto &= ~RB_DFLTROOT;
+ else if (c == 's')
+ howto |= RB_SINGLE;
+ }
+ else {
+ name = ptr;
+ while ((c = *++ptr) && c != ' ');
+ if (c)
+ *ptr++ = 0;
+ }
+ }
+ if (RB_NOSYM & howto) printf("RB_NOSYM\n\r");
+ if (RB_AUTOBOOT & howto) printf("RB_AUTOBOOT\n\r");
+ if (RB_SINGLE & howto) printf("RB_SINGLE\n\r");
+ if (RB_NOSYNC & howto) printf("RB_NOSYNC\n\r");
+ if (RB_HALT & howto) printf("RB_HALT\n\r");
+ if (RB_DFLTROOT & howto) printf("RB_DFLTROOT\n\r");
+ if (RB_KDB & howto) printf("RB_KDB\n\r");
+ if (RB_RDONLY & howto) printf("RB_RDONLY\n\r");
+ if (RB_DUMP & howto) printf("RB_DUMP\n\r");
+ if (RB_MINIROOT & howto) printf("RB_MINIROOT\n\r");
+
+ }
+ kernel.bflags = howto;
+ kernel.kname = name;
+}
+
--- /dev/null
+OBJ=bugcrt.o
+CFLAGS+=-I${.CURDIR}/../include
+CFLAGS+=-I${.CURDIR}/../..
+CFLAGS+=-I/usr/src/sys
+CFLAGS+=-fwritable-strings
+
+SRCS=bugcrt.c
+all: bugcrt.o
+
+.include <bsd.prog.mk>
--- /dev/null
+#include "bug.h"
+
+asm (" text");
+/*asm ("_stack: word _stack0xFC0000; stack");*/
+asm ("stack: word stack");
+asm (" word _start");
+asm (" align 8");
+
+struct bugenv bugenv;
+extern char *end, *edata;
+
+start()
+{
+ register int dlun asm("r2");
+ register int clun asm("r3");
+ register int ipl asm("r4");
+ register int (*entryptr)() asm("r6");
+ register int *cfg asm("r7");
+ register char *strstr asm("r8");
+ register char *endstr asm("r9");
+ int i;
+ char *str;
+
+asm ("; enable SFU1");
+asm (" ldcr r10,cr1");
+asm (" xor r10,r10,0x8");
+asm (" stcr r10,cr1");
+
+ bugenv.clun = clun;
+ bugenv.dlun = dlun;
+ bugenv.ipl = ipl;
+ bugenv.entry= entryptr;
+
+ bzero(&edata,((char *)&end - (char *)&edata));
+ for (str = strstr, i = 0; str <= strstr; str++, i++) {
+ bugenv.bootargs[i] = *str;
+ }
+ bugenv.bootargs[i] = 0;
+
+ main(&bugenv);
+ bugreturn();
+}
--- /dev/null
+all: hello
+SRCS= hello.c
+OBJS= hello.o
+
+CFLAGS+=-I${.CURDIR}/include -I${.CURDIR}/${MACHINE_ARCH}
+CFLAGS+=-I${.CURDIR}/../include -I${.CURDIR}/../.. -I/usr/src/sys
+CFLAGS+=-fwritable-strings
+
+LIBBUG!= cd $(.CURDIR)/../libbug; \
+ printf "xxx:\n\techo \$${.OBJDIR}/libbug.a\n" | ${MAKE} -r -s -f - xxx
+
+BUGCRT!= cd $(.CURDIR)/../bugcrt; \
+ printf "xxx:\n\techo \$${.OBJDIR}/bugcrt.o\n" | ${MAKE} -r -s -f - xxx
+
+KERNCRT!= cd $(.CURDIR)/../kerncrt; \
+ printf "xxx:\n\techo \$${.OBJDIR}/kerncrt.o\n" | ${MAKE} -r -s -f - xxx
+
+LDADD+=${LIBBUG} /usr/local/lib/libgcc.a
+
+hello: $(OBJS) ${LIBBUG}
+ ${LD} -x -Ttext 10020 ${KERNCRT} $(OBJS) ${LDADD} -o ${.TARGET}
+clean:
+ rm -f a.out *.core
+ rm -f hello.o hello.bug hello.bug.1 hello.bug.2
+
+.include <bsd.prog.mk>
--- /dev/null
+#include "bug.h"
+#include "bugio.h"
+
+void putchar __P((char));
+int bcd2int __P((unsigned int));
+
+void
+putchar(char c)
+{
+ bugoutchr(c);
+}
+
+main(struct bugenv *env)
+{
+ struct bugrtc rtc;
+ struct bugbrdid brdid;
+
+ bugrtcrd(&rtc);
+ printf("From RTC:\n");
+ printf("Year %d\tMonth %d\tDay %d\tDay of Week %d\n",
+ bcd2int(rtc.Y), bcd2int(rtc.M), bcd2int(rtc.D), bcd2int(rtc.d));
+ printf("Hour %d\tMin %d\tSec %d\tCal %d\n",
+ bcd2int(rtc.H), bcd2int(rtc.m), bcd2int(rtc.s), bcd2int(rtc.c));
+ printf("From BRDID:\n");
+ bugbrdid(&brdid);
+/* printf("Eye catcher %c%c%c%c\n", brdid.eye[0], brdid.eye[1],
+ brdid.eye[2], brdid.eye[3]); */
+ printf("Board no %d (%d) \tsuffix %c%c\n", bcd2int(brdid.brdno),
+ brdid.brdno, brdid.brdsuf[0], brdid.brdsuf[1]);
+/* printf("Clun %x\tdlun %x\n", brdid.clun, brdid.dlun); */
+ return 0;
+}
+
+ipow(int base, int i)
+{
+ int cnt = 1;
+ while (i--) {
+ cnt *= base;
+ }
+ return cnt;
+}
+
+int
+bcd2int(unsigned int i)
+{
+ unsigned val = 0;
+ int cnt = 0;
+ while (i) {
+ val += (i&0xf) * ipow(10,cnt);
+ cnt++;
+ i >>= 4;
+ }
+ return val;
+}
--- /dev/null
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "vid.h"
+
+#define sec2blk(x) ((x) * 2)
+#define BUF_SIZ 512
+
+main(int argc, char **argv)
+{
+ struct vid *pvid;
+ struct cfg *pcfg;
+ struct stat stat;
+ int exe_file;
+ int tape_vid;
+ int tape_exe;
+ char *filename;
+ char fileext[256];
+ char hdrbuf[BUF_SIZ];
+
+ if (argc == 0){
+ filename = "a.out";
+ } else {
+ filename = argv[1];
+ }
+ exe_file = open(filename, O_RDONLY,0444);
+ if (exe_file == -1)
+ {
+ printf("file %s does not exist\n",filename);
+ exit(2);
+ }
+ sprintf (fileext,"%s%s",filename,".1");
+ tape_vid = open(fileext, O_WRONLY|O_CREAT|O_TRUNC,0644);
+ sprintf (fileext,"%s%s",filename,".2");
+ tape_exe = open(fileext, O_WRONLY|O_CREAT|O_TRUNC,0644);
+
+ lseek(exe_file,0,SEEK_SET);
+ memset (hdrbuf,0,BUF_SIZ);
+ read(exe_file,hdrbuf, 0x20); /* read the header */
+
+ write(tape_vid,hdrbuf,BUF_SIZ);
+
+ copy_exe(exe_file,tape_exe);
+ close (exe_file);
+ close (tape_vid);
+ close (tape_exe);
+}
+
+copy_exe(exe_file,tape_exe)
+{
+ char *buf;
+ int cnt = 0;
+
+ buf = (char *)malloc (BUF_SIZ);
+
+ lseek (exe_file,0x20,SEEK_SET);
+ while (BUF_SIZ == (cnt = read(exe_file, buf , BUF_SIZ))) {
+ write (tape_exe,buf,cnt);
+ }
+ memset (&buf[cnt],0,BUF_SIZ-cnt);
+ write (tape_exe,buf,BUF_SIZ);
+}
--- /dev/null
+struct bugenv {
+ int clun;
+ int dlun;
+ int ipl;
+ int (*entry)();
+ char bootargs[256];
+};
+
--- /dev/null
+#include "sys/cdefs.h"
+
+struct bugdisk_io {
+ char clun;
+ char dlun;
+ short status;
+ void *addr;
+ int blkno;
+#define fileno blkno
+ short nblks;
+ char flag;
+#define FILEMARKFLAG 0x80
+#define IGNOREFILENO 0x02
+#define ENDOFFILE 0x01
+ char am;
+};
+
+/* values are in BCD {upper nibble+lower nibble} */
+
+struct bugrtc {
+ unsigned char Y;
+ unsigned char M;
+ unsigned char D;
+ unsigned char d;
+ unsigned char H;
+ unsigned char m;
+ unsigned char s;
+ unsigned char c;
+};
+
+/* Board ID - lots of info */
+
+struct bugbrdid {
+ unsigned char eye[4];
+ char rev;
+ char month;
+ char day;
+ char year;
+ short packetsize;
+ short dummy;
+ short brdno;
+ unsigned char brdsuf[2];
+ char options[3];
+ char family:4;
+ char cpu:4;
+ short clun;
+ short dlun;
+ short type;
+ short dev;
+ int option;
+};
+
+char buginchr __P((void));
+int buginstat __P((void));
+int bugoutchr __P((unsigned char));
+int bugoutstr __P((char *, char *));
+int bugpcrlf __P((void));
+int bugdskrd __P((struct bugdisk_io *));
+int bugdskwr __P((struct bugdisk_io *));
+int bugrtcrd __P((struct bugrtc *));
+int bugreturn __P((void));
+int bugbrdid __P((struct bugbrdid *));
--- /dev/null
+# $Id: Makefile,v 1.1.1.1 1997/03/03 19:30:46 rahnds Exp $
+
+CFLAGS+=-I${.CURDIR}/../include -I${.CURDIR}/${MACHINE_ARCH}
+
+.PATH: ${.CURDIR}/${MACHINE_ARCH}
+
+SRCS= kerncrt.c
+
+OBJS=${SRCS:.c=.o}
+
+all: ${OBJS}
+
+kerncrt.o: ${SRCS}
+ ${CC} ${CFLAGS} -c -O ${.ALLSRC}
+ ${LD} -x -r ${.TARGET}
+ mv a.out ${.TARGET}
+
+install:
+
+lint tags:
+
+.include <bsd.prog.mk>
--- /dev/null
+#include "bug.h"
+start(struct bugenv *bugarea)
+{
+ main(bugarea);
+ bugreturn();
+}
+
+__main()
+{
+ return;
+}
--- /dev/null
+#include "bugargs.h"
+#define volatile
+int _DYNAMIC;
+start(struct bugargs *bugarea)
+{
+ main(bugarea);
+ bug_return();
+ /* NOTREACHED */
+}
--- /dev/null
+LIB=bug
+
+CFLAGS+=-I${.CURDIR}/../include
+CFLAGS+=-I${.CURDIR}/../../include
+CFLAGS+=-I${.CURDIR}/../..
+CFLAGS+=-I/usr/src/sys
+CFLAGS+=-fwritable-strings
+
+NOPIC=
+
+SRCS+=bug.c
+#SRCS+=bugcrt.c bugio.c main.c
+
+.if (${MACHINE_ARCH} == "m68k")
+SRCS+=mvme147.c bcopy.c bzero.c
+.endif
+.if (${MACHINE_ARCH} == "m88k")
+SRCS+=bcopy.c bzero.c printf.c bugsupp.c
+.endif
+
+.PATH: ${.CURDIR}/../../../../lib/libkern ${.CURDIR}/../../../../lib/libsa ${.CURDIR}/${MACHINE_ARCH}
+
+all: bugio.o
+
+#bugio.o: bugio.c
+# ${CC} ${CFLAGS} -c -O ${.ALLSRC}
+# ${LD} -x -r ${.TARGET}
+# mv a.out ${.TARGET}
+
+.include <bsd.lib.mk>
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include "bug.h"
+
+#define _INCHR "00"
+#define _INSTAT "01"
+#define _INLN "02"
+#define _READSTR "03"
+#define _READLN "04"
+#define _DSKRD "16"
+#define _DSKWR "17"
+#define _DSKCFIG "18"
+#define _DSKFMT "20"
+#define _DSKCTRL "12"
+#define _OUTCHR "32"
+#define _OUTSTR "33"
+#define _OUTLN "34"
+#define _WRITE "35"
+#define _WRITELN "36"
+#define _DELAY "67"
+#define _RTC_RD "83"
+#define _RETURN "99"
+#define _BRD_ID "112"
+
+/* BUG - tty routines */
+
+#define BUG_CALL(x) \
+ asm volatile ("or r9,r0," x); \
+ asm volatile ("tb0 0,r0,496");
+
+char bug_inchr()
+{
+ register char a;
+ asm volatile ("sub r31,r31,4");
+ BUG_CALL(_INCHR);
+ asm volatile ("or %0,r0,r2" : "=r" (a));
+ return a;
+}
+
+/* returns 0 if no characters ready to read */
+int bug_instat()
+{
+ short ret;
+ BUG_CALL(_INSTAT);
+ asm volatile ("or %0,r0,r2" : "=r" (ret));
+ return (!(ret & 0x4));
+
+}
+
+void bug_outchr(char a)
+{
+ asm volatile ("or r2, r0, %0" : :"r" (a));
+ BUG_CALL(_OUTCHR);
+ return;
+}
+
+void bug_outstr(char *pstrb, char *pstre)
+{
+ asm volatile ("or r2,r0,%0": : "r" (pstrb) );
+ asm volatile ("or r3,r0,%0": : "r" (pstre) );
+ BUG_CALL(_OUTSTR);
+ return;
+}
+
+void bug_outln(char *pstrb, char *pstre)
+{
+ asm volatile ("or r2,r0,%0": : "r" (pstrb) );
+ asm volatile ("or r3,r0,%0": : "r" (pstre) );
+ BUG_CALL(_OUTLN);
+ return;
+}
+
+/* BUG - disk routines */
+
+/* returns 0: success, nonzero: error */
+int bug_diskrd(bug_dskio *arg)
+{
+ int ret;
+ asm volatile ("or r2,r0,%0": : "r" (arg) );
+ BUG_CALL(_DSKRD);
+ return (!(ret & 0x4));
+}
+/* returns 0: success, nonzero: error */
+int bug_diskwr(bug_dskio *arg)
+{
+ int ret;
+ asm volatile ("or r2,r0,%0": : "r" (arg) );
+ BUG_CALL(_DSKWR);
+ return (!(ret & 0x4));
+}
+#ifdef NOTYET
+bug_diskcfig()
+{
+
+}
+bug_diskfmt(){}
+bug_diskctrl(){}
+#endif
+
+/* BUG - timing routine */
+
+void bug_delay(int delay_msec)
+{
+ asm volatile ("or r2,r0,%0": : "r" (delay_msec) );
+ BUG_CALL(_DELAY);
+ return ;
+}
+
+/* BUG - return to bug routine */
+
+void bug_return()
+{
+ BUG_CALL(_RETURN);
+ /*NOTREACHED*/
+}
+
+/* BUG - query board routines */
+
+struct bug_brdid *bug_brdid()
+{
+ struct bug_brdid *pbrd_id;
+ BUG_CALL(_BRD_ID);
+ asm volatile ("or %0,r0,r2": "=r" (pbrd_id):);
+ return pbrd_id;
+}
+void bug_rtc_rd(struct bug_time *ptime)
+{
+ asm volatile ("or r2,r0,%0": : "r" (ptime));
+ BUG_CALL(_RTC_RD);
+ return;
+}
--- /dev/null
+#include "bugio.h"
+
+#define INCHR "0x0000"
+#define INSTAT "0x0001"
+#define INLN "0x0002"
+#define READSTR "0x0003"
+#define READLN "0x0004"
+#define DSKRD "0x0010"
+#define DSKWR "0x0011"
+#define DSKCFIG "0x0012"
+#define OUTCHR "0x0020"
+#define PCRLF "0x0026"
+#define TMDISP "0x0042"
+#define DELAY "0x0043"
+#define RTC_DSP "0x0052"
+#define RTC_RD "0x0053"
+#define RETURN "0x0063"
+#define BRD_ID "0x0070"
+#define BUGTRAP "0x01F0"
+
+char
+buginchr(void)
+{
+ register int cc asm("r2");
+ asm("or r9,r0," INCHR);
+ asm("tb0 0,r0,0x1F0");
+ /*asm("or %0,r0,r2" : "=r" (cc) : );*/
+ return ((char)cc & 0xFF);
+}
+
+/* return 1 if not empty else 0 */
+
+buginstat(void)
+{
+ int ret;
+ asm("or r9,r0," INSTAT);
+ asm("tb0 0,r0,0x1F0");
+ asm("or %0,r0,r2" : "=r" (ret) : );
+ return (ret & 0x40 ? 1 : 0);
+}
+
+bugoutchr(unsigned char c)
+{
+ unsigned char cc;
+
+ if ((cc = c) == '\n') {
+ bugpcrlf();
+ return;
+ }
+ asm("or r2,r0,%0" : : "r" (cc));
+ asm("or r9,r0," OUTCHR);
+ asm("tb0 0,r0,0x1F0");
+}
+
+bugpcrlf(void)
+{
+ asm("or r9,r0," PCRLF);
+ asm("tb0 0,r0,0x1F0");
+}
+/* return 0 on success */
+
+bugdskrd(struct bugdisk_io *arg)
+{
+ int ret;
+ asm("or r9,r0, " DSKRD);
+ asm("tb0 0,r0,0x1F0");
+ asm("or %0,r0,r2" : "=r" (ret) : );
+ return ((ret&0x4) == 0x4 ? 1 : 0);
+}
+
+/* return 0 on success */
+
+bugdskwr(struct bugdisk_io *arg)
+{
+ int ret;
+ asm("or r9,r0, " DSKWR);
+ asm("tb0 0,r0,0x1F0");
+ asm("or %0,r0,r2" : "=r" (ret) : );
+ return ((ret&0x4) == 0x4 ? 1 : 0);
+}
+
+bugrtcrd(struct bugrtc *rtc)
+{
+ asm("or r9,r0, " RTC_RD);
+ asm("tb0 0,r0,0x1F0");
+}
+
+bugreturn(void)
+{
+ asm("or r9,r0, " RETURN);
+ asm("tb0 0,r0,0x1F0");
+}
+
+bugbrdid(struct bugbrdid *id)
+{
+ struct bugbrdid *ptr;
+ asm("or r9,r0, " BRD_ID);
+ asm("tb0 0,r0,0x1F0");
+ asm("or %0,r0,r2" : "=r" (ptr) : );
+ bcopy(ptr, id, sizeof(struct bugbrdid));
+}
--- /dev/null
+#include "bug.h"
+
+int putchar(char a)
+{
+ bug_outchr(a);
+}
+__main(){}
--- /dev/null
+# $Id: Makefile,v 1.1.1.1 1997/03/03 19:31:01 rahnds Exp $
+
+SUBDIR= netboot sboot bootsd bootst libsa bugcrt libbug wrtvid
+
+.include <bsd.subdir.mk>
--- /dev/null
+# $Id: Makefile.inc,v 1.1.1.1 1997/03/03 19:31:01 rahnds Exp $
+
+MDEC_DIR?=/usr/mdec
--- /dev/null
+# from: @(#)Makefile 8.1 (Berkeley) 6/10/93
+# $Id: Makefile,v 1.1.1.1 1997/03/03 19:31:02 rahnds Exp $
+
+RELOC=0x3F0000
+
+S= ${.CURDIR}/../../../..
+DEFS= -DSTANDALONE -DCOMPAT_NOLABEL # -DROMPRF
+INCPATH=-I${.CURDIR} -I${.CURDIR}/../../include -I${S} -I${S}/lib/libsa
+CFLAGS= -O2 ${INCPATH} ${DEFS} ${COPTS}
+CLEANFILES+=sdboot bootsd bootsd.bug
+
+#.PATH: ${S}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
+#.PATH: ${S}/lib/libsa
+
+.include "${S}/arch/${MACHINE}/stand/libsa/Makefile.inc"
+.include "${S}/arch/${MACHINE}/stand/libbug/Makefile.inc"
+.include "${S}/arch/${MACHINE}/stand/bugcrt/Makefile.inc"
+.include "${S}/arch/${MACHINE}/stand/wrtvid/Makefile.inc"
+
+SRCS= boot.c filesystem.c bugdev.c version.c
+
+LIBS= ${LIBSA} ${LIBBUG}
+
+OBJS= ${SRCS:N*.h:R:S/$/.o/g}
+
+BOOTS= bootsd sdboot
+ALL= ${BOOTS}
+
+all: ${ALL}
+
+devopen.o machdep.o: Makefile
+
+bootsd.bug: ${OBJS} ${BUGCRT} ${LIBS}
+ ${LD} -N -T ${RELOC} ${BUGCRT} ${OBJS} ${LIBS} -o $@
+ @size bootsd.bug
+
+bootsd sdboot: bootsd.bug ${WRTVID}
+ cp bootsd.bug bootsd.bin
+ strip bootsd.bin
+ @if [ `size bootsd.bin | awk 'BEGIN {getline} {print $$1+$$2;}'` -gt 7168 ];\
+ then\
+ echo BOOTBLOCKS ARE TOO BIG;\
+ fail;\
+ fi
+ ${WRTVID} bootsd.bin
+
+install:
+ install -c -m 555 -g bin -o bin ${BOOTS} ${DESTDIR}${MDEC_DIR}
+
+.include <bsd.prog.mk>
--- /dev/null
+In short: stick the the bootblocks into a partition with
+something like:
+ cat sdboot bootsd > /dev/rsd0c
--- /dev/null
+/* $Id: boot.c,v 1.1.1.1 1997/03/03 19:31:02 rahnds Exp $ */
+
+/*-
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ *
+ * Copyright (c) 1982, 1986, 1990, 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.
+ *
+ * from: @(#)boot.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/reboot.h>
+#include <a.out.h>
+#include <machine/prom.h>
+#include "stand.h"
+
+void copyunix __P((int io, char *addr));
+void parse_args __P((void));
+
+int debug;
+int netif_debug;
+#define RB_NOSYM 0x400
+
+/*
+ * Boot device is derived from ROM provided information.
+ */
+extern char *version;
+u_long esym;
+char *strtab;
+int strtablen;
+#if 0
+struct nlist *nlp, *enlp;
+#endif
+
+struct kernel {
+ void *entry;
+ void *symtab;
+ void *esym;
+ int bflags;
+ int bdev;
+ char *kname;
+ void *smini;
+ void *emini;
+ u_int end_loaded;
+} kernel;
+
+extern struct mvmeprom_args bugargs;
+
+int
+main()
+{
+ struct exec x;
+ char *file;
+ void *addr;
+ int io, i;
+
+ printf(">> OpenBSD sdboot [%s]\n", version);
+
+ parse_args();
+ file = kernel.kname;
+
+ io = open(file, 0);
+ if (io < 0) {
+ printf("Can't open %s: %s\n", file, strerror(errno));
+ mvmeprom_return();
+ }
+ i = read(io, (char *)&x, sizeof(x));
+ if (i != sizeof(x) || N_BADMAG(x)) {
+ printf("Bad format\n");
+ return (0);
+ }
+ /* Make load address start of page which containes "start" */
+ addr = (void *)(x.a_entry & ~0x0FFF);
+ lseek(io, 0, SEEK_SET);
+
+ printf("load %s to 0x%x\n", file, addr);
+ copyunix(io, addr);
+ return (0);
+}
+
+/*ARGSUSED*/
+void
+copyunix(io, addr)
+ int io;
+ char *addr;
+{
+ void (*entry)() = (void (*)())addr;
+ struct exec x;
+ int i, cnt;
+
+ i = read(io, (char *)&x, sizeof(x));
+ if (i != sizeof(x) || N_BADMAG(x)) {
+ printf("Bad format\n");
+ return;
+ }
+
+ printf("%x", x.a_text);
+ if (N_GETMAGIC(x) == ZMAGIC) {
+ kernel.entry = entry = (void *)x.a_entry;
+ lseek(io, 0, SEEK_SET);
+ }
+ if (read(io, (char *)addr, x.a_text) != x.a_text)
+ goto shread;
+ addr += x.a_text;
+ if (N_GETMAGIC(x) == NMAGIC)
+ while ((int)addr & CLOFSET)
+ *addr++ = 0;
+ printf("+%x", x.a_data);
+ if (read(io, addr, x.a_data) != x.a_data)
+ goto shread;
+ addr += x.a_data;
+ printf("+%x", x.a_bss);
+ for (i = 0; i < x.a_bss; i++)
+ *addr++ = 0;
+ if (x.a_syms != 0 && !(kernel.bflags & RB_NOSYM)) {
+ bcopy(&x.a_syms, addr, sizeof(x.a_syms));
+ addr += sizeof(x.a_syms);
+#if 0
+ nlp = (struct nlist *)addr;
+#endif
+ printf("+[%x+", x.a_syms);
+ if (read(io, addr, x.a_syms) != x.a_syms)
+ goto shread;
+ addr += x.a_syms;
+#if 0
+ enlp = (struct nlist *)(strtab = addr);
+#endif
+
+ if (read(io, &strtablen, sizeof(int)) != sizeof(int))
+ goto shread;
+
+ bcopy(&strtablen, addr, sizeof(int));
+ if (i = strtablen) {
+ i -= sizeof(int);
+ addr += sizeof(int);
+ cnt = read(io, addr, i);
+ if (cnt != i)
+ printf("symwarn"); /* goto shread; */
+ addr += i;
+ }
+ printf("%x]", i);
+ esym = KERNBASE +
+ (((int)addr + sizeof(int) - 1) & ~(sizeof(int) - 1));
+ kernel.symtab = (void *) x.a_syms;
+ kernel.esym = addr;
+ } else {
+ kernel.symtab = 0;
+ kernel.esym = 0;
+ }
+
+#if 0
+ while (nlp < enlp) {
+ register int strx = nlp->n_un.n_strx;
+ if (strx > strtablen)
+ continue;
+ if (strcmp(strtab+strx, "_esym") == 0) {
+ *(int*)(nlp->n_value - KERNBASE) = esym;
+ break;
+ }
+ nlp++;
+ }
+#endif
+
+ kernel.bdev = 0;
+ kernel.end_loaded = (u_int)addr;
+ kernel.smini = 0;
+ kernel.emini = 0;
+ kernel.kname = 0;
+
+ printf("=%x\n", (u_int)addr - (u_int)entry); /* XXX wrong? */
+
+#if 0
+printf("entry %x\n",kernel.entry);
+printf("symtab %x\n",kernel.symtab);
+printf("esym %x\n",kernel.esym);
+printf("bflags %x\n",kernel.bflags);
+printf("bdev %x\n",kernel.bdev);
+printf("kname %x\n",kernel.kname);
+printf("smini %x\n",kernel.smini);
+printf("emini %x\n",kernel.emini);
+printf("end_loaded %x\n",kernel.end_loaded);
+#endif
+
+ printf("start at 0x%x\n", (int)entry);
+ if (((u_long)entry &0xf) == 0x2) {
+ (entry)(&bugargs, &kernel);
+ } else {
+ /* is type fixing anything like price fixing? */
+ typedef (* kernel_start) __P((int, int, void *,void *, void *));
+ kernel_start addr;
+ addr = (void *)entry;
+ (addr)(kernel.bflags, 0, kernel.esym, kernel.smini, kernel.emini);
+ }
+ return;
+
+shread:
+ printf("short read\n");
+}
+
+struct flags {
+ char c;
+ short bit;
+} bf[] = {
+ { 'a', RB_ASKNAME },
+ { 'b', RB_HALT },
+ { 'y', RB_NOSYM },
+ { 'd', RB_KDB },
+ { 'm', RB_MINIROOT },
+ { 'r', RB_DFLTROOT },
+ { 's', RB_SINGLE },
+};
+
+void
+parse_args()
+{
+ char *name = "/netbsd", *ptr;
+ int i, howto = 0;
+ char c;
+
+ if (bugargs.arg_start != bugargs.arg_end) {
+ ptr = bugargs.arg_start;
+ while (c = *ptr) {
+ while (c == ' ')
+ c = *++ptr;
+ if (c == '\0')
+ return;
+ if (c != '-') {
+ name = ptr;
+ while ((c = *++ptr) && c != ' ')
+ ;
+ if (c)
+ *ptr++ = 0;
+ continue;
+ }
+ while ((c = *++ptr) && c != ' ') {
+ for (i = 0; i < sizeof(bf)/sizeof(bf[0]); i++)
+ if (bf[i].c == c) {
+ howto |= bf[i].bit;
+ }
+ }
+ }
+ }
+ kernel.bflags = howto;
+ kernel.kname = name;
+}
--- /dev/null
+/* $Id: bugdev.c,v 1.1.1.1 1997/03/03 19:31:02 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1993 Paul Kranenburg
+ * 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 Paul Kranenburg.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include <machine/prom.h>
+#include "stand.h"
+
+int bugscopen __P((struct open_file *, ...));
+int bugscclose __P((struct open_file *));
+int bugscioctl __P((struct open_file *, u_long, void *));
+int bugscstrategy __P((void *, int, daddr_t, size_t, void *, size_t *));
+
+void cputobsdlabel __P((struct disklabel *lp, struct cpu_disklabel *clp));
+
+struct devsw devsw[] = {
+ { "bugsc", bugscstrategy, bugscopen, bugscclose, bugscioctl },
+};
+int ndevs = (sizeof(devsw)/sizeof(devsw[0]));
+
+extern struct mvmeprom_args bugargs;
+int errno;
+
+struct bugsc_softc {
+ int fd; /* Prom file descriptor */
+ int poff; /* Partition offset */
+ int psize; /* Partition size */
+ short ctrl;
+ short dev;
+} bugsc_softc[1];
+
+int
+devopen(f, fname, file)
+ struct open_file *f;
+ const char *fname;
+ char **file;
+{
+ register struct bugsc_softc *pp = &bugsc_softc[0];
+ int error, i, dn = 0, pn = 0;
+ char *dev, *cp;
+ static char iobuf[MAXBSIZE];
+ struct disklabel sdlabel;
+
+ dev = bugargs.arg_start;
+
+ /*
+ * Extract partition # from boot device string.
+ */
+ for (cp = dev; *cp; cp++) /* void */;
+ while (*cp != '/' && cp > dev) {
+ if (*cp == ':')
+ pn = *(cp+1) - 'a';
+ --cp;
+ }
+
+ pp->fd = bugscopen(f);
+
+ if (pp->fd < 0) {
+ printf("Can't open device `%s'\n", dev);
+ return (ENXIO);
+ }
+ error = bugscstrategy(pp, F_READ, LABELSECTOR, DEV_BSIZE, iobuf, &i);
+ if (error)
+ return (error);
+ if (i != DEV_BSIZE)
+ return (EINVAL);
+
+ cputobsdlabel(&sdlabel, (struct cpu_disklabel *)iobuf);
+ pp->poff = sdlabel.d_partitions[pn].p_offset;
+ pp->psize = sdlabel.d_partitions[pn].p_size;
+
+ f->f_dev = devsw;
+ f->f_devdata = (void *)pp;
+ *file = (char *)fname;
+ return (0);
+}
+
+/* silly block scale factor */
+#define BUG_BLOCK_SIZE 256
+#define BUG_SCALE (512/BUG_BLOCK_SIZE)
+int
+bugscstrategy(devdata, func, dblk, size, buf, rsize)
+ void *devdata;
+ int func;
+ daddr_t dblk;
+ size_t size;
+ void *buf;
+ size_t *rsize;
+{
+ struct mvmeprom_dskio dio;
+ register struct bugsc_softc *pp = (struct bugsc_softc *)devdata;
+ daddr_t blk = dblk + pp->poff;
+
+ twiddle();
+
+ dio.ctrl_lun = pp->ctrl;
+ dio.dev_lun = pp->dev;
+ dio.status = 0;
+ dio.pbuffer = buf;
+ dio.blk_num = blk * BUG_SCALE;
+ dio.blk_cnt = size / BUG_BLOCK_SIZE; /* assumed size in bytes */
+ dio.flag = 0;
+ dio.addr_mod = 0;
+#ifdef 0
+ printf("bugscstrategy: size=%d blk=%d buf=%x\n", size, blk, buf);
+ printf("ctrl %d dev %d\n", dio.ctrl_lun, dio.dev_lun);
+#endif
+ mvmeprom_diskrd(&dio);
+
+ *rsize = dio.blk_cnt * BUG_BLOCK_SIZE;
+#ifdef 0
+printf("rsize %d status %x\n", *rsize, dio.status);
+#endif
+
+ if (dio.status)
+ return (EIO);
+ return (0);
+}
+
+int
+bugscopen(f)
+ struct open_file *f;
+{
+#ifdef DEBUG
+ printf("bugscopen:\n");
+#endif
+
+ f->f_devdata = (void *)bugsc_softc;
+ bugsc_softc[0].ctrl = (short)bugargs.ctrl_lun;
+ bugsc_softc[0].dev = (short)bugargs.dev_lun;
+ printf("using mvmebug ctrl %d dev %d\n",
+ bugsc_softc[0].ctrl, bugsc_softc[0].dev);
+ return (0);
+}
+
+int
+bugscclose(f)
+ struct open_file *f;
+{
+ return (EIO);
+}
+
+int
+bugscioctl(f, cmd, data)
+ struct open_file *f;
+ u_long cmd;
+ void *data;
+{
+ return (EIO);
+}
+
+void
+cputobsdlabel(lp, clp)
+ struct disklabel *lp;
+ struct cpu_disklabel *clp;
+{
+ int i;
+
+ lp->d_magic = clp->magic1;
+ lp->d_type = clp->type;
+ lp->d_subtype = clp->subtype;
+ bcopy(clp->vid_vd, lp->d_typename, 16);
+ bcopy(clp->packname, lp->d_packname, 16);
+ lp->d_secsize = clp->cfg_psm;
+ lp->d_nsectors = clp->cfg_spt;
+ lp->d_ncylinders = clp->cfg_trk; /* trk is really num of cyl! */
+ lp->d_ntracks = clp->cfg_hds;
+
+ lp->d_secpercyl = clp->secpercyl;
+ lp->d_secperunit = clp->secperunit;
+ lp->d_secpercyl = clp->secpercyl;
+ lp->d_secperunit = clp->secperunit;
+ lp->d_sparespertrack = clp->sparespertrack;
+ lp->d_sparespercyl = clp->sparespercyl;
+ lp->d_acylinders = clp->acylinders;
+ lp->d_rpm = clp->rpm;
+ lp->d_interleave = clp->cfg_ilv;
+ lp->d_trackskew = clp->cfg_sof;
+ lp->d_cylskew = clp->cylskew;
+ lp->d_headswitch = clp->headswitch;
+
+ /* this silly table is for winchester drives */
+ switch (clp->cfg_ssr) {
+ case 0:
+ lp->d_trkseek = 0;
+ break;
+ case 1:
+ lp->d_trkseek = 6;
+ break;
+ case 2:
+ lp->d_trkseek = 10;
+ break;
+ case 3:
+ lp->d_trkseek = 15;
+ break;
+ case 4:
+ lp->d_trkseek = 20;
+ break;
+ default:
+ lp->d_trkseek = 0;
+ break;
+ }
+ lp->d_flags = clp->flags;
+ for (i = 0; i < NDDATA; i++)
+ lp->d_drivedata[i] = clp->drivedata[i];
+ for (i = 0; i < NSPARE; i++)
+ lp->d_spare[i] = clp->spare[i];
+ lp->d_magic2 = clp->magic2;
+ lp->d_checksum = clp->checksum;
+ lp->d_npartitions = clp->partitions;
+ lp->d_bbsize = clp->bbsize;
+ lp->d_sbsize = clp->sbsize;
+ bcopy(clp->vid_4, &(lp->d_partitions[0]), sizeof (struct partition) * 4);
+ bcopy(clp->cfg_4, &(lp->d_partitions[4]), sizeof (struct partition) * 12);
+}
--- /dev/null
+/* $Id: filesystem.c,v 1.1.1.1 1997/03/03 19:31:02 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1993 Philip A. Nelson.
+ * 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 Philip A. Nelson.
+ * 4. The name of Philip A. Nelson may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY PHILIP NELSON ``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 PHILIP NELSON 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 <stand.h>
+#include <ufs.h>
+
+struct fs_ops file_system[] = {
+ { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat },
+};
+
+int nfsys = sizeof(file_system)/sizeof(struct fs_ops);
+
--- /dev/null
+/* $Id: version.c,v 1.1.1.1 1997/03/03 19:31:02 rahnds Exp $ */
+
+/*
+ * make a random change to this file when you want the bootblock
+ * revision to increase. like change this x to a y, or something.
+ */
+
+char *version = "$Revision: 1.1.1.1 $";
--- /dev/null
+# from: @(#)Makefile 8.1 (Berkeley) 6/10/93
+# $Id: Makefile,v 1.1.1.1 1997/03/03 19:31:03 rahnds Exp $
+
+RELOC=0x3F0000
+
+S= ${.CURDIR}/../../../..
+DEFS= -DSTANDALONE -DCOMPAT_NOLABEL # -DROMPRF
+INCPATH=-I${.CURDIR} -I${.CURDIR}/../../include -I${S} -I${S}/lib/libsa
+CFLAGS= -O2 ${INCPATH} ${DEFS} ${COPTS}
+CLEANFILES+=sdboot bootst bootst.bug
+
+#.PATH: ${S}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
+#.PATH: ${S}/lib/libsa
+
+.include "${S}/arch/${MACHINE}/stand/libsa/Makefile.inc"
+.include "${S}/arch/${MACHINE}/stand/libbug/Makefile.inc"
+.include "${S}/arch/${MACHINE}/stand/bugcrt/Makefile.inc"
+.include "${S}/arch/${MACHINE}/stand/wrtvid/Makefile.inc"
+
+SRCS= bootst.c
+
+LIBS= ${LIBSA} ${LIBBUG}
+
+OBJS= ${SRCS:N*.h:R:S/$/.o/g}
+
+BOOTS= bootst stboot
+ALL= ${BOOTS}
+
+all: ${ALL}
+
+bootst.bug: ${OBJS} ${BUGCRT} ${LIBS}
+ ${LD} -s -N -T ${RELOC} ${BUGCRT} ${OBJS} ${LIBS} -o $@
+ @size bootst.bug
+
+bootst stboot: bootst.bug ${WRTVID}
+ ${WRTVID} bootst.bug
+
+install:
+ install -c -m 555 -g bin -o bin ${BOOTS} ${DESTDIR}${MDEC_DIR}
+
+.include <bsd.prog.mk>
--- /dev/null
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/exec.h>
+#include <machine/prom.h>
+
+#define RB_NOSYM 0x400
+
+void parse_args __P((struct mvmeprom_args *pbugargs));
+int load_kern();
+int read_tape_block __P((short ctrl, short dev, short *status,
+ void *addr, int *cnt, int blk_num, u_char *flags, int verbose));
+
+struct kernel {
+ void *entry;
+ void *symtab;
+ void *esym;
+ int bflags;
+ int bdev;
+ char *kname;
+ void *smini;
+ void *emini;
+ u_int end_loaded;
+} kernel;
+
+typedef(*kernel_entry) __P((struct mvmeprom_args *, struct kernel *));
+
+int
+main(pbugargs)
+ struct mvmeprom_args *pbugargs;
+{
+ kernel_entry addr;
+
+ /*
+ print_bugargs(pbugargs);
+ print_time();
+ print_brdid();
+ print_memory();
+ */
+ parse_args(pbugargs);
+ if (load_kern(pbugargs) == 1) {
+ printf("unsuccessful in loading kernel\n");
+ } else {
+ addr = kernel.entry;
+
+ printf("kernel loaded at %x\n", addr);
+ printf("kernel.entry %x\n", kernel.entry);
+ printf("kernel.symtab %x\n", kernel.symtab);
+ printf("kernel.esym %x\n", kernel.esym);
+ printf("kernel.bflags %x\n", kernel.bflags);
+ printf("kernel.bdev %x\n", kernel.bdev);
+ if (kernel.kname)
+ printf("kernel.kname <%s>\n", kernel.kname);
+ else
+ printf("kernel.kname <null>\n");
+ printf("kernel.end_loaded %x\n", kernel.end_loaded);
+
+ if (kernel.bflags & RB_MINIROOT)
+ loadmini(kernel.end_loaded, pbugargs);
+
+ printf("kernel.smini %x\n", kernel.smini);
+ printf("kernel.emini %x\n", kernel.emini);
+ printf("kernel.end_loaded %x\n", kernel.end_loaded);
+ if (kernel.bflags & RB_HALT)
+ mvmeprom_return();
+ if (((u_long)addr &0xf) == 0x2) {
+ (addr)(pbugargs, &kernel);
+ } else {
+ /* is type fixing anything like price fixing? */
+ typedef (* kernel_start) __P((int, int, void *,void *, void *));
+ kernel_start addr1;
+ addr1 = (void *)addr;
+ (addr1)(kernel.bflags, 0, kernel.esym, kernel.smini, kernel.emini
+ );
+ }
+
+ }
+ return (0);
+}
+
+#define MVMEPROM_SCALE (512/MVMEPROM_BLOCK_SIZE)
+
+int
+read_tape_block(ctrl, dev, status, addr, cnt, blk_num, flags, verbose)
+ short ctrl;
+ short dev;
+ short *status;
+ void *addr;
+ int *cnt;
+ int blk_num;
+ u_char *flags;
+ int verbose;
+{
+ struct mvmeprom_dskio dio;
+ int ret;
+
+ dio.ctrl_lun = ctrl;
+ dio.dev_lun = dev;
+ dio.status = *status;
+ dio.pbuffer = addr;
+ dio.blk_num = blk_num;
+ dio.blk_cnt = *cnt / (512 / MVMEPROM_SCALE);
+ dio.flag = *flags;
+ dio.addr_mod = 0;
+
+ if (verbose)
+ printf("saddr %x eaddr %x", dio.pbuffer,
+ (int) dio.pbuffer + (dio.blk_cnt * MVMEPROM_BLOCK_SIZE));
+ ret = mvmeprom_diskrd(&dio);
+
+ *status = dio.status;
+ *cnt = (dio.blk_cnt / MVMEPROM_SCALE) * 512;
+ if (verbose) {
+ printf("status %x ret %d ", *status, ret);
+ printf("flags %x blocks read %x cnt %x\n",
+ *flags, dio.blk_cnt, *cnt);
+ }
+ return (ret);
+}
+#ifdef DEBUG
+int verbose = 1;
+#else
+int verbose = 0;
+#endif
+
+int
+load_kern(pbugargs)
+ struct mvmeprom_args *pbugargs;
+{
+ int ret;
+ char *addr;
+ u_char flags;
+ short status = 0;
+ int blk_num;
+ struct exec *pexec;
+ int magic;
+ int *esym;
+ int *symtab;
+ int cnt, len;
+ char buf[512];
+
+ blk_num = 2;
+ /* flags = IGNORE_FILENUM; */
+ flags = 0;
+ cnt = 512;
+printf("ctrl %x dev %x\n",pbugargs->ctrl_lun, pbugargs->dev_lun);
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, &status,
+ buf, &cnt, blk_num, &flags, verbose);
+ if (ret != 0) {
+ printf("unable to load kernel 1 status %x\n", status);
+ return (1);
+ }
+ pexec = (struct exec *) buf;
+ if (N_GETMID(*pexec) != MID_M68K &&
+ N_GETMID(*pexec) != MID_M68K4K) {
+ printf("invalid mid on kernel\n");
+ return (1);
+ }
+
+ magic = N_GETMAGIC(*pexec);
+ switch (magic) {
+ case ZMAGIC:
+ break;
+ case NMAGIC:
+ printf("NMAGIC not yet supported");
+ case OMAGIC:
+ case QMAGIC:
+ default:
+ printf("Unknown or unsupported magic type <%x>\n", magic);
+ return (1);
+ }
+ if (magic == ZMAGIC) {
+ status = 0;
+ addr = (char *) (pexec->a_entry & ~0x0FFF);
+
+ if ((int) pexec->a_entry != (int) addr + 0x22) {
+ printf("warning kernel start address not %x, %x\n",
+ (int) addr + 0x22, pexec->a_entry);
+ printf("kernel loaded at %x\n", addr);
+ }
+ bcopy(&buf, addr, 512);
+ /* 2nd block of exe */
+ addr += 512;
+
+ printf("text 0x%x data 0x%x bss 0x%x\n",
+ pexec->a_text, pexec->a_data, pexec->a_bss);
+
+ len = (pexec->a_text - 512); /* XXX */
+ len += (pexec->a_data);
+
+ printf("loading [ %x + %x ", pexec->a_text, pexec->a_data);
+
+ cnt = len;
+ flags = IGNORE_FILENUM;
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun,
+ &status, addr, &cnt, blk_num, &flags, verbose);
+ if (ret != 0 || cnt != len) {
+ printf("unable to load kernel 2 status %x\n", status);
+ return 1;
+ }
+ addr += len;
+
+ /* Skip over text and data and zero bss. */
+ len = pexec->a_bss;
+ printf("+ %x", len);
+#ifdef DEBUG
+ printf("bss %x - %x\n", addr, addr + pexec->a_bss);
+#endif
+ bzero(addr, pexec->a_bss);
+ addr += len;
+
+ if (pexec->a_syms != 0 && !(kernel.bflags & RB_NOSYM)) {
+ printf(" + [ %x", pexec->a_syms);
+ addr += 4; /* skip over _end symbol */
+ symtab = (void *) pexec->a_syms;
+ len = pexec->a_syms;
+ cnt = ((len + (512 - 1)) / 512) * 512;
+ flags = IGNORE_FILENUM;
+ ret = read_tape_block(pbugargs->ctrl_lun,
+ pbugargs->dev_lun, &status, addr,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0 || cnt != ((len + (512 - 1)) / 512) * 512) {
+ printf("unable to load kernel 3\n");
+ return 1;
+ }
+ /* this value should have already been loaded XXX */
+ esym = (void *) ((u_int) addr + pexec->a_syms);
+ if ((int) addr + cnt <= (int) esym) {
+ printf("missed loading count of symbols\n");
+ return 1;
+ }
+ addr += cnt;
+
+
+ len = *esym;
+#if 0
+ printf("start load %x end load %x %x\n", addr,
+ len, addr + len);
+ printf("esym %x *esym %x\n", esym, len);
+#endif
+ /* dont load tail of already loaded */
+ len -= (u_int) addr - (u_int) esym;
+
+ if (len > 0) {
+ printf(" + %x", *esym);
+ esym = (void *) (addr + len);
+ cnt = ((len + (512 - 1)) / 512) * 512;
+ flags = IGNORE_FILENUM;
+ ret = read_tape_block(pbugargs->ctrl_lun,
+ pbugargs->dev_lun, &status, addr,
+ &cnt, blk_num, &flags, verbose);
+ if (ret != 0 || cnt != ((len + (512-1)) / 512)*512) {
+ printf("unable to load kernel 4\n");
+ return (1);
+ }
+ addr += len;
+ printf(" ]");
+ } else {
+ printf("+ %x ]", *esym);
+ }
+ esym = (int *) (((int) esym) + *esym);
+
+ kernel.symtab = symtab;
+ kernel.esym = esym;
+ } else {
+ kernel.symtab = 0;
+ kernel.esym = 0;
+ }
+ kernel.end_loaded = (int) addr;
+ flags = IGNORE_FILENUM | END_OF_FILE;
+ cnt = 8192;
+ printf("removing pad [");
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun,
+ &status, addr, &cnt, blk_num, &flags, verbose);
+ if (ret != 0) {
+ printf("unable to load kernel 5\n");
+ return (1);
+ }
+ printf(" %d ]", cnt);
+
+ printf("]\n");
+ }
+ kernel.entry = (void *) pexec->a_entry;
+ return (0);
+}
+
+int
+loadmini(addr, pbugargs)
+ u_int addr;
+ struct mvmeprom_args *pbugargs;
+{
+ int cnt, ret, blk_num = 3;
+ short status = 0;
+ u_char flags;
+
+ /* align addr to some boundary */
+#define ALIGN_F 0x4
+ addr = (u_int) ((((int) addr + ALIGN_F - 1) / ALIGN_F) * ALIGN_F);
+#undef ALIGN_F
+ flags = END_OF_FILE;
+ cnt = 6144 * 512; /* some abserdly large value. (3meg) */
+ printf("loading miniroot[ ");
+ ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun,
+ &status, (void *) addr, &cnt, blk_num, &flags, verbose);
+ if (ret != 0) {
+ printf("unable to load miniroot\n");
+ return (1);
+ }
+ kernel.smini = (void *)addr;
+ printf("%d ]\n", cnt);
+ kernel.emini = (void *) ((u_int) addr + cnt);
+ kernel.end_loaded = (u_int) kernel.emini;
+ return (0);
+}
+
+void
+parse_args(pargs)
+ struct mvmeprom_args *pargs;
+{
+ char *ptr = pargs->arg_start;
+ char c, *name = NULL;
+ int howto = 0;
+
+ if (pargs->arg_start != pargs->arg_end) {
+ while (c = *ptr) {
+ while (c == ' ')
+ c = *++ptr;
+ if (!c)
+ return;
+ if (c != '-') {
+ name = ptr;
+ while ((c = *++ptr) && c != ' ');
+ if (c)
+ *ptr++ = 0;
+ continue;
+ }
+ while ((c = *++ptr) && c != ' ') {
+ if (c == 'a')
+ howto |= RB_ASKNAME;
+ else if (c == 'b')
+ howto |= RB_HALT;
+ else if (c == 'y')
+ howto |= RB_NOSYM;
+ else if (c == 'd')
+ howto |= RB_KDB;
+ else if (c == 'm')
+ howto |= RB_MINIROOT;
+ else if (c == 'r')
+ howto |= RB_DFLTROOT;
+ else if (c == 's')
+ howto |= RB_SINGLE;
+ }
+ }
+ }
+ kernel.bflags = howto;
+ kernel.kname = name;
+}
--- /dev/null
+# $Id: Makefile,v 1.1.1.1 1997/03/03 19:31:03 rahnds Exp $
+
+CFLAGS+=-I${.CURDIR}/../../include -O2
+
+.include "${MACHINE_ARCH}/Makefile.inc"
+
+.PATH: ${.CURDIR}/${MACHINE_ARCH}
+
+OBJS=bugcrt.o
+
+CLEANFILES+=a.out
+
+all: ${OBJS}
+
+bugcrt.o: bugcrt.c
+ ${CC} ${CFLAGS} -c ${.ALLSRC}
+ ${LD} -x -r ${.TARGET}
+ mv a.out ${.TARGET}
+
+install:
+
+lint tags:
+
+.include <bsd.prog.mk>
--- /dev/null
+BUG_CRT_DIR=${S}/arch/${MACHINE}/stand/bugcrt
+
+BUGCRT_DIR!= cd ${BUG_CRT_DIR}; \
+ printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx
+
+BUGCRT=${BUGCRT_DIR}/bugcrt.o
+
+$(BUGCRT): .NOTMAIN __always_make_bugcrt
+ @echo making sure the bugcrt is up to date...
+ @(cd ${BUG_CRT_DIR}; ${MAKE})
+
+__always_make_bugcrt: .NOTMAIN
--- /dev/null
+#include <sys/types.h>
+#include <machine/prom.h>
+
+struct mvmeprom_args bugargs = { 1 }; /* not BSS */
+
+ asm (".text");
+ asm (".long 0x003ffff8");
+ asm (".long _start");
+start()
+{
+ register int dev_lun asm ("r2");
+ register int ctrl_lun asm ("r3");
+ register int flags asm ("r4");
+ register int ctrl_addr asm ("r5");
+ register int entry asm ("r6");
+ register int conf_blk asm ("r7");
+ register char *arg_start asm ("r8");
+ register char *arg_end asm ("r9");
+ extern int edata, end;
+
+ bugargs.dev_lun = dev_lun;
+ bugargs.ctrl_lun = ctrl_lun;
+ bugargs.flags = flags;
+ bugargs.ctrl_addr = ctrl_addr;
+ bugargs.entry = entry;
+ bugargs.conf_blk = conf_blk;
+ bugargs.arg_start = arg_start;
+ bugargs.arg_end = arg_end;
+ *arg_end = 0;
+
+ bzero(&edata, (int)&edata - (int)&end);
+ main();
+ mvmeprom_return();
+ /* NOTREACHED */
+}
+
+__main()
+{
+}
--- /dev/null
+LIB=bug
+
+NOPIC=
+NOPROFILE=
+
+CFLAGS+=-I${.CURDIR}/../../include
+
+SRCS=delay.c diskrd.c diskwr.c getbrdid.c instat.c outln.c outstr.c \
+ return.c rtc_rd.c
+.PATH: ${.CURDIR}/../../../../lib/libc_sa ${.CURDIR}/${MACHINE_ARCH}
+
+install:
+
+.include <bsd.lib.mk>
--- /dev/null
+LIB_BUG_DIR=${S}/arch/${MACHINE}/stand/libbug
+
+LIBBUG_DIR!= cd ${LIB_BUG_DIR}; \
+ printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx
+
+LIBBUG=${LIBBUG_DIR}/libbug.a
+
+$(LIBBUG): .NOTMAIN __always_make_libbug
+ @echo making sure the libbug is up to date...
+ @(cd ${LIB_BUG_DIR}; ${MAKE})
+
+__always_make_libbug: .NOTMAIN
--- /dev/null
+delay.o delay.o
+diskrd.o diskrd.o
+diskwr.o diskwr.o
+getbrdid.o getbrdid.o
+instat.o instat.o
+outln.o outln.o
+outstr.o outstr.o
+return.o return.o
+rtc_rd.o rtc_rd.o
--- /dev/null
+rtc_rd.o
+return.o
+outstr.o
+outln.o
+instat.o
+getbrdid.o
+diskwr.o
+diskrd.o
+delay.o
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* BUG - timing routine */
+void
+mvmeprom_delay(msec)
+ int msec;
+{
+ asm volatile ("or r2,r0,%0": : "r" (msec));
+ MVMEPROM_CALL(MVMEPROM_DELAY);
+}
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_diskrd(arg)
+ struct mvmeprom_dskio *arg;
+{
+ int ret;
+
+ asm volatile ("or r2,r0,%0": : "r" (arg));
+ MVMEPROM_CALL(MVMEPROM_DSKRD);
+ asm volatile ("or %0,r0,r2" : "=r" (ret));
+ return (!(ret & 0x4));
+}
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_diskwr(arg)
+ struct mvmeprom_dskio *arg;
+{
+ int ret;
+
+ asm volatile ("or r2,r0,%0": : "r" (arg) );
+ MVMEPROM_CALL(MVMEPROM_DSKWR);
+ asm volatile ("or %0,r0,r2" : "=r" (ret));
+ return (!(ret & 0x4));
+}
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* BUG - query board routines */
+struct mvmeprom_brdid *
+mvmeprom_brdid()
+{
+ struct mvmeprom_brdid *id;
+
+ MVMEPROM_CALL(MVMEPROM_GETBRDID);
+ asm volatile ("or %0,r0,r2": "=r" (id):);
+ return (id);
+}
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* returns 0 if no characters ready to read */
+int
+mvmeprom_instat()
+{
+ short ret;
+
+ MVMEPROM_CALL(MVMEPROM_INSTAT);
+ asm volatile ("or %0,r0,r2" : "=r" (ret));
+ return (!(ret & 0x4));
+}
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+void
+mvmeprom_outchr(a)
+ char a;
+{
+ asm volatile ("or r2, r0, %0" : :"r" (a));
+ BUG_CALL(_OUTCHR);
+}
+
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+void
+mvmeprom_outln(start, end)
+ char *start, *end;
+{
+ asm volatile ("or r2,r0,%0": : "r" (start));
+ asm volatile ("or r3,r0,%0": : "r" (end));
+ MVMEPROM_CALL(MVMEPROM_OUTSTRCRLF);
+}
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+void
+mvmeprom_outstr(start, end)
+ char *start, *end;
+{
+ asm volatile ("or r2,r0,%0": : "r" (start));
+ asm volatile ("or r3,r0,%0": : "r" (end));
+ MVMEPROM_CALL(MVMEPROM_OUTSTR);
+}
--- /dev/null
+#define MVMEPROM_CALL(x) \
+ asm volatile ( __CONCAT("or r9,r0," __STRING(x)) ); \
+ asm volatile ("tb0 0,r0,496");
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* BUG - return to bug routine */
+void
+mvmeprom_return()
+{
+ MVMEPROM_CALL(MVMEPROM_EXIT);
+ /*NOTREACHED*/
+}
--- /dev/null
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+void
+mvmeprom_rtc_rd(ptime)
+ struct mvmeprom_time *ptime)
+{
+ asm volatile ("or r2,r0,%0": : "r" (ptime));
+ MVMEPROM_CALL(MVMEPROM_RTC_RD);
+}
--- /dev/null
+# $Id: Makefile,v 1.1.1.1 1997/03/03 19:31:06 rahnds Exp $
+
+LIB=sa
+
+CLEANFILES+=SRT0.o SRT1.o
+
+NOPIC=nopic
+NOPROFILE=noprofile
+
+# Logically src/sys
+S=${.CURDIR}/../../../..
+DIR_SA=$S/lib/libsa
+DIR_KERN=$S/lib/libkern
+
+SRC_net= nfs.c rpc.c net.c ether.c arp.c in_cksum.c netif.c \
+ bootparam.c rarp.c
+
+
+SRC_sa = alloc.c bcopy.c memcpy.c close.c getfile.c open.c \
+ printf.c read.c strerror.c ufs.c globals.c lseek.c \
+ closeall.c dev.c dkcksum.c nullfs.c fstat.c
+
+SRC_kern= ashrdi3.c bcmp.c bzero.c strcmp.c strlen.c
+
+SRC_sun3= exec_sun.c
+
+SRC_here= clock.c devopen.c dvma.c \
+ gets.c panic.c \
+ promboot.c promcons.c
+
+SRCS= ${SRC_net} ${SRC_sa} ${SRC_kern} ${SRC_sun3} ${SRC_here}
+
+# DBG= -DDEBUG -DNETIF_DEBUG -DNFS_DEBUG -DRPC_DEBUG \
+# -DNET_DEBUG -DRARP_DEBUG -DETHER_DEBUG
+
+#DEFS= -DCOMPAT_UFS
+INCL= -I. -I${S}/lib/libsa -I${S}
+COPTS= #-fno-defer-pop
+CFLAGS= -O2 ${COPTS} ${DEFS} ${DBG} ${INCL}
+
+.PATH: ${DIR_SA} ${DIR_KERN} ../../sun3
+
+all: libsa.a SRT0.o SRT1.o
+
+install:
+
+.include <bsd.lib.mk>
--- /dev/null
+LIB_SA_DIR=${S}/arch/${MACHINE}/stand/libsa
+
+LIBSA_DIR!= cd ${LIB_SA_DIR}; \
+ printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx
+
+LIBSA=${LIBSA_DIR}/libsa.a
+
+$(LIBSA): .NOTMAIN __always_make_libsa
+ @echo making sure the libsa is up to date...
+ @(cd ${LIB_SA_DIR}; ${MAKE})
+
+__always_make_libsa: .NOTMAIN
--- /dev/null
+| $Id: SRT0.S,v 1.1.1.1 1997/03/03 19:31:06 rahnds Exp $
+
+| Copyright (c) 1995 Theo de Raadt
+|
+| 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 under OpenBSD by
+| Theo de Raadt for Willowglen Singapore.
+| 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.
+|
+| Copyright (c) 1995 Gordon W. Ross
+| 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. The name of the author may not be used to endorse or promote products
+| derived from this software without specific prior written permission.
+| 4. All advertising materials mentioning features or use of this software
+| must display the following acknowledgement:
+| This product includes software developed by Gordon Ross
+|
+| 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.
+
+| SRT0.S - Stand-alone Run-Time startup code, part 0
+ .file "SRT0.S"
+ .text
+ .globl __estack
+__estack:
+ .globl start
+start:
+| Check to see if the code is located correctly.
+| This SHOULD do a PC-relative load into a0, but...
+| lea start, a0 | current location (0x4000)
+| XXX - GAS version 1.93 gets the above lea wrong!
+ .word 0x41fa
+ .word 0xfffe
+| Now force a long (not PC-relative) load to a1 and compare.
+ lea start:l, a1 | desired location (LINKADDR)
+ cmpl a0, a1
+ beqs restart
+
+| Relocate the code and data to where they belong.
+ movl #_edata,d2 | Desired end of program
+ subl a1,d2 | Calculate length, round up.
+ lsrl #2,d2
+Lcp: movl a0@+, a1@+
+ dbra d2, Lcp
+
+| Force a long jump to the relocated code (not pc-relative)
+ lea restart:l, a0
+ jmp a0@
+
+restart:
+| now in the relocated code
+
+| Set up stack (just before relocated text)
+ lea __estack:l, a0
+ movl a0, sp
+ subl a6, a6
+
+ movl d0, _devlun
+ movl d1, _ctrlun
+ movl a3, _oparg
+ movl a4, _opargend
+
+| Call the run-time startup C code, which will:
+| initialize, call main, call exit
+ jsr __start:l
+
+| If _start returns, fall into abort.
+ .globl _abort
+_abort:
+ trap #0
+
+| If abort returns, fall into reset.
+ .globl _reset
+_reset:
+ reset
+ jmp _reset
+
+| function to get the vector base register
+ .globl _getvbr
+_getvbr:
+ movc vbr, d0
+ rts
+
+| The end.
+
+ .data
+ .globl _devlun, _ctrlun, _oparg, _opargend
+_devlun: .long 0
+_ctrlun: .long 0
+_oparg: .long 0
+_opargend: .long 0
--- /dev/null
+/* $Id: SRT1.c,v 1.1.1.1 1997/03/03 19:31:06 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ *
+ * Copyright (c) 1995 Gordon W. Ross
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * 4. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Gordon Ross
+ *
+ * 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.
+ */
+
+/* SRT1.c - Stand-alone Run-time startup code, part 1 */
+
+#include <stdarg.h>
+#include <sys/types.h>
+
+#include "config.h"
+
+extern int edata[], end[];
+extern int * getvbr();
+extern volatile void abort();
+
+volatile void
+exit()
+{
+#if 0
+ mon_exit_to_mon();
+#endif
+ abort();
+}
+
+struct brdid brdid;
+int cputyp;
+
+/*
+ * This is called by SRT0.S
+ * to do final prep for main
+ */
+_start()
+{
+ register int *p;
+
+ /* Clear BSS */
+ p = edata;
+ do *p++ = 0;
+ while (p < end);
+
+#if 0
+ /* Set the vector for trap 0 used by abort. */
+ p = getvbr();
+ p[32] = (int)romp->abortEntry;
+#endif
+
+ asm("clrl sp@-; trap #15; .short 0x70; movl sp@+, %0" : "&=d" (p));
+ bcopy(p, &brdid, sizeof brdid);
+ cputyp = brdid.model;
+
+ main(0);
+ exit();
+}
+
+/*
+ * Boot programs in C++ ? Not likely!
+ */
+__main() {}
--- /dev/null
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 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.
+ *
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+#define MVMEPROM_CALL(x) \
+ asm volatile (__CONCAT("trap #15; .short ", __STRING(x)) )
+
+/* returns 0 if no characters ready to read */
+int
+mvmeprom_instat()
+{
+ u_short ret;
+
+ MVMEPROM_CALL(MVMEPROM_INSTAT);
+ asm volatile ("movew ccr,%0": "=d" (ret));
+ return (!(ret & 0x4));
+}
+
+void
+mvmeprom_outstr(start, end)
+ char *start, *end;
+{
+ asm volatile ("movl %0, sp@-" : "=a" (start));
+ asm volatile ("movl %0, sp@-" : "=a" (end));
+ MVMEPROM_CALL(MVMEPROM_OUTSTR);
+}
+
+void
+mvmeprom_outln(start, end)
+ char *start, *end;
+{
+ asm volatile ("movl %0, sp@-" : "=a" (start));
+ asm volatile ("movl %0, sp@-" : "=a" (end));
+ MVMEPROM_CALL(MVMEPROM_OUTSTRCRLF);
+}
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_diskrd(arg)
+ struct mvmeprom_dskio *arg;
+{
+ int ret;
+
+ asm volatile ("movel %0, sp@-"::"d" (arg));
+ MVMEPROM_CALL(MVMEPROM_DSKRD);
+ asm volatile ("movew ccr,%0": "=d" (ret));
+ return (!(ret & 0x4));
+}
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_diskwr(arg)
+ struct mvmeprom_dskio *arg;
+{
+ int ret;
+
+ asm volatile ("movel %0, sp@-"::"d" (arg));
+ MVMEPROM_CALL(MVMEPROM_DSKWR);
+ asm volatile ("movew ccr,%0": "=d" (ret));
+ return (!(ret & 0x4));
+}
+
+#ifdef NOTYET
+mvmeprom_diskcfig() {}
+mvmeprom_diskfmt(){}
+mvmeprom_diskctrl(){}
+#endif
+
+/* BUG - timing routine */
+void
+mvmeprom_delay(msec)
+ int msec;
+{
+ asm volatile ("movel %0,sp@-" : :"d" (msec));
+ MVMEPROM_CALL(MVMEPROM_DELAY);
+}
+
+/* BUG - return to bug routine */
+void
+mvmeprom_return()
+{
+ MVMEPROM_CALL(MVMEPROM_EXIT);
+ /*NOTREACHED*/
+}
+
+/* BUG - query board routines */
+struct mvmeprom_brdid *
+mvmeprom_getbrdid()
+{
+ struct mvmeprom_brdid *id;
+
+ asm volatile ("clrl sp@-");
+ MVMEPROM_CALL(MVMEPROM_GETBRDID);
+ asm volatile ("movel sp@+,%0": "=d" (id):);
+ return (id);
+}
+
+void
+mvmeprom_rtc_rd(ptime)
+ struct mvmeprom_time *ptime;
+{
+ asm volatile ("movel %0,sp@-" : :"a" (ptime));
+ MVMEPROM_CALL(MVMEPROM_RTC_RD);
+}
--- /dev/null
+#include <sys/types.h>
+
+#include "clockreg.h"
+#include "config.h"
+#include "clock.h"
+
+/*
+ * 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);
+}
+
+time_t
+getsecs()
+{
+ extern int cputyp;
+ register struct clockreg *cl;
+ int sec, min, hour, day, mon, year;
+
+ if (cputyp == CPU_147)
+ cl = (struct clockreg *) CLOCK_ADDR_147;
+ else
+ cl = (struct clockreg *) CLOCK_ADDR_16x;
+
+ 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));
+}
+
+int
+getticks()
+{
+ return getsecs() * 100;
+}
--- /dev/null
+
+extern int hz;
+
+time_t getsecs();
+int getticks();
+
--- /dev/null
+/* $Id: clockreg.h,v 1.1.1.1 1997/03/03 19:31:06 rahnds 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
+
+#define CLOCK_ADDR_147 (0xfffe07f8) /* PA of clock */
+#define CLOCK_ADDR_16x (0xfffc1ff8) /* PA of clock */
--- /dev/null
+/* $Id: config.h,v 1.1.1.1 1997/03/03 19:31:06 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 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.
+ */
+
+/* configuration information for base-line code */
+
+#define ETHER_ADDR_147 (0xfffe0778)
+#define ETHER_ADDR_16X (0xfffc0000+7980)
+#define ERAM_ADDR (0xfffe0774)
+#define LANCE_REG_ADDR (0xfffe1800)
+#define INTEL_REG_ADDR (0xfff46000)
+
+#define CPU_147 0x147
+#define CPU_162 0x162
+#define CPU_167 0x167
+#define CPU_172 0x172
+#define CPU_177 0x177
+
+struct brdid {
+ u_long eye_catcher;
+ u_char rev;
+ u_char month;
+ u_char day;
+ u_char year;
+ u_short size;
+ u_short rsv1;
+ u_short model;
+ u_short suffix;
+ u_short options;
+ u_char family;
+ u_char cpu;
+ u_short ctrlun;
+ u_short devlun;
+ u_short devtype;
+ u_short devnum;
+ u_long bug;
+};
--- /dev/null
+/* $Id: dev_disk.c,v 1.1.1.1 1997/03/03 19:31:06 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1993 Paul Kranenburg
+ * 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 Paul Kranenburg.
+ * 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.
+ */
+
+/*
+ * This module implements a "raw device" interface suitable for
+ * use by the stand-alone I/O library UFS file-system code, and
+ * possibly for direct access (i.e. boot from tape).
+ *
+ * The implementation is deceptively simple because it uses the
+ * drivers provided by the Sun PROM monitor. Note that only the
+ * PROM driver used to load the boot program is available here.
+ */
+
+#include <sys/types.h>
+#include <machine/mon.h>
+#include <machine/saio.h>
+
+#include "stand.h"
+
+#include "dvma.h"
+#include "promdev.h"
+
+int
+disk_open(f, devname)
+ struct open_file *f;
+ char *devname; /* Device part of file name (or NULL). */
+{
+ struct saioreq *sip;
+ int error;
+
+#ifdef DEBUG_PROM
+ printf("disk_open: %s\n", devname);
+#endif
+
+ if ((error = prom_iopen(&sip)) != 0)
+ return (error);
+
+ f->f_devdata = sip;
+ return 0;
+}
+
+int
+disk_close(f)
+ struct open_file *f;
+{
+ struct saioreq *sip;
+
+ sip = f->f_devdata;
+ prom_iclose(sip);
+ f->f_devdata = NULL;
+ return 0;
+}
+
+int
+disk_strategy(devdata, flag, dblk, size, buf, rsize)
+ void *devdata;
+ int flag;
+ daddr_t dblk;
+ u_int size;
+ char *buf;
+ u_int *rsize;
+{
+ struct saioreq *si;
+ struct boottab *ops;
+ char *dmabuf;
+ int si_flag, xcnt;
+
+ si = devdata;
+ ops = si->si_boottab;
+
+#ifdef DEBUG_PROM
+ printf("disk_strategy: size=%d dblk=%d\n", size, dblk);
+#else
+ twiddle();
+#endif
+
+ dmabuf = dvma_mapin(buf, size);
+
+ si->si_bn = dblk;
+ si->si_ma = dmabuf;
+ si->si_cc = size;
+
+ si_flag = (flag == F_READ) ? SAIO_F_READ : SAIO_F_WRITE;
+ xcnt = (*ops->b_strategy)(si, si_flag);
+ dvma_mapout(dmabuf, size);
+
+#ifdef DEBUG_PROM
+ printf("disk_strategy: xcnt = %x\n", xcnt);
+#endif
+
+ if (xcnt <= 0)
+ return (EIO);
+
+ *rsize = xcnt;
+ return (0);
+}
+
+int
+disk_ioctl()
+{
+ return EIO;
+}
+
--- /dev/null
+
+int disk_open __P((struct open_file *, ...));
+int disk_close __P((struct open_file *));
+int disk_strategy __P((void *, int, daddr_t, u_int, char *, u_int *));
+int disk_ioctl();
+
--- /dev/null
+
+#include <sys/param.h>
+#include <stand.h>
+#include "promboot.h"
+
+/*
+ * Open the device named by the combined device/file name
+ * given as the "fname" arg, something like: "sd()bsd"
+ *
+ * However, Sun PROMs don't really let you choose which
+ * device you will talk to. You can only open the device
+ * that was used to load the boot program. Therefore, we
+ * do not accept a "device" part in the "fname" string.
+ * Pass the PROM device name to open in case it needs it.
+ */
+int
+devopen(f, fname, file)
+ struct open_file *f;
+ const char *fname;
+ char **file;
+{
+ struct devsw *dp;
+ char *cp, *path, *devname;
+ int error;
+
+ *file = (char*)fname;
+ dp = &devsw[0];
+ f->f_dev = dp;
+ error = (*dp->dv_open)(f, prom_bootdev);
+
+ return (error);
+}
--- /dev/null
+
+/*
+ * The easiest way to deal with the need for DVMA mappings is
+ * to just map the first four megabytes of RAM into DVMA space.
+ * That way, dvma_mapin can just compute the DVMA alias address,
+ * and dvma_mapout does nothing.
+ */
+
+#include <sys/param.h>
+
+#define DVMA_BASE 0x00000000
+#define DVMA_MASK 0x00ffFFff
+#define DVMA_MAPLEN 0x400000 /* 4 MB */
+
+void
+dvma_init()
+{
+#if 0
+ int segva, sme;
+
+ for (segva = 0; segva < DVMA_MAPLEN; segva += NBSG) {
+ sme = get_segmap(segva);
+ set_segmap((DVMA_BASE | segva), sme);
+ }
+#endif
+}
+
+/* Convert a local address to a DVMA address. */
+char *
+dvma_mapin(char *addr, int len)
+{
+ int va = (int)addr;
+
+ va |= DVMA_BASE;
+ return ((char *) va);
+}
+
+/* Convert a DVMA address to a local address. */
+char *
+dvma_mapout(char *dmabuf, int len)
+{
+ if (dmabuf < (char*)DVMA_BASE)
+ panic("dvma_mapout");
+ return (dmabuf - DVMA_BASE);
+}
+
+extern char *alloc(int len);
+char *
+dvma_alloc(int len)
+{
+ char *mem;
+
+ mem = alloc(len);
+ if (!mem)
+ return(mem);
+ return(dvma_mapin(mem, len));
+}
+
+extern void free(void *ptr, int len);
+void
+dvma_free(char *dvma, int len)
+{
+ char *mem;
+
+ mem = dvma_mapout(dvma, len);
+ if (mem)
+ free(mem, len);
+}
--- /dev/null
+
+char * dvma_mapin(char *pkt, int len);
+void dvma_mapout(char *dmabuf, int len);
+
+char * dvma_alloc(int len);
+
--- /dev/null
+/* $Id: exec_sun.c,v 1.1.1.1 1997/03/03 19:31:07 rahnds Exp $ */
+
+/*-
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 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.
+ *
+ * Copyright (c) 1982, 1986, 1990, 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.
+ *
+ * @(#)boot.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <a.out.h>
+
+#include "stand.h"
+
+extern int debug;
+
+extern u_int bootdev;
+
+/*ARGSUSED*/
+exec_sun(file, loadaddr, howto)
+ char *file;
+ char *loadaddr;
+ int howto;
+{
+ register int io;
+ struct exec x;
+ int cc, magic;
+ void (*entry)();
+ register char *cp;
+ register int *ip;
+ int textlen;
+
+#ifdef DEBUG
+ printf("exec_sun: file=%s loadaddr=0x%x\n", file, loadaddr);
+#endif
+
+ io = open(file, 0);
+ if (io < 0)
+ return(-1);
+
+ /*
+ * Read in the exec header, and validate it.
+ */
+ if (read(io, (char *)&x, sizeof(x)) != sizeof(x))
+ goto shread;
+ if (N_BADMAG(x)) {
+ errno = EFTYPE;
+ goto closeout;
+ }
+
+ cp = loadaddr;
+ textlen = x.a_text;
+ magic = N_GETMAGIC(x);
+ if (magic == ZMAGIC) {
+ cp += sizeof(x);
+ textlen -= sizeof(x);
+ }
+ entry = (void (*)())cp;
+
+ /*
+ * Leave a copy of the exec header before the text.
+ * The sun3 kernel uses this to verify that the
+ * symbols were loaded by this boot program.
+ */
+ bcopy(&x, cp - sizeof(x), sizeof(x));
+
+ /*
+ * Read in the text segment.
+ */
+ printf("%x", x.a_text);
+ if (read(io, cp, textlen) != textlen)
+ goto shread;
+ cp += textlen;
+
+ /*
+ * NMAGIC may have a gap between text and data.
+ */
+ if (magic == NMAGIC) {
+ register int mask = N_PAGSIZ(x) - 1;
+ while ((int)cp & mask)
+ *cp++ = 0;
+ }
+
+ /*
+ * Read in the data segment.
+ */
+ printf("+%x", x.a_data);
+ if (read(io, cp, x.a_data) != x.a_data)
+ goto shread;
+ cp += x.a_data;
+
+ /*
+ * Zero out the BSS section.
+ * (Kernel does not do it itself)
+ */
+ printf("+%x", x.a_bss);
+ cc = x.a_bss;
+ while ((int)cp & 3) {
+ *cp++ = 0;
+ --cc;
+ }
+ ip = (int *)cp;
+ cp += cc;
+ while ((char *)ip < cp)
+ *ip++ = 0;
+
+ /*
+ * Read in the symbol table and strings.
+ * (Always set the symtab size word.)
+ */
+ *ip++ = x.a_syms;
+ cp = (char *)ip;
+
+ if (x.a_syms > 0) {
+
+ /* Symbol table and string table length word. */
+ cc = x.a_syms;
+ printf("+[%x", cc);
+ cc += sizeof(int); /* strtab length too */
+ if (read(io, cp, cc) != cc)
+ goto shread;
+ cp += x.a_syms;
+ ip = (int *)cp; /* points to strtab length */
+ cp += sizeof(int);
+
+ /* String table. Length word includes itself. */
+ cc = *ip;
+ printf("+%x]", cc);
+ cc -= sizeof(int);
+ if (cc <= 0)
+ goto shread;
+ if (read(io, cp, cc) != cc)
+ goto shread;
+ cp += cc;
+ }
+ printf("=%x\n", cp - loadaddr);
+ close(io);
+
+ if (debug) {
+ printf("Debug mode - enter c to continue\n");
+ asm(" trap #0");
+ }
+
+ printf("Starting program at 0x%x\n", (int)entry);
+ (*entry)(howto, bootdev, cp, 0, 0);
+ panic("exec returned");
+
+shread:
+ printf("exec: short read\n");
+ errno = EIO;
+closeout:
+ close(io);
+ return(-1);
+}
--- /dev/null
+/* $Id: gets.c,v 1.1.1.1 1997/03/03 19:31:07 rahnds Exp $ */
+
+/*-
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 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.
+ *
+ * Copyright (c) 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.
+ *
+ * @(#)gets.c 8.1 (Berkeley) 6/11/93
+ */
+
+#include "stand.h"
+
+/*
+ * This implementation assumes that getchar() does echo, because
+ * on some machines, it is hard to keep echo from being done.
+ * Those that need it can do echo in their getchar() function.
+ *
+ * Yes, the code below will echo CR, DEL, and other control chars,
+ * but sending CR or DEL here is harmless. All the other editing
+ * characters will be followed by a newline, so it doesn't matter.
+ * (Most terminals will not show them anyway.)
+ */
+
+void
+gets(buf)
+ char *buf;
+{
+ register int c;
+ register char *lp;
+
+top:
+ lp = buf;
+
+ for (;;) {
+ c = getchar() & 0177;
+
+ putchar(c);
+
+ switch (c) {
+
+ default:
+ *lp++ = c;
+ continue;
+
+ case '\177':
+ putchar('\b');
+ /* fall through */
+ case '\b':
+ putchar(' ');
+ putchar('\b');
+ /* fall through */
+ case '#':
+ if (lp > buf)
+ lp--;
+ continue;
+
+ /*
+ * This is not very useful in a boot program.
+ * (It costs you 52 bytes on m68k, gcc -O3).
+ */
+ case 'r'&037: {
+ register char *p;
+ putchar('\n');
+ for (p = buf; p < lp; ++p)
+ putchar(*p);
+ continue;
+ }
+
+ case '@':
+ case 'u'&037:
+ case 'w'&037:
+ putchar('\n');
+ goto top;
+
+ case '\r':
+ putchar('\n');
+ /* fall through */
+ case '\n':
+ *lp = '\0';
+ return;
+
+ } /* switch */
+ }
+ /*NOTREACHED*/
+}
--- /dev/null
+nfs.o nfs.o
+rpc.o rpc.o
+net.o net.o
+ether.o ether.o
+arp.o arp.o
+in_cksum.o in_cksum.o
+netif.o netif.o
+bootparam.o bootparam.o
+rarp.o rarp.o
+alloc.o alloc.o
+bcopy.o bcopy.o
+memcpy.o memcpy.o
+close.o close.o
+getfile.o getfile.o
+open.o open.o
+printf.o printf.o
+read.o read.o
+strerror.o strerror.o
+ufs.o ufs.o
+globals.o globals.o
+lseek.o lseek.o
+closeall.o closeall.o
+dev.o dev.o
+dkcksum.o dkcksum.o
+nullfs.o nullfs.o
+fstat.o fstat.o
+ashrdi3.o ashrdi3.o
+bcmp.o bcmp.o
+bzero.o bzero.o
+strcmp.o strcmp.o
+strlen.o strlen.o
+exec_sun.o exec_sun.o
+clock.o clock.o
+devopen.o devopen.o
+dvma.o dvma.o
+gets.o gets.o
+panic.o panic.o
+promboot.o promboot.o
+promcons.o promcons.o
+ufs.o ashrdi3.o
+dvma.o alloc.o
+nfs.o alloc.o
+ufs.o alloc.o
+net.o arp.o
+net.o arp.o
+arp.o globals.o
+ether.o globals.o
+rarp.o globals.o
+arp.o bcmp.o
+ether.o bcmp.o
+rarp.o bcmp.o
+arp.o bcopy.o
+bootparam.o bcopy.o
+ether.o bcopy.o
+exec_sun.o bcopy.o
+memcpy.o bcopy.o
+net.o bcopy.o
+nfs.o bcopy.o
+rarp.o bcopy.o
+ufs.o bcopy.o
+arp.o bzero.o
+net.o bzero.o
+netif.o bzero.o
+nfs.o bzero.o
+rarp.o bzero.o
+rpc.o bzero.o
+ufs.o bzero.o
+closeall.o close.o
+exec_sun.o close.o
+open.o devopen.o
+dvma.o alloc.o
+nfs.o alloc.o
+ufs.o alloc.o
+gets.o promcons.o
+getfile.o gets.o
+net.o clock.o
+net.o in_cksum.o
+arp.o net.o
+ether.o netif.o
+ether.o netif.o
+net.o globals.o
+rarp.o globals.o
+exec_sun.o open.o
+getfile.o open.o
+arp.o panic.o
+exec_sun.o panic.o
+net.o panic.o
+netif.o panic.o
+arp.o printf.o
+bootparam.o printf.o
+exec_sun.o printf.o
+getfile.o printf.o
+net.o printf.o
+netif.o printf.o
+nfs.o printf.o
+panic.o printf.o
+rarp.o printf.o
+rpc.o printf.o
+gets.o promcons.o
+printf.o promcons.o
+exec_sun.o read.o
+arp.o ether.o
+net.o ether.o
+rarp.o ether.o
+rpc.o net.o
+bootparam.o rpc.o
+nfs.o rpc.o
+bootparam.o rpc.o
+bootparam.o rpc.o
+bootparam.o rpc.o
+nfs.o rpc.o
+arp.o ether.o
+net.o ether.o
+rarp.o ether.o
+arp.o net.o
+rarp.o net.o
+rpc.o net.o
+rpc.o net.o
+bootparam.o netif.o
+nfs.o netif.o
+rarp.o netif.o
+strerror.o printf.o
+ufs.o strcmp.o
+rpc.o strerror.o
+bootparam.o strlen.o
+nfs.o strlen.o
+ufs.o strlen.o
+nfs.o printf.o
+read.o printf.o
+ufs.o printf.o
--- /dev/null
+promboot.o
+dvma.o
+exec_sun.o
+fstat.o
+nullfs.o
+dkcksum.o
+dev.o
+closeall.o
+lseek.o
+ufs.o
+read.o
+getfile.o
+close.o
+memcpy.o
+rarp.o
+bootparam.o
+nfs.o
+gets.o
+strlen.o
+strcmp.o
+ashrdi3.o
+open.o
+alloc.o
+rpc.o
+devopen.o
+strerror.o
+arp.o
+net.o
+clock.o
+in_cksum.o
+ether.o
+bcmp.o
+globals.o
+bcopy.o
+netif.o
+panic.o
+bzero.o
+printf.o
+promcons.o
--- /dev/null
+/* $Id: netif_sun.c,v 1.1.1.1 1997/03/03 19:31:07 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Gordon W. Ross
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * 4. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Gordon W. Ross
+ *
+ * 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.
+ */
+
+/*
+ * The Sun PROM has a fairly general set of network drivers,
+ * so it is easiest to just replace the netif module with
+ * this adaptation to the PROM network interface.
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <time.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+
+#include <machine/control.h>
+#include <machine/idprom.h>
+#include <machine/mon.h>
+#include <machine/saio.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+
+#include "clock.h"
+#include "dvma.h"
+#include "promdev.h"
+
+static struct netif netif_prom;
+
+#ifdef NETIF_DEBUG
+int netif_debug;
+#endif
+
+struct iodesc sockets[SOPEN_MAX];
+
+struct iodesc *
+socktodesc(sock)
+ int sock;
+{
+ if (sock != 0) {
+ return(NULL);
+ }
+ return (sockets);
+}
+
+int
+netif_open(machdep_hint)
+ void *machdep_hint;
+{
+ struct saioreq *si;
+ struct iodesc *io;
+ int fd, error;
+
+ /* find a free socket */
+ io = sockets;
+ if (io->io_netif) {
+#ifdef DEBUG
+ printf("netif_open: device busy\n");
+#endif
+ return (-1);
+ }
+ bzero(io, sizeof(*io));
+
+ /*
+ * Note: Sun PROMs will do RARP on open, but does not tell
+ * you the IP address it gets, so it is just noise to us...
+ */
+ if ((error = prom_iopen(&si)) != 0) {
+#ifdef DEBUG
+ printf("netif_open: prom_iopen, error=%d\n", error);
+#endif
+ return (-1);
+ }
+ if (si->si_sif == NULL) {
+#ifdef DEBUG
+ printf("netif_open: not a network device\n");
+#endif
+ prom_iclose(si);
+ return (-1);
+ }
+
+ netif_prom.devdata = si;
+ io->io_netif = &netif_prom;
+
+ /* Put our ethernet address in io->myea */
+ sun3_getether(io->myea);
+
+ return(0);
+}
+
+int
+netif_close(fd)
+ int fd;
+{
+ struct iodesc *io;
+ struct netif *ni;
+
+ if (fd != 0) {
+ errno = EBADF;
+ return(-1);
+ }
+
+ io = sockets;
+ ni = io->io_netif;
+ if (ni != NULL) {
+ prom_iclose(ni->devdata);
+ ni->devdata = NULL;
+ io->io_netif = NULL;
+ }
+ return(0);
+}
+
+/*
+ * Send a packet. The ether header is already there.
+ * Return the length sent (or -1 on error).
+ */
+int
+netif_put(desc, pkt, len)
+ struct iodesc *desc;
+ void *pkt;
+ int len;
+{
+ struct saioreq *si;
+ struct saif *sif;
+ char *dmabuf;
+ int rv, sendlen;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug) {
+ struct ether_header *eh;
+
+ printf("netif_put: desc=0x%x pkt=0x%x len=%d\n",
+ desc, pkt, len);
+ eh = pkt;
+ printf("dst: %s ", ether_sprintf(eh->ether_dhost));
+ printf("src: %s ", ether_sprintf(eh->ether_shost));
+ printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
+ }
+#endif
+
+ si = desc->io_netif->devdata;
+ sif = si->si_sif;
+ sendlen = len;
+ if (sendlen < 60) {
+ sendlen = 60;
+#ifdef NETIF_DEBUG
+ printf("netif_put: length padded to %d\n", sendlen);
+#endif
+ }
+
+#ifdef PARANOID
+ if (sif == NULL)
+ panic("netif_put: no saif ptr\n");
+#endif
+
+ dmabuf = dvma_mapin(pkt, sendlen);
+ rv = sif->sif_xmit(si->si_devdata, dmabuf, sendlen);
+ dvma_mapout(dmabuf, sendlen);
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("netif_put: xmit returned %d\n", rv);
+#endif
+ if (rv == 0) rv = len;
+ else rv = -1;
+
+ return rv;
+}
+
+/*
+ * Receive a packet, including the ether header.
+ * Return the total length received (or -1 on error).
+ */
+int
+netif_get(desc, pkt, maxlen, timo)
+ struct iodesc *desc;
+ void *pkt;
+ int maxlen;
+ time_t timo;
+{
+ struct saioreq *si;
+ struct saif *sif;
+ char *dmabuf;
+ int tick0, tmo_ticks;
+ int len;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("netif_get: pkt=0x%x, maxlen=%d, tmo=%d\n",
+ pkt, maxlen, timo);
+#endif
+
+ si = desc->io_netif->devdata;
+ sif = si->si_sif;
+
+#ifdef PARANOID
+ if (sif == NULL)
+ panic("netif_get: no saif ptr\n");
+#endif
+
+ tmo_ticks = timo * hz;
+ tick0 = getticks();
+
+ dmabuf = dvma_mapin(pkt, maxlen);
+ do len = sif->sif_poll(si->si_devdata, dmabuf);
+ while ((len == 0) && ((getticks() - tick0) < tmo_ticks));
+ dvma_mapout(dmabuf, maxlen);
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("netif_get: received len=%d\n", len);
+#endif
+
+ if (len < 12)
+ return -1;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug) {
+ struct ether_header *eh = pkt;
+
+ printf("dst: %s ", ether_sprintf(eh->ether_dhost));
+ printf("src: %s ", ether_sprintf(eh->ether_shost));
+ printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
+ }
+#endif
+
+ return len;
+}
+
+static struct idprom sun3_idprom;
+
+sun3_getether(ea)
+ u_char *ea;
+{
+ u_char *src, *dst;
+ int len, x;
+
+ if (sun3_idprom.idp_format == 0) {
+ dst = (char*)&sun3_idprom;
+ src = (char*)IDPROM_BASE;
+ len = IDPROM_SIZE;
+ do {
+ x = get_control_byte(src++);
+ *dst++ = x;
+ } while (--len > 0);
+ }
+ MACPY(sun3_idprom.idp_etheraddr, ea);
+}
+
--- /dev/null
+
+#include <stdarg.h>
+#include "stand.h"
+
+extern volatile void abort();
+extern int _estack[];
+
+__dead void
+panic(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ printf(fmt, ap);
+ printf("\n");
+ va_end(ap);
+ stackdump(0);
+ abort();
+}
+
+stackdump(dummy)
+ int dummy;
+{
+ int *ip;
+
+ printf("stackdump:\n");
+ for (ip = &dummy; ip < _estack; ip += 4) {
+ printf("%x: %x %x %x %x\n",
+ (int)ip, ip[0], ip[1], ip[2], ip[3]);
+ }
+}
--- /dev/null
+/* $Id: promboot.c,v 1.1.1.1 1997/03/03 19:31:07 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 4. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include "stand.h"
+#include "promboot.h"
+
+char prom_bootdev[32];
+char prom_bootfile[32];
+int prom_boothow;
+int debug;
+
+void
+prom_get_boot_info()
+{
+ char c, *src, *dst;
+ extern int devlun, ctrlun;
+ extern char *oparg, *opargend;
+
+#ifdef DEBUG
+ printf("prom_get_boot_info\n");
+#endif
+
+ /* Get kernel filename */
+ src = oparg;
+ while (src && (*src == ' ' || *src == '\t'))
+ src++;
+
+ dst = prom_bootfile;
+ if (src && *src != '-') {
+ while (src && *src) {
+ if (*src == ' ' || *src == '\t')
+ break;
+ *dst++ = *src++;
+ }
+ }
+ *dst = '\0';
+
+ /* Get boothowto flags */
+ while (src && (*src == ' ' || *src == '\t'))
+ src++;
+ if (src && (*src == '-')) {
+ while (*src) {
+ switch (*src++) {
+ case 'a':
+ prom_boothow |= RB_ASKNAME;
+ break;
+ case 's':
+ prom_boothow |= RB_SINGLE;
+ break;
+ case 'd':
+ prom_boothow |= RB_KDB;
+ debug = 1;
+ break;
+ }
+ }
+ }
+#ifdef DEBUG
+ printf("promboot: device=\"%s\" file=\"%s\" how=0x%x\n",
+ prom_bootdev, prom_bootfile, prom_boothow);
+#endif
+}
--- /dev/null
+
+extern char prom_bootdev[];
+extern char prom_bootfile[];
+extern int prom_boothow;
+
--- /dev/null
+/* $Id: promcons.c,v 1.1.1.1 1997/03/03 19:31:07 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 4. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdarg.h>
+#include <sys/types.h>
+
+int
+getchar()
+{
+ char c;
+
+ __asm("movb #0,sp@-; trap #15; .short 0x0; movb sp@+, %0" : : "d" (c));
+ return (c);
+}
+
+peekchar()
+{
+ int have = 0;
+
+ __asm("trap #15; .short 0x1; beq 1f; movl #1, %0\n1:" : : "d" (have));
+ return (have);
+}
+
+void
+putchar(c)
+ int c;
+{
+ if (c == '\n')
+ putchar('\r');
+ __asm("movb %0,sp@-; trap #15; .short 0x20" : : "d" (c));
+}
+
--- /dev/null
+/* $Id: promdev.c,v 1.1.1.1 1997/03/03 19:31:07 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Gordon W. Ross
+ * Copyright (c) 1993 Paul Kranenburg
+ * 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 Paul Kranenburg.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <machine/mon.h>
+#include <machine/pte.h>
+#include <machine/saio.h>
+
+#include <dvma.h>
+#include <stand.h>
+
+struct saioreq prom_si;
+static int promdev_inuse;
+
+static char *
+prom_mapin(u_long physaddr, int length, int maptype);
+
+int
+prom_iopen(void **devdatap)
+{
+ struct bootparam *bp;
+ struct boottab *ops;
+ struct devinfo *dip;
+ struct saioreq *si;
+ char *p;
+ int error;
+
+ if (promdev_inuse)
+ return(EMFILE);
+
+ bp = *romp->bootParam;
+ ops = bp->bootDevice;
+ dip = ops->b_devinfo;
+
+#ifdef DEBUG_PROM
+ printf("Boot device type: %s\n", ops->b_desc);
+#endif
+
+ dvma_init();
+
+ si = &prom_si;
+ bzero((caddr_t)si, sizeof(*si));
+ si->si_boottab = ops;
+ si->si_ctlr = bp->ctlrNum;
+ si->si_unit = bp->unitNum;
+ si->si_boff = bp->partNum;
+
+ if (si->si_ctlr > dip->d_stdcount) {
+ printf("Invalid controller number\n");
+ return(ENXIO);
+ }
+
+ if (dip->d_devbytes) {
+ si->si_devaddr = prom_mapin(dip->d_stdaddrs[si->si_ctlr],
+ dip->d_devbytes, dip->d_devtype);
+#ifdef DEBUG_PROM
+ printf("prom_iopen: devaddr=0x%x pte=0x%x\n",
+ si->si_devaddr, get_pte(si->si_devaddr));
+#endif
+ }
+
+ if (dip->d_dmabytes) {
+ si->si_dmaaddr = dvma_alloc(dip->d_dmabytes);
+#ifdef DEBUG_PROM
+ printf("prom_iopen: dmaaddr=0x%x\n", si->si_dmaaddr);
+#endif
+ }
+
+ /* OK, call the PROM device open routine. */
+ error = (*ops->b_open)(si);
+ if (error != 0) {
+ printf("prom_iopen: \"%s\" error=%d\n",
+ ops->b_desc, error);
+ return (ENXIO);
+ }
+#ifdef DEBUG_PROM
+ printf("prom_iopen: succeeded, error=%d\n", error);
+#endif
+
+ *devdatap = si;
+ promdev_inuse++;
+ return (0);
+}
+
+void
+prom_iclose(void *devdata)
+{
+ struct boottab *ops;
+ struct devinfo *dip;
+ struct saioreq *si;
+
+ if (promdev_inuse == 0)
+ return;
+
+ si = devdata;
+ ops = si->si_boottab;
+ dip = ops->b_devinfo;
+
+ (*ops->b_close)(si);
+
+ if (si->si_dmaaddr) {
+ dvma_free(si->si_dmaaddr, dip->d_dmabytes);
+ si->si_dmaaddr = NULL;
+ }
+
+ promdev_inuse = 0;
+}
+
+struct mapinfo {
+ int maptype;
+ int pgtype;
+ int base;
+};
+
+static struct mapinfo
+prom_mapinfo[] = {
+ { MAP_MAINMEM, PGT_OBMEM, 0 },
+ { MAP_OBIO, PGT_OBIO, 0 },
+ { MAP_MBMEM, PGT_OBMEM, 0 }, /* XXX - Sun2 Multibus? */
+ { MAP_MBIO, PGT_OBIO, 0 }, /* XXX - Sun2 Multibus? */
+ { MAP_VME16A16D, PGT_VME_D16, 0xFFFF0000 },
+ { MAP_VME16A32D, PGT_VME_D32, 0xFFFF0000 },
+ { MAP_VME24A16D, PGT_VME_D16, 0xFF000000 },
+ { MAP_VME24A32D, PGT_VME_D32, 0xFF000000 },
+ { MAP_VME32A16D, PGT_VME_D16, 0 },
+ { MAP_VME32A32D, PGT_VME_D32, 0 },
+};
+static prom_mapinfo_cnt = sizeof(prom_mapinfo) / sizeof(prom_mapinfo[0]);
+
+/* The virtual address we will use for PROM device mappings. */
+static int prom_devmap = MONSHORTSEG;
+
+static char *
+prom_mapin(physaddr, length, maptype)
+ u_long physaddr;
+ int length, maptype;
+{
+ int i, pa, pte, va;
+
+ if (length > (4*NBPG))
+ panic("prom_mapin: length=%d\n", length);
+
+ for (i = 0; i < prom_mapinfo_cnt; i++)
+ if (prom_mapinfo[i].maptype == maptype)
+ goto found;
+ panic("prom_mapin: invalid maptype %d\n", maptype);
+found:
+
+ pte = prom_mapinfo[i].pgtype;
+ pte |= PG_PERM;
+ pa = prom_mapinfo[i].base;
+ pa += physaddr;
+ pte |= PA_PGNUM(pa);
+
+ va = prom_devmap;
+ do {
+ set_pte(va, pte);
+ va += NBPG;
+ pte += 1;
+ length -= NBPG;
+ } while (length > 0);
+ return ((char*)prom_devmap);
+}
--- /dev/null
+
+int prom_iopen(struct saioreq **sipp);
+void prom_iclose(struct saioreq *sip);
+
--- /dev/null
+# $Id: Makefile,v 1.1.1.1 1997/03/03 19:31:08 rahnds Exp $
+
+RELOC=0x3F0000
+
+S= ${.CURDIR}/../../../..
+DEFS= -DSTANDALONE -DSUN_BOOTPARAMS
+INCPATH=-I${.CURDIR} -I${.CURDIR}/../libsa -I${S} -I${S}/lib/libsa
+CFLAGS= -O2 ${INCPATH} ${DEFS} ${COPTS}
+
+.include "${S}/arch/${MACHINE}/stand/libsa/Makefile.inc"
+.PATH: ${S}/arch/${MACHINE}/stand/libsa
+SRTOBJ= SRT0.o SRT1.o
+
+SRCS= boot.c conf.c version.c dev_net.c
+SRCS+= if_ie.c if_le.c
+OBJS= ${SRTOBJ} ${SRCS:S/.c/.o/g}
+
+all: netboot.bin
+
+netboot: ${OBJS} ${LIBSA}
+ ${LD} -s -N -T ${RELOC} -e start -o $@ ${OBJS} ${LIBSA}
+ @size $@
+
+netboot.bin: netboot
+ dd ibs=32 skip=1 if=netboot of=$@
+
+install:
+ install ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
+ netboot.bin ${DESTDIR}${MDEC_DIR}/netboot
+
+.include <bsd.prog.mk>
--- /dev/null
+/* $Id: boot.c,v 1.1.1.1 1997/03/03 19:31:08 rahnds Exp $ */
+
+/*-
+ * Copyright (c) 1995 Theo de Raadt
+ * 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 Theo de Raadt
+ * 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.
+ *
+ * Copyright (c) 1982, 1986, 1990, 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.
+ *
+ * @(#)boot.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+
+#include "stand.h"
+#include "promboot.h"
+
+/*
+ * Boot device is derived from ROM provided information.
+ */
+#define LOADADDR 0x10000
+
+extern char *version;
+char defname[32] = "bsd";
+char line[80];
+
+#if 0
+u_int bootdev = MAKEBOOTDEV(0, sdmajor, 0, 0, 0); /* disk boot */
+#endif
+u_int bootdev = MAKEBOOTDEV(1, 0, 0, 0, 0); /* network boot */
+
+main()
+{
+ char *cp, *file;
+ int io;
+ extern int cputyp;
+ extern char *oparg, *opargend;
+ int ask = 0;
+
+ printf(">> OpenBSD netboot [%s]\n", version);
+ printf("model MVME%x\n", cputyp);
+
+ *opargend = '\0';
+ prom_get_boot_info();
+ file = defname;
+
+ cp = prom_bootfile;
+ if (cp && *cp)
+ file = cp;
+
+ for (;;) {
+ if (ask) {
+ printf("boot: ");
+ gets(line);
+ if (line[0]) {
+ oparg = line;
+ prom_get_boot_info();
+ }
+ }
+ exec_sun(file, (char *)LOADADDR, prom_boothow);
+ printf("boot: %s\n", strerror(errno));
+ ask = 1;
+ }
+}
--- /dev/null
+/* $Id: conf.c,v 1.1.1.1 1997/03/03 19:31:08 rahnds Exp $ */
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <stand.h>
+#include <nfs.h>
+#include <dev_net.h>
+
+struct fs_ops file_system[] = {
+ { nfs_open, nfs_close, nfs_read, nfs_write, nfs_seek, nfs_stat },
+};
+int nfsys = sizeof(file_system) / sizeof(file_system[0]);
+
+struct devsw devsw[] = {
+ { "net", net_strategy, net_open, net_close, net_ioctl },
+};
+int ndevs = sizeof(devsw) / sizeof(devsw[0]);
+
+extern struct netif_driver le_driver;
+extern struct netif_driver ie_driver;
+
+struct netif_driver *netif_drivers[] = {
+ &le_driver,
+ &ie_driver,
+};
+int n_netif_drivers = sizeof(netif_drivers) / sizeof(netif_drivers[0]);
+
+
+/* XXX */
+int netif_debug;
+int debug;
+int errno;
--- /dev/null
+/* $Id: dev_net.c,v 1.1.1.1 1997/03/03 19:31:08 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Gordon W. Ross
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * 4. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Gordon W. Ross
+ *
+ * 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.
+ */
+
+/*
+ * This module implements a "raw device" interface suitable for
+ * use by the stand-alone I/O library NFS code. This interface
+ * does not support any "block" access, and exists only for the
+ * purpose of initializing the network interface, getting boot
+ * parameters, and performing the NFS mount.
+ *
+ * At open time, this does:
+ *
+ * find interface - netif_open()
+ * RARP for IP address - rarp_getipaddress()
+ * RPC/bootparams - callrpc(d, RPC_BOOTPARAMS, ...)
+ * RPC/mountd - nfs_mount(sock, ip, path)
+ *
+ * the root file handle from mountd is saved in a global
+ * for use by the NFS open code (NFS/lookup).
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+#include "config.h"
+#include "bootparam.h"
+
+extern int nfs_root_node[]; /* XXX - get from nfs_mount() */
+
+struct in_addr myip, rootip, gateip, mask;
+char rootpath[FNAME_SIZE];
+
+int netdev_sock = -1;
+static int open_count;
+
+/*
+ * Called by devopen after it sets f->f_dev to our devsw entry.
+ * This opens the low-level device and sets f->f_devdata.
+ */
+int
+net_open(f, devname)
+ struct open_file *f;
+ char *devname; /* Device part of file name (or NULL). */
+{
+ int error = 0;
+
+ /* On first open, do netif open, mount, etc. */
+ if (open_count == 0) {
+ /* Find network interface. */
+ if ((netdev_sock = netif_open(devname)) < 0)
+ return (error=ENXIO);
+ if ((error = net_mountroot(f, devname)) != 0)
+ return (error);
+ }
+ open_count++;
+ f->f_devdata = nfs_root_node;
+ return (error);
+}
+
+int
+net_close(f)
+ struct open_file *f;
+{
+ /* On last close, do netif close, etc. */
+ if (open_count > 0)
+ if (--open_count == 0)
+ netif_close(netdev_sock);
+ f->f_devdata = NULL;
+}
+
+int
+net_ioctl()
+{
+ return EIO;
+}
+
+int
+net_strategy()
+{
+ return EIO;
+}
+
+int
+net_mountroot(f, devname)
+ struct open_file *f;
+ char *devname; /* Device part of file name (or NULL). */
+{
+ int error;
+
+#ifdef DEBUG
+ printf("net_mountroot: %s\n", devname);
+#endif
+
+ /*
+ * Get info for NFS boot: our IP address, our hostname,
+ * server IP address, and our root path on the server.
+ * There are two ways to do this: The old, Sun way,
+ * and the more modern, BOOTP way. (RFC951, RFC1048)
+ */
+
+#ifdef SUN_BOOTPARAMS
+ /* Get boot info using RARP and Sun bootparams. */
+
+ /* Get our IP address. (rarp.c) */
+ if (rarp_getipaddress(netdev_sock) == -1)
+ return (EIO);
+ printf("boot: client IP address: %s\n", intoa(myip.s_addr));
+
+ /* Get our hostname, server IP address. */
+ if (bp_whoami(netdev_sock))
+ return (EIO);
+ printf("boot: client name: %s\n", hostname);
+
+ /* Get the root pathname. */
+ if (bp_getfile(netdev_sock, "root", &rootip, rootpath))
+ return (EIO);
+
+#else
+
+ /* Get boot info using BOOTP way. (RFC951, RFC1048) */
+ bootp(netdev_sock);
+
+ printf("Using IP address: %s\n", intoa(myip.s_addr));
+
+ printf("myip: %s (%s)", hostname, intoa(myip));
+ if (gateip)
+ printf(", gateip: %s", intoa(gateip));
+ if (mask)
+ printf(", mask: %s", intoa(mask));
+ printf("\n");
+
+#endif
+
+ printf("root addr=%s path=%s\n", intoa(rootip.s_addr), rootpath);
+
+ /* Get the NFS file handle (mount). */
+ error = nfs_mount(netdev_sock, rootip, rootpath);
+
+ return (error);
+}
+
+/*
+ * machdep_common_ether: get ethernet address
+ */
+void
+machdep_common_ether(ether)
+ u_char *ether;
+{
+ u_char *ea;
+ extern int cputyp;
+
+ if (cputyp == CPU_147) {
+ ea = (u_char *) ETHER_ADDR_147;
+
+ if ((*(int *) ea & 0x2fffff00) == 0x2fffff00)
+ panic("ERROR: ethernet address not set!\r\n");
+ ether[0] = 0x08;
+ ether[1] = 0x00;
+ ether[2] = 0x3e;
+ ether[3] = ea[0];
+ ether[4] = ea[1];
+ ether[5] = ea[2];
+ } else {
+ ea = (u_char *) ETHER_ADDR_16X;
+
+ if (ea[0] + ea[1] + ea[2] + ea[3] + ea[4] + ea[5] == 0)
+ panic("ERROR: ethernet address not set!\r\n");
+ ether[0] = ea[0];
+ ether[1] = ea[1];
+ ether[2] = ea[2];
+ ether[3] = ea[3];
+ ether[4] = ea[4];
+ ether[5] = ea[5];
+ }
+}
--- /dev/null
+
+int net_open __P((struct open_file *, ...));
+int net_close __P((struct open_file *));
+int net_ioctl();
+int net_strategy();
+
--- /dev/null
+/* $Id: i82586.h,v 1.1.1.1 1997/03/03 19:31:08 rahnds Exp $ */
+
+/*-
+ * Copyright (c) 1995 Theo de Raadt
+ * Copyright (c) 1992, University of Vermont and State Agricultural College.
+ * Copyright (c) 1992, Garrett A. Wollman.
+ * 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
+ * Vermont and State Agricultural College and Garrett A. Wollman.
+ * 4. Neither the name of the University nor the name of the author
+ * 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 UNIVERSITY OR 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.
+ */
+
+/*
+ * Intel 82586 Ethernet chip
+ * Register, bit, and structure definitions.
+ *
+ * Written by GAW with reference to the Clarkson Packet Driver code for this
+ * chip written by Russ Nelson and others.
+ */
+
+struct ie_en_addr {
+ u_char data[6];
+};
+/*
+ * the only actual IE registers.
+ */
+struct iereg {
+ u_short ie_porthigh;
+ u_short ie_portlow;
+ u_long ie_attention;
+};
+#define IE_PORT_NEWSCP 0x00000002
+#define IE_PORT_RESET 0x00000000
+
+/*
+ * This is the master configuration block. It tells the hardware where
+ * all the rest of the stuff is.
+ */
+struct ie_scp {
+ u_char mbz1[3]; /* must be zero */
+ u_char scp_sysbus; /* true if 8-bit only */
+ u_char mbz2[4]; /* must be zero */
+ u_short scp_iscp_low; /* 24-bit physaddr of ISCP */
+ u_char mbz3[1];
+ u_char scp_iscp_high; /* the rest of the physaddr.. */
+};
+/*
+ * The tells the hardware where all the rest of the stuff is, too.
+ * FIXME: some of these should be re-commented after we figure out their
+ * REAL function.
+ */
+struct ie_iscp {
+ u_char mbz1[1];
+ u_char iscp_busy; /* zeroed after init */
+ u_short iscp_scboffset; /* 16-bit physaddr of next struct */
+ u_short iscp_base_low; /* 24-bit physaddr for all 16-bit vars */
+ u_char mbz2[1];
+ u_char iscp_base_high; /* rest of physaddr ... */
+};
+/*
+ * This FINALLY tells the hardware what to do and where to put it.
+ */
+struct ie_scb {
+ u_short ie_status; /* status word */
+ u_short ie_command; /* command word */
+ u_short ie_command_list;/* 16-pointer to command block list */
+ u_short ie_recv_list; /* 16-pointer to receive frame list */
+ u_short ie_err_crc; /* CRC errors */
+ u_short ie_err_align; /* Alignment errors */
+ u_short ie_err_resource;/* Resource errors */
+ u_short ie_err_overrun; /* Overrun errors */
+};
+/* Command values */
+#define IE_RU_COMMAND 0x0070 /* mask for RU command */
+#define IE_RU_NOP 0 /* for completeness */
+#define IE_RU_START 0x0010 /* start receive unit command */
+#define IE_RU_ENABLE 0x0020 /* enable receiver command */
+#define IE_RU_DISABLE 0x0030 /* disable receiver command */
+#define IE_RU_ABORT 0x0040 /* abort current receive operation */
+
+#define IE_CU_COMMAND 0x0700 /* mask for CU command */
+#define IE_CU_NOP 0 /* included for completeness */
+#define IE_CU_START 0x0100 /* do-command command */
+#define IE_CU_RESUME 0x0200 /* resume a suspended cmd list */
+#define IE_CU_STOP 0x0300 /* SUSPEND was already taken */
+#define IE_CU_ABORT 0x0400 /* abort current command */
+
+#define IE_ACK_COMMAND 0xf000 /* mask for ACK command */
+#define IE_ACK_CX 0x8000 /* ack IE_ST_DONE */
+#define IE_ACK_FR 0x4000 /* ack IE_ST_RECV */
+#define IE_ACK_CNA 0x2000 /* ack IE_ST_ALLDONE */
+#define IE_ACK_RNR 0x1000 /* ack IE_ST_RNR */
+
+#define IE_ACTION_COMMAND(x) (((x) & IE_CU_COMMAND) == IE_CU_START)
+ /* is this command an action command? */
+
+/* Status values */
+#define IE_ST_WHENCE 0xf000 /* mask for cause of interrupt */
+#define IE_ST_DONE 0x8000 /* command with I bit completed */
+#define IE_ST_RECV 0x4000 /* frame received */
+#define IE_ST_ALLDONE 0x2000 /* all commands completed */
+#define IE_ST_RNR 0x1000 /* receive not ready */
+
+#define IE_CU_STATUS 0x700 /* mask for command unit status */
+#define IE_CU_ACTIVE 0x200 /* command unit is active */
+#define IE_CU_SUSPEND 0x100 /* command unit is suspended */
+
+#define IE_RU_STATUS 0x70 /* mask for receiver unit status */
+#define IE_RU_SUSPEND 0x10 /* receiver is suspended */
+#define IE_RU_NOSPACE 0x20 /* receiver has no resources */
+#define IE_RU_READY 0x40 /* receiver is ready */
+
+/*
+ * This is filled in partially by the chip, partially by us.
+ */
+struct ie_recv_frame_desc {
+ u_short ie_fd_status; /* status for this frame */
+ u_short ie_fd_last; /* end of frame list flag */
+ u_short ie_fd_next; /* 16-pointer to next RFD */
+ u_short ie_fd_buf_desc; /* 16-pointer to list of buffer desc's */
+ struct ie_en_addr dest; /* destination ether */
+ struct ie_en_addr src; /* source ether */
+ u_short ie_length; /* 802 length/Ether type */
+ u_short mbz; /* must be zero */
+};
+#define IE_FD_LAST 0x8000 /* last rfd in list */
+#define IE_FD_SUSP 0x4000 /* suspend RU after receipt */
+
+#define IE_FD_COMPLETE 0x8000 /* frame is complete */
+#define IE_FD_BUSY 0x4000 /* frame is busy */
+#define IE_FD_OK 0x2000 /* frame is bad */
+#define IE_FD_RNR 0x0200 /* receiver out of resources here */
+
+/*
+ * linked list of buffers...
+ */
+struct ie_recv_buf_desc {
+ u_short ie_rbd_actual; /* status for this buffer */
+ u_short ie_rbd_next; /* 16-pointer to next RBD */
+ u_short ie_rbd_buffer_low; /* 24-pointer to buffer for this RBD */
+ u_short ie_rbd_buffer_high; /* 24-pointer to buffer for this RBD */
+ u_short ie_rbd_length; /* length of the buffer */
+ u_short mbz; /* must be zero */
+};
+#define IE_RBD_LAST 0x8000 /* last buffer */
+#define IE_RBD_USED 0x4000 /* this buffer has data */
+/*
+ * All commands share this in common.
+ */
+struct ie_cmd_common {
+ u_short ie_cmd_status; /* status of this command */
+ u_short ie_cmd_cmd; /* command word */
+ u_short ie_cmd_link; /* link to next command */
+};
+#define IE_STAT_COMPL 0x8000 /* command is completed */
+#define IE_STAT_BUSY 0x4000 /* command is running now */
+#define IE_STAT_OK 0x2000 /* command completed successfully */
+#define IE_STAT_ABORT 0x1000 /* command was aborted */
+
+
+#define IE_CMD_NOP 0x0000 /* NOP */
+#define IE_CMD_IASETUP 0x0001 /* initial address setup */
+#define IE_CMD_CONFIG 0x0002 /* configure command */
+#define IE_CMD_MCAST 0x0003 /* multicast setup command */
+#define IE_CMD_XMIT 0x0004 /* transmit command */
+#define IE_CMD_TDR 0x0005 /* time-domain reflectometer command */
+#define IE_CMD_DUMP 0x0006 /* dump command */
+#define IE_CMD_DIAGNOSE 0x0007 /* diagnostics command */
+
+#define IE_CMD_LAST 0x8000 /* this is the last command in the list */
+#define IE_CMD_SUSPEND 0x4000 /* suspend CU after this command */
+#define IE_CMD_INTR 0x2000 /* post an interrupt after completion */
+
+/*
+ * This is the command to transmit a frame.
+ */
+struct ie_xmit_cmd {
+ struct ie_cmd_common com; /* common part */
+#define ie_xmit_status com.ie_cmd_status
+
+ u_short ie_xmit_desc; /* 16-pointer to buffer descriptor */
+ struct ie_en_addr ie_xmit_addr; /* destination address */
+
+ u_short ie_xmit_length; /* 802.3 length/Ether type field */
+};
+#define IE_XS_MAXCOLL 0x000f /* number of collisions during transmit */
+#define IE_XS_EXCMAX 0x0020 /* exceeded maximum number of collisions */
+#define IE_XS_SQE 0x0040 /* SQE positive */
+#define IE_XS_DEFERRED 0x0080 /* transmission deferred */
+#define IE_XS_UNDERRUN 0x0100 /* DMA underrun */
+#define IE_XS_LOSTCTS 0x0200 /* Lost CTS */
+#define IE_XS_NOCARRIER 0x0400 /* No Carrier */
+
+/*
+ * This is a buffer descriptor for a frame to be transmitted.
+ */
+
+struct ie_xmit_buf {
+ u_short ie_xmit_flags; /* see below */
+ u_short ie_xmit_next; /* 16-pointer to next desc. */
+ u_short ie_xmit_buf_low;/* 24-pointer to the actual buffer */
+ u_short ie_xmit_buf_high; /* 24-pointer to the actual buffer */
+};
+#define IE_XMIT_LAST 0x8000 /* this TBD is the last one */
+/* The rest of the `flags' word is actually the length. */
+
+/*
+ * Multicast setup command.
+ */
+
+#define MAXMCAST 250 /* must fit in transmit buffer */
+
+struct ie_mcast_cmd {
+ struct ie_cmd_common com; /* common part */
+#define ie_mcast_status com.ie_cmd_status
+
+ u_short ie_mcast_bytes; /* size (in bytes) of multicast addresses */
+ struct ie_en_addr ie_mcast_addrs[MAXMCAST + 1]; /* space for them */
+};
+/*
+ * Time Domain Reflectometer command.
+ */
+
+struct ie_tdr_cmd {
+ struct ie_cmd_common com; /* common part */
+#define ie_tdr_status com.ie_cmd_status
+
+ u_short ie_tdr_time; /* error bits and time */
+};
+#define IE_TDR_SUCCESS 0x8000 /* TDR succeeded without error */
+#define IE_TDR_XCVR 0x4000 /* detected a transceiver problem */
+#define IE_TDR_OPEN 0x2000 /* detected an open */
+#define IE_TDR_SHORT 0x1000 /* TDR detected a short */
+#define IE_TDR_TIME 0x07ff /* mask for reflection time */
+
+/*
+ * Initial Address Setup command
+ */
+struct ie_iasetup_cmd {
+ struct ie_cmd_common com;
+#define ie_iasetup_status com.ie_cmd_status
+
+ struct ie_en_addr ie_address;
+};
+/*
+ * Configuration command
+ */
+struct ie_config_cmd {
+ struct ie_cmd_common com; /* common part */
+#define ie_config_status com.ie_cmd_status
+
+ u_char ie_config_count;/* byte count (0x0c) */
+ u_char ie_fifo; /* fifo (8) */
+ u_char ie_save_bad; /* save bad frames (0x40) */
+ u_char ie_addr_len; /* address length (0x2e) (AL-LOC == 1) */
+ u_char ie_priority; /* priority and backoff (0x0) */
+ u_char ie_ifs; /* inter-frame spacing (0x60) */
+ u_char ie_slot_low; /* slot time, LSB (0x0) */
+ u_char ie_slot_high; /* slot time, MSN, and retries (0xf2) */
+ u_char ie_promisc; /* 1 if promiscuous, else 0 */
+ u_char ie_crs_cdt; /* CSMA/CD parameters (0x0) */
+ u_char ie_min_len; /* min frame length (0x40) */
+ u_char ie_junk; /* stuff for 82596 (0xff) */
+};
+
+struct iemem {
+ volatile struct ie_scp im_scp;
+ u_char xx1[4];
+ volatile struct ie_iscp im_iscp;
+
+ volatile struct ie_scb im_scb;
+ volatile struct ie_config_cmd im_cc;
+ volatile struct ie_iasetup_cmd im_ic;
+ volatile struct ie_recv_frame_desc im_rfd[NRXBUF];
+ volatile struct ie_recv_buf_desc im_rbd[NRXBUF];
+ volatile struct ie_xmit_cmd im_xc[NTXBUF];
+ volatile struct ie_xmit_buf im_xd[NTXBUF];
+ volatile u_char im_rxbuf[NRXBUF * IE_RBUF_SIZE];
+ volatile u_char im_txbuf[NTXBUF * ETHER_MAX_LEN];
+
+};
--- /dev/null
+/* $Id: if_ie.c,v 1.1.1.1 1997/03/03 19:31:09 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#define ETHER_MIN_LEN 64
+#define ETHER_MAX_LEN 1518
+
+#define NTXBUF 1
+#define NRXBUF 16
+#define IE_RBUF_SIZE ETHER_MAX_LEN
+
+#include "stand.h"
+#include "netif.h"
+#include "config.h"
+
+#include "i82586.h"
+#include "if_iereg.h"
+
+int ie_debug = 0;
+
+void ie_stop __P((struct netif *));
+void ie_end __P((struct netif *));
+void ie_error __P((struct netif *, char *, volatile struct iereg *));
+int ie_get __P((struct iodesc *, void *, size_t, time_t));
+void ie_init __P((struct iodesc *, void *));
+int ie_match __P((struct netif *, void *));
+int ie_poll __P((struct iodesc *, void *, int));
+int ie_probe __P((struct netif *, void *));
+int ie_put __P((struct iodesc *, void *, size_t));
+void ie_reset __P((struct netif *, u_char *));
+
+struct netif_stats ie_stats;
+
+struct netif_dif ie0_dif = {
+ 0, /* unit */
+ 1, /* nsel */
+ &ie_stats,
+ 0,
+ 0,
+};
+
+struct netif_driver ie_driver = {
+ "ie", /* netif_bname */
+ ie_match, /* match */
+ ie_probe, /* probe */
+ ie_init, /* init */
+ ie_get, /* get */
+ ie_put, /* put */
+ ie_end, /* end */
+ &ie0_dif, /* netif_ifs */
+ 1, /* netif_nifs */
+};
+
+struct ie_configuration {
+ u_int phys_addr;
+ int used;
+} ie_config[] = {
+ { INTEL_REG_ADDR, 0 }
+};
+
+int nie_config = sizeof(ie_config) / (sizeof(ie_config[0]));
+
+struct {
+ struct iereg *sc_reg; /* IE registers */
+ struct iemem *sc_mem; /* RAM */
+} ie_softc;
+
+int
+ie_match(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+ char *name;
+ int i, val = 0;
+ extern int cputyp;
+
+ if (cputyp == CPU_147)
+ return (0);
+ name = machdep_hint;
+ if (name && !bcmp(ie_driver.netif_bname, name, 2))
+ val += 10;
+ for (i = 0; i < nie_config; i++) {
+ if (ie_config[i].used)
+ continue;
+ if (ie_debug)
+ printf("ie%d: ie_match --> %d\n", i, val + 1);
+ ie_config[i].used++;
+ return (val + 1);
+ }
+ if (ie_debug)
+ printf("ie%d: ie_match --> 0\n", i);
+ return (0);
+}
+
+int
+ie_probe(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+ extern int cputyp;
+
+ /* the set unit is the current unit */
+ if (ie_debug)
+ printf("ie%d: ie_probe called\n", nif->nif_unit);
+
+ if (cputyp != CPU_147)
+ return (0);
+ return (1);
+}
+
+void
+ie_error(nif, str, ier)
+ struct netif *nif;
+ char *str;
+ volatile struct iereg *ier;
+{
+ panic("ie%d: unknown error\n", nif->nif_unit);
+}
+
+ieack(ier, iem)
+ volatile struct iereg *ier;
+ struct iemem *iem;
+{
+ /* ack the `interrupt' */
+ iem->im_scb.ie_command = iem->im_scb.ie_status & IE_ST_WHENCE;
+ ier->ie_attention = 1; /* chan attention! */
+ while (iem->im_scb.ie_command)
+ ;
+}
+
+void
+ie_reset(nif, myea)
+ struct netif *nif;
+ u_char *myea;
+{
+ volatile struct iereg *ier = ie_softc.sc_reg;
+ struct iemem *iem = ie_softc.sc_mem;
+ int timo = 10000, stat, i;
+ volatile int t;
+ u_int a;
+
+ if (ie_debug)
+ printf("ie%d: ie_reset called\n", nif->nif_unit);
+
+ /*printf("ier %x iem %x\n", ier, iem);*/
+
+ *(u_char *)0xfff4202a = 0x40;
+
+ bzero(iem, sizeof(*iem));
+ iem->im_scp.scp_sysbus = 0;
+ iem->im_scp.scp_iscp_low = (int) &iem->im_iscp & 0xffff;
+ iem->im_scp.scp_iscp_high = (int) &iem->im_iscp >> 16;
+
+ iem->im_iscp.iscp_scboffset = (int) &iem->im_scb - (int) iem;
+ iem->im_iscp.iscp_busy = 1;
+ iem->im_iscp.iscp_base_low = (int) iem & 0xffff;
+ iem->im_iscp.iscp_base_high = (int) iem >> 16;
+
+ /*
+ * completely and utterly unlike what i expected, the
+ * "write" order is:
+ * 1st: d15-d0 -> high address
+ * 2nd: d31-d16 -> low address
+ */
+
+ /* reset chip */
+ a = IE_PORT_RESET;
+ ier->ie_porthigh = a & 0xffff;
+ t = 0;
+ t = 1;
+ ier->ie_portlow = a >> 16;
+ for (t = timo; t--;)
+ ;
+
+ /* set new SCP pointer */
+ a = (int) &iem->im_scp | IE_PORT_NEWSCP;
+ ier->ie_porthigh = a & 0xffff;
+ t = 0;
+ t = 1;
+ ier->ie_portlow = a >> 16;
+ for (t = timo; t--;)
+ ;
+
+ ier->ie_attention = 1; /* chan attention! */
+ for (t = timo * 10; t--;)
+ ;
+
+ /* send CONFIGURE command */
+ iem->im_scb.ie_command = IE_CU_START;
+ iem->im_scb.ie_command_list = (int) &iem->im_cc - (int) iem;
+ iem->im_cc.com.ie_cmd_status = 0;
+ iem->im_cc.com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
+ iem->im_cc.com.ie_cmd_link = 0xffff;
+ iem->im_cc.ie_config_count = 0x0c;
+ iem->im_cc.ie_fifo = 8;
+ iem->im_cc.ie_save_bad = 0x40;
+ iem->im_cc.ie_addr_len = 0x2e;
+ iem->im_cc.ie_priority = 0;
+ iem->im_cc.ie_ifs = 0x60;
+ iem->im_cc.ie_slot_low = 0;
+ iem->im_cc.ie_slot_high = 0xf2;
+ iem->im_cc.ie_promisc = 0;
+ iem->im_cc.ie_crs_cdt = 0;
+ iem->im_cc.ie_min_len = 64;
+ iem->im_cc.ie_junk = 0xff;
+
+ ier->ie_attention = 1; /* chan attention! */
+ for (t = timo * 10; t--;)
+ ;
+
+ ieack(ier, iem);
+
+ /*printf("ic %x\n", &iem->im_ic);*/
+ /* send IASETUP command */
+ iem->im_scb.ie_command = IE_CU_START;
+ iem->im_scb.ie_command_list = (int) &iem->im_ic - (int) iem;
+ iem->im_ic.com.ie_cmd_status = 0;
+ iem->im_ic.com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
+ iem->im_ic.com.ie_cmd_link = 0xffff;
+ bcopy(myea, (void *)&iem->im_ic.ie_address, sizeof iem->im_ic.ie_address);
+
+ ier->ie_attention = 1; /* chan attention! */
+ for (t = timo * 10; t--;)
+ ;
+
+ ieack(ier, iem);
+
+ /* setup buffers */
+
+ for (i = 0; i < NRXBUF; i++) {
+ iem->im_rfd[i].ie_fd_next = (int) &iem->im_rfd[(i+1) % NRXBUF] -
+ (int) iem;
+ iem->im_rbd[i].ie_rbd_next = (int) &iem->im_rbd[(i+1) % NRXBUF] -
+ (int) iem;
+ a = (int) &iem->im_rxbuf[i * IE_RBUF_SIZE];
+ iem->im_rbd[i].ie_rbd_buffer_low = a & 0xffff;
+ iem->im_rbd[i].ie_rbd_buffer_high = a >> 16;
+ iem->im_rbd[i].ie_rbd_length = IE_RBUF_SIZE;
+ }
+ iem->im_rfd[NRXBUF-1].ie_fd_last |= IE_FD_LAST;
+ iem->im_rbd[NRXBUF-1].ie_rbd_length |= IE_RBD_LAST;
+ iem->im_rfd[0].ie_fd_buf_desc = (int) &iem->im_rbd[0] - (int) iem;
+
+ /*printf("rfd[0] %x rbd[0] %x buf[0] %x\n", &iem->im_rfd, &iem->im_rbd,
+ &iem->im_rxbuf);*/
+
+ /* send receiver start command */
+ iem->im_scb.ie_command = IE_RU_START;
+ iem->im_scb.ie_command_list = 0;
+ iem->im_scb.ie_recv_list = (int) &iem->im_rfd[0] - (int) iem;
+ ier->ie_attention = 1; /* chan attention! */
+ while (iem->im_scb.ie_command)
+ ;
+
+ ieack(ier, iem);
+}
+
+int
+ie_poll(desc, pkt, len)
+ struct iodesc *desc;
+ void *pkt;
+ int len;
+{
+ volatile struct iereg *ier = ie_softc.sc_reg;
+ struct iemem *iem = ie_softc.sc_mem;
+ u_char *p = pkt;
+ static int slot;
+ int length = 0;
+ u_int a;
+ u_short status;
+
+ asm(".word 0xf518\n");
+ status = iem->im_rfd[slot].ie_fd_status;
+ if (status & IE_FD_BUSY)
+ return (0);
+
+ /* printf("slot %d: %x\n", slot, status); */
+ if ((status & (IE_FD_COMPLETE | IE_FD_OK)) == (IE_FD_COMPLETE | IE_FD_OK)) {
+ if (status & IE_FD_OK) {
+ length = iem->im_rbd[slot].ie_rbd_actual & 0x3fff;
+ if (length > len)
+ length = len;
+ bcopy((void *)&iem->im_rxbuf[slot * IE_RBUF_SIZE],
+ pkt, length);
+
+ iem->im_rfd[slot].ie_fd_status = 0;
+ iem->im_rfd[slot].ie_fd_last |= IE_FD_LAST;
+ iem->im_rfd[(slot+NRXBUF-1)%NRXBUF].ie_fd_last &=
+ ~IE_FD_LAST;
+ iem->im_rbd[slot].ie_rbd_actual = 0;
+ iem->im_rbd[slot].ie_rbd_length |= IE_RBD_LAST;
+ iem->im_rbd[(slot+NRXBUF-1)%NRXBUF].ie_rbd_length &=
+ ~IE_RBD_LAST;
+ /*printf("S%d\n", slot);*/
+
+ } else {
+ printf("shit\n");
+ }
+ slot++;
+ /* should move descriptor onto end of queue... */
+ }
+ if ((iem->im_scb.ie_status & IE_RU_READY) == 0) {
+ printf("RR\n");
+
+ for (slot = 0; slot < NRXBUF; slot++) {
+ iem->im_rbd[slot].ie_rbd_length &= ~IE_RBD_LAST;
+ iem->im_rfd[slot].ie_fd_last &= ~IE_FD_LAST;
+ }
+ iem->im_rbd[NRXBUF-1].ie_rbd_length |= IE_RBD_LAST;
+ iem->im_rfd[NRXBUF-1].ie_fd_last |= IE_FD_LAST;
+
+ iem->im_rfd[0].ie_fd_buf_desc = (int)&iem->im_rbd[0] - (int)iem;
+
+ iem->im_scb.ie_command = IE_RU_START;
+ iem->im_scb.ie_command_list = 0;
+ iem->im_scb.ie_recv_list = (int)&iem->im_rfd[0] - (int)iem;
+ ier->ie_attention = 1; /* chan attention! */
+ while (iem->im_scb.ie_command)
+ ;
+ slot = 0;
+ }
+ slot = slot % NRXBUF;
+ return (length);
+}
+
+int
+ie_put(desc, pkt, len)
+ struct iodesc *desc;
+ void *pkt;
+ size_t len;
+{
+ volatile struct iereg *ier = ie_softc.sc_reg;
+ struct iemem *iem = ie_softc.sc_mem;
+ u_char *p = pkt;
+ int timo = 10000, stat, i;
+ volatile int t;
+ u_int a;
+ int xx = 0;
+
+ /* send transmit command */
+
+ while (iem->im_scb.ie_command)
+ ;
+
+ /* copy data */
+ bcopy(p, (void *)&iem->im_txbuf[xx], len);
+
+ len = MAX(len, ETHER_MIN_LEN);
+
+ /* build transmit descriptor */
+ iem->im_xd[xx].ie_xmit_flags = len | IE_XMIT_LAST;
+ iem->im_xd[xx].ie_xmit_next = 0xffff;
+ a = (int) &iem->im_txbuf[xx];
+ iem->im_xd[xx].ie_xmit_buf_low = a & 0xffff;
+ iem->im_xd[xx].ie_xmit_buf_high = a >> 16;
+
+ /* transmit command */
+ iem->im_xc[xx].com.ie_cmd_status = 0;
+ iem->im_xc[xx].com.ie_cmd_cmd = IE_CMD_XMIT | IE_CMD_LAST;
+ iem->im_xc[xx].com.ie_cmd_link = 0xffff;
+ iem->im_xc[xx].ie_xmit_desc = (int) &iem->im_xd[xx] - (int) iem;
+ iem->im_xc[xx].ie_xmit_length = len;
+ bcopy(p, (void *)&iem->im_xc[xx].ie_xmit_addr,
+ sizeof iem->im_xc[xx].ie_xmit_addr);
+
+ iem->im_scb.ie_command = IE_CU_START;
+ iem->im_scb.ie_command_list = (int) &iem->im_xc[xx] - (int) iem;
+
+ ier->ie_attention = 1; /* chan attention! */
+
+ if (ie_debug) {
+ printf("ie%d: send %d to %x:%x:%x:%x:%x:%x\n",
+ desc->io_netif->nif_unit, len,
+ p[0], p[1], p[2], p[3], p[4], p[5]);
+ }
+ return (len);
+}
+
+int
+ie_get(desc, pkt, len, timeout)
+ struct iodesc *desc;
+ void *pkt;
+ size_t len;
+ time_t timeout;
+{
+ time_t t;
+ int cc;
+
+ t = getsecs();
+ cc = 0;
+ while (((getsecs() - t) < timeout) && !cc) {
+ cc = ie_poll(desc, pkt, len);
+ }
+ return (cc);
+}
+/*
+ * init ie device. return 0 on failure, 1 if ok.
+ */
+void
+ie_init(desc, machdep_hint)
+ struct iodesc *desc;
+ void *machdep_hint;
+{
+ struct netif *nif = desc->io_netif;
+
+ if (ie_debug)
+ printf("ie%d: ie_init called\n", desc->io_netif->nif_unit);
+ machdep_common_ether(desc->myea);
+ bzero(&ie_softc, sizeof(ie_softc));
+ ie_softc.sc_reg =
+ (struct iereg *) ie_config[desc->io_netif->nif_unit].phys_addr;
+ ie_softc.sc_mem = (struct iemem *) 0x1e0000;
+ ie_reset(desc->io_netif, desc->myea);
+ printf("device: %s%d attached to %s\n", nif->nif_driver->netif_bname,
+ nif->nif_unit, ether_sprintf(desc->myea));
+}
+
+void
+ie_stop(nif)
+ struct netif *nif;
+{
+ volatile struct iereg *ier = ie_softc.sc_reg;
+ struct iemem *iem = ie_softc.sc_mem;
+ int timo = 10000;
+ volatile int t;
+ u_int a;
+
+ iem->im_iscp.iscp_busy = 1;
+ /* reset chip */
+ a = IE_PORT_RESET;
+ ier->ie_porthigh = a & 0xffff;
+ t = 0;
+ t = 1;
+ ier->ie_portlow = a >> 16;
+ for (t = timo; t--;)
+ ;
+
+ /* reset chip again */
+ a = IE_PORT_RESET;
+ ier->ie_porthigh = a & 0xffff;
+ t = 0;
+ t = 1;
+ ier->ie_portlow = a >> 16;
+ for (t = timo; t--;)
+ ;
+
+ /*printf("status %x busy %x\n", iem->im_scb.ie_status,
+ iem->im_iscp.iscp_busy);*/
+}
+
+void
+ie_end(nif)
+ struct netif *nif;
+{
+ if (ie_debug)
+ printf("ie%d: ie_end called\n", nif->nif_unit);
+
+ ie_stop(nif);
+
+ /* *(u_char *) 0xfff42002 = 0; */
+}
--- /dev/null
+/* $Id: if_iereg.h,v 1.1.1.1 1997/03/03 19:31:09 rahnds Exp $ */
+
+/*
+ * if_sunie.h
+ *
+ * sun's ie interface
+ */
+
+/*
+ * programming notes:
+ *
+ * the ie chip operates in a 24 bit address space.
+ *
+ * most ie interfaces appear to be divided into two parts:
+ * - generic 586 stuff
+ * - board specific
+ *
+ * generic:
+ * the generic stuff of the ie chip is all done with data structures
+ * that live in the chip's memory address space. the chip expects
+ * its main data structure (the sys conf ptr -- SCP) to be at a fixed
+ * address in its 24 bit space: 0xfffff4
+ *
+ * the SCP points to another structure called the ISCP.
+ * the ISCP points to another structure called the SCB.
+ * the SCB has a status field, a linked list of "commands", and
+ * a linked list of "receive buffers". these are data structures that
+ * live in memory, not registers.
+ *
+ * board:
+ * to get the chip to do anything, you first put a command in the
+ * command data structure list. then you have to signal "attention"
+ * to the chip to get it to look at the command. how you
+ * signal attention depends on what board you have... on PC's
+ * there is an i/o port number to do this, on sun's there is a
+ * register bit you toggle.
+ *
+ * to get data from the chip you program it to interrupt...
+ *
+ *
+ * sun issues:
+ *
+ * there are 3 kinds of sun "ie" interfaces:
+ * 1 - a VME/multibus card
+ * 2 - an on-board interface (sun3's, sun-4/100's, and sun-4/200's)
+ * 3 - another VME board called the 3E
+ *
+ * the VME boards lives in vme16 space. only 16 and 8 bit accesses
+ * are allowed, so functions that copy data must be aware of this.
+ *
+ * the chip is an intel chip. this means that the byte order
+ * on all the "short"s in the chip's data structures is wrong.
+ * so, constants described in the intel docs are swapped for the sun.
+ * that means that any buffer pointers you give the chip must be
+ * swapped to intel format. yuck.
+ *
+ * VME/multibus interface:
+ * for the multibus interface the board ignores the top 4 bits
+ * of the chip address. the multibus interface seems to have its
+ * own MMU like page map (without protections or valid bits, etc).
+ * there are 256 pages of physical memory on the board (each page
+ * is 1024 bytes). there are 1024 slots in the page map. so,
+ * a 1024 byte page takes up 10 bits of address for the offset,
+ * and if there are 1024 slots in the page that is another 10 bits
+ * of the address. that makes a 20 bit address, and as stated
+ * earlier the board ignores the top 4 bits, so that accounts
+ * for all 24 bits of address.
+ *
+ * note that the last entry of the page map maps the top of the
+ * 24 bit address space and that the SCP is supposed to be at
+ * 0xfffff4 (taking into account allignment). so,
+ * for multibus, that entry in the page map has to be used for the SCP.
+ *
+ * the page map effects BOTH how the ie chip sees the
+ * memory, and how the host sees it.
+ *
+ * the page map is part of the "register" area of the board
+ *
+ * on-board interface:
+ *
+ * <fill in useful info later>
+ *
+ *
+ * VME3E interface:
+ *
+ * <fill in useful info later>
+ *
+ */
+
+/*
+ * PART 1: VME/multibus defs
+ */
+#define IEVME_PAGESIZE 1024 /* bytes */
+#define IEVME_PAGSHIFT 10 /* bits */
+#define IEVME_NPAGES 256 /* number of pages on chip */
+#define IEVME_MAPSZ 1024 /* number of entries in the map */
+
+/*
+ * PTE for the page map
+ */
+#define IEVME_SBORDR 0x8000 /* sun byte order */
+#define IEVME_IBORDR 0x0000 /* intel byte ordr */
+
+#define IEVME_P2MEM 0x2000 /* memory is on P2 */
+#define IEVME_OBMEM 0x0000 /* memory is on board */
+
+#define IEVME_PGMASK 0x0fff /* gives the physical page frame number */
+
+struct ievme {
+ u_short pgmap[IEVME_MAPSZ];
+ u_short xxx[32]; /* prom */
+ u_short status; /* see below for bits */
+ u_short xxx2; /* filler */
+ u_short pectrl; /* parity control (see below) */
+ u_short peaddr; /* low 16 bits of address */
+};
+/*
+ * status bits
+ */
+#define IEVME_RESET 0x8000 /* reset board */
+#define IEVME_ONAIR 0x4000 /* go out of loopback 'on-air' */
+#define IEVME_ATTEN 0x2000 /* attention */
+#define IEVME_IENAB 0x1000 /* interrupt enable */
+#define IEVME_PEINT 0x0800 /* parity error interrupt enable */
+#define IEVME_PERR 0x0200 /* parity error flag */
+#define IEVME_INT 0x0100 /* interrupt flag */
+#define IEVME_P2EN 0x0020 /* enable p2 bus */
+#define IEVME_256K 0x0010 /* 256kb rams */
+#define IEVME_HADDR 0x000f /* mask for bits 17-20 of address */
+
+/*
+ * parity control
+ */
+#define IEVME_PARACK 0x0100 /* parity error ack */
+#define IEVME_PARSRC 0x0080 /* parity error source */
+#define IEVME_PAREND 0x0040 /* which end of the data got the error */
+#define IEVME_PARADR 0x000f /* mask to get bits 17-20 of parity address */
+
+
+/*
+ * PART 2: the on-board interface
+ */
+struct ieob {
+ u_char obctrl;
+};
+#define IEOB_NORSET 0x80 /* don't reset the board */
+#define IEOB_ONAIR 0x40 /* put us on the air */
+#define IEOB_ATTEN 0x20 /* attention! */
+#define IEOB_IENAB 0x10 /* interrupt enable */
+#define IEOB_XXXXX 0x08 /* free bit */
+#define IEOB_XCVRL2 0x04 /* level 2 transceiver? */
+#define IEOB_BUSERR 0x02 /* bus error */
+#define IEOB_INT 0x01 /* interrupt */
+
+#define IEOB_ADBASE 0xff000000 /* KVA base addr of 24 bit address space */
+
+/*
+ * PART 3: the 3E board
+ */
+
+/*
+ * not supported (yet?)
+ */
--- /dev/null
+/* $Id: if_le.c,v 1.1.1.1 1997/03/03 19:31:09 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ *
+ * 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 <sys/param.h>
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include "stand.h"
+#include "netif.h"
+#include "config.h"
+
+#include "if_lereg.h"
+
+int le_debug = 0;
+
+void le_end __P((struct netif *));
+void le_error __P((struct netif *, char *, volatile struct lereg1 *));
+int le_get __P((struct iodesc *, void *, size_t, time_t));
+void le_init __P((struct iodesc *, void *));
+int le_match __P((struct netif *, void *));
+int le_poll __P((struct iodesc *, void *, int));
+int le_probe __P((struct netif *, void *));
+int le_put __P((struct iodesc *, void *, size_t));
+void le_reset __P((struct netif *, u_char *));
+
+struct netif_stats le_stats;
+
+struct netif_dif le0_dif = {
+ 0, /* unit */
+ 1, /* nsel */
+ &le_stats,
+ 0,
+ 0,
+};
+
+struct netif_driver le_driver = {
+ "le", /* netif_bname */
+ le_match, /* match */
+ le_probe, /* probe */
+ le_init, /* init */
+ le_get, /* get */
+ le_put, /* put */
+ le_end, /* end */
+ &le0_dif, /* netif_ifs */
+ 1, /* netif_nifs */
+};
+
+struct le_configuration {
+ unsigned int phys_addr;
+ int used;
+} le_config[] = {
+ { LANCE_REG_ADDR, 0 }
+};
+
+int nle_config = sizeof(le_config) / (sizeof(le_config[0]));
+
+struct {
+ struct lereg1 *sc_r1; /* LANCE registers */
+ struct lereg2 *sc_r2; /* RAM */
+ int next_rmd;
+ int next_tmd;
+} le_softc;
+
+int
+le_match(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+ char *name;
+ int i, val = 0;
+ extern int cputyp;
+
+ if (cputyp != CPU_147)
+ return (0);
+ name = machdep_hint;
+ if (name && !bcmp(le_driver.netif_bname, name, 2))
+ val += 10;
+ for (i = 0; i < nle_config; i++) {
+ if (le_config[i].used)
+ continue;
+ if (le_debug)
+ printf("le%d: le_match --> %d\n", i, val + 1);
+ le_config[i].used++;
+ return val + 1;
+ }
+ if (le_debug)
+ printf("le%d: le_match --> 0\n", i);
+ return 0;
+}
+
+int
+le_probe(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+ extern int cputyp;
+
+ /* the set unit is the current unit */
+ if (le_debug)
+ printf("le%d: le_probe called\n", nif->nif_unit);
+
+ if (cputyp == CPU_147)
+ return 0;
+ return 1;
+}
+
+void
+le_error(nif, str, ler1)
+ struct netif *nif;
+ char *str;
+ volatile struct lereg1 *ler1;
+{
+ /* ler1->ler1_rap = LE_CSRO done in caller */
+ if (ler1->ler1_rdp & LE_C0_BABL)
+ panic("le%d: been babbling, found by '%s'\n", nif->nif_unit, str);
+ if (ler1->ler1_rdp & LE_C0_CERR) {
+ le_stats.collision_error++;
+ ler1->ler1_rdp = LE_C0_CERR;
+ }
+ if (ler1->ler1_rdp & LE_C0_MISS) {
+ le_stats.missed++;
+ ler1->ler1_rdp = LE_C0_MISS;
+ }
+ if (ler1->ler1_rdp & LE_C0_MERR) {
+ printf("le%d: memory error in '%s'\n", nif->nif_unit, str);
+ panic("memory error");
+ }
+}
+
+void
+le_reset(nif, myea)
+ struct netif *nif;
+ 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;
+
+ if (le_debug)
+ printf("le%d: le_reset called\n", nif->nif_unit);
+ 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("le%d: init timeout, stat = 0x%x\n",
+ nif->nif_unit, 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(desc, pkt, len)
+ struct iodesc *desc;
+ 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(desc->io_netif, "le_poll", ler1);
+ if (rmd->rmd1_bits & LE_R1_ERR) {
+ printf("le%d_poll: rmd status 0x%x\n", desc->io_netif->nif_unit,
+ rmd->rmd1_bits);
+ length = 0;
+ goto cleanup;
+ }
+ if ((rmd->rmd1_bits & (LE_R1_STP | LE_R1_ENP)) != (LE_R1_STP | LE_R1_ENP))
+ panic("le_poll: chained packet\n");
+
+ length = rmd->rmd3;
+ if (length >= LEMTU) {
+ length = 0;
+ panic("csr0 when bad things happen: %x\n", ler1->ler1_rdp);
+ goto cleanup;
+ }
+ if (!length)
+ goto cleanup;
+ length -= 4;
+ if (length > 0) {
+
+ /*
+ * if buffer is smaller than the packet truncate it.
+ * (is this wise?)
+ */
+ if (length > len)
+ length = len;
+
+ bcopy((void *)&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(desc, pkt, len)
+ struct iodesc *desc;
+ void *pkt;
+ size_t len;
+{
+ volatile struct lereg1 *ler1 = le_softc.sc_r1;
+ volatile struct lereg2 *ler2 = le_softc.sc_r2;
+ volatile 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(desc->io_netif, "le_put(way before xmit)", ler1);
+ tmd = &ler2->ler2_tmd[le_softc.next_tmd];
+ while (tmd->tmd1_bits & LE_T1_OWN) {
+ printf("le%d: output buffer busy\n", desc->io_netif->nif_unit);
+ }
+ bcopy(pkt, (void *)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(desc->io_netif, "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(desc->io_netif, "le_put(after xmit)", ler1);
+ do {
+ if (--timo == 0) {
+ printf("le%d: transmit timeout, stat = 0x%x\n",
+ desc->io_netif->nif_unit, stat);
+ if (ler1->ler1_rdp & LE_C0_ERR)
+ le_error(desc->io_netif, "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(desc->io_netif, "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_DEF)
+ le_stats.deferred++;
+ if (tmd->tmd1_bits & LE_T1_ONE)
+ le_stats.collisions++;
+ if (tmd->tmd1_bits & LE_T1_MORE)
+ le_stats.collisions += 2;
+ if (tmd->tmd1_bits & LE_T1_ERR) {
+ printf("le%d: transmit error, error = 0x%x\n", desc->io_netif->nif_unit,
+ tmd->tmd3);
+ return -1;
+ }
+ if (le_debug) {
+ printf("le%d: le_put() successful: sent %d\n",
+ desc->io_netif->nif_unit, len);
+ printf("le%d: le_put(): tmd1_bits: %x tmd3: %x\n",
+ desc->io_netif->nif_unit,
+ (unsigned int) tmd->tmd1_bits,
+ (unsigned int) tmd->tmd3);
+ }
+ return len;
+}
+
+int
+le_get(desc, pkt, len, timeout)
+ struct iodesc *desc;
+ void *pkt;
+ size_t len;
+ time_t timeout;
+{
+ time_t t;
+ int cc;
+
+ t = getsecs();
+ cc = 0;
+ while (((getsecs() - t) < timeout) && !cc) {
+ cc = le_poll(desc, pkt, len);
+ }
+ return cc;
+}
+/*
+ * init le device. return 0 on failure, 1 if ok.
+ */
+void
+le_init(desc, machdep_hint)
+ struct iodesc *desc;
+ void *machdep_hint;
+{
+ u_long eram = 4*1024*1024;
+ struct netif *nif = desc->io_netif;
+
+ if (le_debug)
+ printf("le%d: le_init called\n", desc->io_netif->nif_unit);
+ machdep_common_ether(desc->myea);
+ bzero(&le_softc, sizeof(le_softc));
+ le_softc.sc_r1 =
+ (struct lereg1 *) le_config[desc->io_netif->nif_unit].phys_addr;
+ le_softc.sc_r2 = (struct lereg2 *) (eram - (1024 * 1024));
+ le_reset(desc->io_netif, desc->myea);
+ printf("device: %s%d attached to %s\n", nif->nif_driver->netif_bname,
+ nif->nif_unit, ether_sprintf(desc->myea));
+}
+
+void
+le_end(nif)
+ struct netif *nif;
+{
+ struct lereg1 *ler1 = le_softc.sc_r1;
+
+ if (le_debug)
+ printf("le%d: le_end called\n", nif->nif_unit);
+ ler1->ler1_rap = LE_CSR0;
+ ler1->ler1_rdp = LE_C0_STOP;
+}
--- /dev/null
+/* $Id: if_lereg.h,v 1.1.1.1 1997/03/03 19:31:09 rahnds 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)
--- /dev/null
+/* $Id: version.c,v 1.1.1.1 1997/03/03 19:31:09 rahnds Exp $ */
+
+/*
+ * NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.
+ *
+ * 1.1
+ */
+
+char *version = "$Revision: 1.1.1.1 $";
--- /dev/null
+PROG= prtvid
+NOMAN=
+
+install:
+
+.include <bsd.prog.mk>
--- /dev/null
+#include <stdio.h>
+#define __DBINTERFACE_PRIVATE
+#include <db.h>
+#include "vid.h"
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ struct vid *pvid;
+ struct cfg *pcfg;
+
+ pvid = (struct vid *) malloc(sizeof (struct vid));
+
+ fread(pvid, sizeof(struct vid), 1, stdin);
+
+ if (BYTE_ORDER != BIG_ENDIAN)
+ swabvid(pvid);
+
+ printf("vid_id %s %x\n", pvid->vid_id,
+ (char *)&(pvid->vid_id[4]) - (char *)pvid);
+ printf("vid_oss %x %x\n", pvid->vid_oss,
+ (char *)&(pvid->vid_oss) - (char *)pvid);
+ printf("vid_osl %x %x\n", pvid->vid_osl,
+ (char *)&(pvid->vid_osl) - (char *)pvid);
+ printf("vid_osa_u %x %x\n", pvid->vid_osa_u,
+ (char *)&(pvid->vid_osa_u) - (char *)pvid);
+ printf("vid_osa_l %x %x\n", pvid->vid_osa_l,
+ (char *)&(pvid->vid_osa_l) - (char *)pvid);
+ printf("vid_vd %x\n",
+ (char *)&(pvid->vid_vd) - (char *)pvid);
+ printf("vid_cas %x %x\n", pvid->vid_cas,
+ (char *)&(pvid->vid_cas) - (char *)pvid);
+ printf("vid_cal %x %x\n", pvid->vid_cal,
+ (char *)&(pvid->vid_cal) - (char *)pvid);
+ printf("vid_moto %s %x\n", pvid->vid_mot,
+ (char *)&(pvid->vid_mot[0]) - (char *)pvid);
+
+ free(pvid);
+
+ pcfg = (struct cfg *) malloc(sizeof(struct cfg));
+
+ fread(pcfg, sizeof(struct cfg), 1, stdin);
+
+ if (BYTE_ORDER != BIG_ENDIAN)
+ swabcfg(pcfg);
+
+ printf("cfg_atm %x %x\n", pcfg->cfg_atm,
+ (char *)&(pcfg->cfg_atm) - (char *)(pcfg));
+ printf("cfg_prm %x %x\n", pcfg->cfg_prm,
+ (char *)&(pcfg->cfg_prm) - (char *)(pcfg));
+ printf("cfg_atw %x %x\n", pcfg->cfg_atw,
+ (char *)&(pcfg->cfg_atw) - (char *)(pcfg));
+ printf("cfg_rec %x %x\n",(long)pcfg->cfg_rec,
+ (char *)&(pcfg->cfg_rec) - (char *)(pcfg));
+ printf("cfg_spt %x %x\n", pcfg->cfg_spt,
+ (char *)&(pcfg->cfg_spt) - (char *)(pcfg));
+ printf("cfg_hds %x %x\n", pcfg->cfg_hds,
+ (char *)&(pcfg->cfg_hds) - (char *)(pcfg));
+ printf("cfg_trk %x %x\n", pcfg->cfg_trk,
+ (char *)&(pcfg->cfg_trk) - (char *)(pcfg));
+ printf("cfg_ilv %x %x\n", pcfg->cfg_ilv,
+ (char *)&(pcfg->cfg_ilv) - (char *)(pcfg));
+ printf("cfg_sof %x %x\n", pcfg->cfg_sof,
+ (char *)&(pcfg->cfg_sof) - (char *)(pcfg));
+ printf("cfg_psm %x %x\n", pcfg->cfg_psm,
+ (char *)&(pcfg->cfg_psm) - (char *)(pcfg));
+ printf("cfg_shd %x %x\n", pcfg->cfg_shd,
+ (char *)&(pcfg->cfg_shd) - (char *)(pcfg));
+ printf("cfg_pcom %x %x\n", pcfg->cfg_pcom,
+ (char *)&(pcfg->cfg_pcom) - (char *)(pcfg));
+ printf("cfg_ssr %x %x\n", pcfg->cfg_ssr,
+ (char *)&(pcfg->cfg_ssr) - (char *)(pcfg));
+ printf("cfg_rwcc %x %x\n", pcfg->cfg_rwcc,
+ (char *)&(pcfg->cfg_rwcc) - (char *)(pcfg));
+ printf("cfg_ecc %x %x\n", pcfg->cfg_ecc,
+ (char *)&(pcfg->cfg_ecc) - (char *)(pcfg));
+ printf("cfg_eatm %x %x\n", pcfg->cfg_eatm,
+ (char *)&(pcfg->cfg_eatm) - (char *)(pcfg));
+ printf("cfg_eprm %x %x\n", pcfg->cfg_eprm,
+ (char *)&(pcfg->cfg_eprm) - (char *)(pcfg));
+ printf("cfg_eatw %x %x\n", pcfg->cfg_eatw,
+ (char *)&(pcfg->cfg_eatw) - (char *)(pcfg));
+ printf("cfg_gpb1 %x %x\n", pcfg->cfg_gpb1,
+ (char *)&(pcfg->cfg_gpb1) - (char *)(pcfg));
+ printf("cfg_gpb2 %x %x\n", pcfg->cfg_gpb2,
+ (char *)&(pcfg->cfg_gpb2) - (char *)(pcfg));
+ printf("cfg_gpb3 %x %x\n", pcfg->cfg_gpb3,
+ (char *)&(pcfg->cfg_gpb3) - (char *)(pcfg));
+ printf("cfg_gpb4 %x %x\n", pcfg->cfg_gpb4,
+ (char *)&(pcfg->cfg_gpb4) - (char *)(pcfg));
+ printf("cfg_ssc %x %x\n", pcfg->cfg_ssc,
+ (char *)&(pcfg->cfg_ssc) - (char *)(pcfg));
+ printf("cfg_runit %x %x\n", pcfg->cfg_runit,
+ (char *)&(pcfg->cfg_runit) - (char *)(pcfg));
+ printf("cfg_rsvc1 %x %x\n", pcfg->cfg_rsvc1,
+ (char *)&(pcfg->cfg_rsvc1) - (char *)(pcfg));
+ printf("cfg_rsvc2 %x %x\n", pcfg->cfg_rsvc2,
+ (char *)&(pcfg->cfg_rsvc2) - (char *)(pcfg));
+}
+
+swabvid(pvid)
+ struct vid *pvid;
+{
+ M_32_SWAP(pvid->vid_oss);
+ M_16_SWAP(pvid->vid_osl);
+ M_16_SWAP(pvid->vid_osa_u);
+ M_16_SWAP(pvid->vid_osa_l);
+ M_32_SWAP(pvid->vid_cas);
+}
+
+swabcfg(pcfg)
+ struct cfg *pcfg;
+{
+ printf("swapping cfg\n");
+
+ M_16_SWAP(pcfg->cfg_atm);
+ M_16_SWAP(pcfg->cfg_prm);
+ M_16_SWAP(pcfg->cfg_atm);
+ M_16_SWAP(pcfg->cfg_rec);
+ M_16_SWAP(pcfg->cfg_trk);
+ M_16_SWAP(pcfg->cfg_psm);
+ M_16_SWAP(pcfg->cfg_shd);
+ M_16_SWAP(pcfg->cfg_pcom);
+ M_16_SWAP(pcfg->cfg_rwcc);
+ M_16_SWAP(pcfg->cfg_ecc);
+ M_16_SWAP(pcfg->cfg_eatm);
+ M_16_SWAP(pcfg->cfg_eprm);
+ M_16_SWAP(pcfg->cfg_eatw);
+ M_16_SWAP(pcfg->cfg_rsvc1);
+ M_16_SWAP(pcfg->cfg_rsvc2);
+}
--- /dev/null
+# $Id: Makefile,v 1.1.1.1 1997/03/03 19:31:10 rahnds Exp $
+
+S= ${.CURDIR}/../../../..
+INCL?= -I${.CURDIR} -I${.CURDIR}/../libsa -I${S}/lib/libsa -I${S}
+COPTS?= ${DEFS} ${INCL}
+
+.include "${S}/arch/${MACHINE}/stand/libsa/Makefile.inc"
+
+SRCS= sboot.c clock.c etherfun.c if_le.c
+
+OBJS= ${SRCS:S/.c/.o/g}
+CLEANFILES+=XBUG.o XSRT0.o oc_cksum.o sboot.tmp rboot.tmp srec sboot rboot
+MDEC_DIR?=/usr/mdec
+
+all: sboot rboot
+
+sboot.tmp: XSRT0.o oc_cksum.o ${OBJS} ${LIBSA}
+ ld -N -s -static -T 0x4000 XSRT0.o ${OBJS} oc_cksum.o -o sboot.tmp ${LIBSA}
+
+rboot.tmp: XBUG.o XSRT0.o oc_cksum.o ${OBJS} ${LIBSA}
+ ld -N -s -static -Ttext 0xffa00000 -Tdata 0x4000 XBUG.o XSRT0.o \
+ ${OBJS} oc_cksum.o -o rboot.tmp ${LIBSA}
+
+srec: srec.c
+ ${CC} ${.CURDIR}/srec.c -o srec
+
+sboot: sboot.tmp srec
+ dd ibs=32 skip=1 if=sboot.tmp | ${.OBJDIR}/srec 4 0x4000 sboot > sboot
+
+rboot: rboot.tmp srec
+ dd ibs=32 skip=1 if=rboot.tmp | ${.OBJDIR}/srec 4 0x4000 rboot > rboot
+
+install:
+ install ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
+ sboot ${DESTDIR}${MDEC_DIR}/sboot
+ install ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
+ rboot ${DESTDIR}${MDEC_DIR}/rboot
+
+.include <bsd.prog.mk>
--- /dev/null
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ */
+
+/*
+ * Theo sez: I wrote a bootrom for the MVME147 *years* ago. To write
+ * this ROM I copied a few chunks from the old bootrom, like this piece:
+ *
+ * "watch this, the moto bastard struck here, shouldn't have hired people
+ * from intel I tried to tell them...
+ * "BOOT"
+ * offset from baseaddr to entry point.
+ * offset from baseaddr to first word after checksum
+ * garbage
+ * checksum made with CS command
+ * No need to change any of this unless you try to take our names out
+ * of there. Ie. don't touch."
+ */
+
+ .text
+bootlabel: .ascii "BOOT"
+ .long bootstart-0xffa00000 | for rom install
+ .long bootlabelend - bootlabel
+ .asciz "VME147 rboot Copyright (c) 1995 Theo de Raadt"
+ .align 2
+bootstart: jmp bssclr
+ .word 0x229c | XXX bitching cksum!
+bootlabelend:
+ .word 0
+
+ | clear bss and the kernel location
+bssclr: movl #_edata,a0
+ movl #_end - _edata,d0
+1: clrb a0@+
+ subql #1,d0
+ bpl 1b
+
+ | rip the data segment from ROM into ram..
+ movl #_etext,a2 | start of data
+ movl #0x4000,a1 | shovel address
+ movl #_edata - _etext,d0
+1: movb a2@+,a1@+
+ subql #1,d0
+ bpl 1b
+
+ bra start
--- /dev/null
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ *
+ * 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 0x4000, load at 0xa000, stack at 0x9ff0.
+ .text
+ .globl start
+start: movb #0,_reboot
+ jra Ldoit
+restart: movb #1,_reboot | fall through
+
+Ldoit: movl #0x00006ff0,sp
+ jsr _main
+
+ .globl ___main
+___main: rts
--- /dev/null
+/* $Id: clock.c,v 1.1.1.1 1997/03/03 19:31:11 rahnds 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 <sys/cdefs.h>
+#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));
+}
--- /dev/null
+/* $Id: clockreg.h,v 1.1.1.1 1997/03/03 19:31:11 rahnds 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
--- /dev/null
+/*
+ *
+ * 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 <sys/cdefs.h>
+#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);
+}
+
+/* Receive 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
+ * acknowledgement
+ */
+void
+do_send_tftp(mesgtype)
+ 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 received the wrong block */
+ if (tftp->info.block < last_ack + 1) {
+ /* nack whatever we received */
+ do_send_tftp(tftp->info.block);
+ } else {
+ /* nack the last confirmed block */
+ do_send_tftp(last_ack);
+ }
+ 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);
+}
--- /dev/null
+/*
+ *
+ * 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.mvme68k\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));
--- /dev/null
+/* $Id: if_le.c,v 1.1.1.1 1997/03/03 19:31:11 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ *
+ * 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 <sys/cdefs.h>
+#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;
+}
--- /dev/null
+/* $Id: if_lereg.h,v 1.1.1.1 1997/03/03 19:31:11 rahnds 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)
+
--- /dev/null
+| $Id: oc_cksum.S,v 1.1.1.1 1997/03/03 19:31:11 rahnds 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 ones 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) does not 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 do not 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 allocator, the data we are called with is almost
+| always longword aligned, there is no benefit to this added cost
+| and we are better off letting the loop take a big performance hit
+| in the rare cases where we are 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 is clear why this happens for a count of 40: unroll-8 pays a
+| loop branch cost and unroll-16 does not. But the tests also showed
+| that 16 was better than 8 for a count of 20. It is 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 <machine/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 are 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 does not affect X)
+
+ movl d0,d1 | fold 32 bit sum to 16 bits
+ swap d1 | (NB- swap does not 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
--- /dev/null
+S00A0000000072626F6F74CF
+S32500004000424F4F540000003C00000044564D453134372072626F6F7420436F70797269671F
+S325000040206874202863292031393935205468656F2064652052616164740000004EF9FFA047
+S325000040400046229C0000207C000040207000421853806A00FFFA247CFFA01908227C00005C
+S325000040604000700012DA53806A00FFFA6000000213FC00000000463C600813FC00010000FD
+S32500004080463C2E7C00006FF04EB9FFA000B84E750A73626F6F743A204D564D4531343720F2
+S325000040A0626F6F7473747261702070726F6772616D0A003E3E3E20004E56FF802F0A61FF64
+S325000040C0FFFFFFCE1D7C0030FF80487AFFC461FF0000159E584F45EEFF80487AFFD761FFDE
+S325000040E00000158E2F0A61FF000013F82F0A610001CA504F584F60E24E714E5600004E4F86
+S3250000410000634E5E4E754D7920697020616464726573732069733A2025642E25642E2564B5
+S325000041202E25640A0053657276657220697020616464726573732069733A2025642E2564AC
+S325000041402E25642E25640A004661696C65642E0A0065786974696E6720746F20524F4D0A51
+S3250000416000446F776E6C6F6164204661696C65640A00446F776E6C6F61642077617320616E
+S325000041802073756363657373210A00636C69656E7420495020616464726573732025642EC0
+S325000041A025642E25642E25640A0073657276657220495020616464726573732025642E25A6
+S325000041C0642E25642E25640A005245564152503A204661696C65642E0A00726563656976D8
+S325000041E06564207365636F6E6461727920626F6F742070726F6772616D2E0A0062736400AB
+S3250000420076616C696420636F6D6D616E64730A0061202D2073656E64206120524152500AB4
+S325000042200062202D20626F6F74207468652073797374656D0A0071202D2065786974207499
+S325000042406F20524F4D0A0066202D206674702074686520626F6F742066696C650A0067202E
+S325000042602D20657865637574652074686520626F6F742066696C650A0068202D2068656CEB
+S32500004280700A0069202D20696E6974204C414E434520656E657420636869700A0073626FB3
+S325000042A06F743A2025733A20556E6B6E6F776E20636F6D6D616E640A00004E5600002F0BF2
+S325000042C02F0A246E000810120C000067670001F26E2E0C000062670000F86E180C000061BA
+S325000042E067364A00670001EC0C00003F67000192600001D40C000066670000AE600001C853
+S325000043000C000069670001B26D0001760C00007167000084600001B061FF0000054C4A8030
+S325000043206766428010390000465F2F00428010390000465E2F00428010390000465D2F0010
+S32500004340428010390000465C2F00487AFDBA45F9FFA0166E4E92428010390000463B2F0006
+S32500004360428010390000463A2F0042801039000046392F0042801039000046382F00487A4A
+S32500004380FDA54E926000014C487AFDBE61FF000012E06000013E487AFDB961FF000012D2BE
+S325000043A06100FD586000012C61FF000007127201B280660E487AFDAB61FF000012B4600032
+S325000043C00112487AFDAE61FF000012A66000010461FF00000F8061FF0000048E4A80660EBB
+S325000043E0487AFDE761FF00001288600000E6428010390000465F2F00428010390000465E43
+S325000044002F00428010390000465D2F00428010390000465C2F00487AFD7347F9FFA0166E19
+S325000044204E93428010390000463B2F00428010390000463A2F0042801039000046392F0067
+S3250000444042801039000046382F00487AFD5E4E93DEFC002861FF000006667201B2806608BF
+S32500004460487AFCFF4E93606A487AFD7061FF00001200584F524A4A12664645FAFD80604086
+S32500004480487AFD7E45F9FFA0166E4E92487AFD824E92487AFD8D4E92487AFD9C4E92487A4E
+S325000044A0FDA74E92487AFDB84E92487AFDCD4E92487AFDD14E92601A61FF00000E9860124D
+S325000044C02F0A613C600C2F0A487AFDD361FF000011A0246EFFF8266EFFFC4E5E4E756A7552
+S325000044E06D70696E6720746F20626F6F742070726F6772616D20617420307825782E0A001A
+S325000045004E56000048E7003C246E00083A7C70002F0D487AFFCA61FF0000115642804281B3
+S32500004520264A2F0A61FF0000108ED5C0284A4ED54CEE3C00FFF04E5E4E7500000000001FB1
+S32500004540003B005A0078009700B500D400F301110130014E4E56000048E73F30266E0008C5
+S325000045602C2E000C2A2E0010282E0014262E0018242E001C200BE880244045F20C00200ABF
+S32500004580720F2E0BC287244147F20A002006E880244045F20C00200A720FC286244145F2A6
+S325000045A00A002C0A2005E880244045F20C00200A720FC285244145F20A002A0A2004E88029
+S325000045C0244045F20C00200A720FC284244145F20A00280A2003E880244045F20C00200A09
+S325000045E0720FC283244145F20A00260A2002E880720FC282244045F20C00200A244145F25D
+S325000046000A44240A7E45BE826D027446200353807E0BBE80650A200453807E1EBE80640487
+S325000046204280607293C97046B4806F1C307C016E223C0000016DE8C007826604D3C8600290
+S32500004640D3C15280B4806EEE41FAFEF030703A00D1C443F098FFE8C0078266087E02BE839C
+S325000046606C02524943F19A0020092200E98192802401E9829481EF822005E7809085EB8074
+S32500004680D085E9802042D1C02006E980908641F00C002008D08B4CEE0CFCFFE04E5E4E756E
+S325000046A04E56000048E73E0020790000400010100000004010801C2800011A280002182851
+S325000046C000031628000514280006122800071010020000BF108042A71F41000342A71F4204
+S325000046E0000342A71F43000342A71F44000342A71F45000342A71F4600036100FE584CEE82
+S32500004700007CFFEC4E5E4E754E5600002F0A428020790000400411BC00FF08005280720524
+S32500004720B2806CEC487800062239000040045C812F0148790000465445F9FFA015D04E927A
+S32500004740207900004004317C8035000C20790000400830BC0001317C08000002117C0006F0
+S325000047600004207900004008117C00040005207900004008317C0003000648780006223900
+S325000047800000400850812F014879000046544E92487800067212D2B9000040082F01487981
+S325000047A0000046544E924280DEFC0024207900004008423008184230080E52807203B28045
+S325000047C06CEA4878004C48790000402861FF00000910246EFFFC4E5E4E754E5600002F0AF6
+S325000047E0487800064878060048790000402861FF00000A6E207900004004504F584F0C688F
+S325000048008035000C66562079000040080C680004000666484878000448790000465C721857
+S32500004820D2882F0145F9FFA015D04E9248780004487900004638720ED2B9000040082F01C0
+S325000048404E924878000648790000463022390000400850812F014E92700160024280246ECA
+S32500004860FFFC4E5E4E754E5600002F0242826100FE986100FF664A8067047001600A52828E
+S325000048807204B2826CE84280242EFFFC4E5E4E75000178787878787878782E6D766D6536BC
+S325000048A0386B006F6374657400003031323334353637383941424344454600004E56FFFCEF
+S325000048C048E73038242E0008663228790000401447EC001961FFFFFFFDCA33C0000046406A
+S325000048E00C7903E7000046406208067903E80000464033FC00450000462C60082679000076
+S325000049004018584B487800062F390000400448790000463045F9FFA015D04E924878000685
+S325000049202639000040045C832F034879000046544E92207900004004317C0800000C20794B
+S325000049400000400C7604EFD0300420790000400C7605EFD0310420790000400C42280001F4
+S3250000496020790000400C42680004317C40000006117C0003000820790000400C117C001190
+S32500004980000948780004760CD6B90000400C2F0348790000465C4E92DEFC00202EBC00008E
+S325000049A000047610D6B90000400C2F034879000046384E9220790000400C4268000A384B1F
+S325000049C098F90000400E314C000242A7487800142F0861FF00000A5C20790000400C46404E
+S325000049E03140000A20790000401030B90000464031790000462C000242680006DEFC00181E
+S32500004A004A82671020790000401830BC000431420002605448780004486EFFFC487900000D
+S32500004A20465C45F9FFA015D04E92487800192F3900004014487AFE5A4E927209DEFC001830
+S32500004A4043FAFE68207900004014700FC0AEFFFC11B108001800202EFFFCE8882D40FFFCD5
+S32500004A6053817601B68165DC207900004010384B98F900004012314C000497FC00004028A2
+S32500004A802F0B48790000402861FF000006544CEE1C0CFFE84E5E4E750A002578200D005413
+S32500004AA04654503A20446F776E6C6F6164206572726F722025643A2025730A004E560000E1
+S32500004AC048E73C304282283C0000700042B90000462842A76100FDE6584F428348780005D6
+S32500004AE04878060048790000402861FF00000772504F584F4A8066304AB900004628670862
+S32500004B002F3900004628600242A76100FDB0584F52827A05BA826CC4487AFF7E61FF00005B
+S32500004B200B5070016000010020790000401C3628000220037A09EBA02F00487AFF5E61FF0E
+S32500004B4000000B2E207900004004504F0C680800000C667820790000400C0C280011000901
+S32500004B60666A0C7900450000462C660C20790000401033D00000462C20790000401C0C5002
+S32500004B800005661E2A0858852F054280302800022F00487AFF0B61FF00000AD6700160001B
+S32500004BA0008620790000401C4280302800022239000046285281B28067186F042F00600603
+S32500004BC02F39000046286100FCF4584F52826000FF0C4282203900004628528023C0000082
+S32500004BE04628207900004010366800042F006100FCCC45EBFFF42F0A2F042A390000401C10
+S32500004C0058852F0561FF000009CAD88A504F504FB7FC0000020B6E00FEC4487AFE7C61FF1E
+S32500004C2000000A4E42804CEE0C3CFFE84E5E4E756C65303A206265656E20626162626C690B
+S32500004C406E672C20666F756E6420627920272573270A006C65303A206D656D6F727920658D
+S32500004C6072726F7220696E20272573270A004E5600002F0A2F02242E0008246E000C30121A
+S32500004C800800000E67142F02487AFFA661FF000009E061FFFFFFF466504F30120800000DEE
+S32500004CA0670434BC200030120800000C670434BC100030120800000B67122F02487AFF955D
+S32500004CC061FF000009AC61FFFFFFF432242EFFF8246EFFFC4E5E4E756C65303A20696E6955
+S32500004CE0742074696D656F75742C2073746174203D20307825780A004E56000048E73C3CF4
+S32500004D00246E0008287900004644267900004648283C000186A0426C000238BC00044878A8
+S32500004D2035BE2F0B61FF000008E64253176A0001000217520003176A00030004176A000262
+S32500004D400005176A00050006176A0004000742AB000842AB000C7418D48B2002424048402B
+S32500004D600040600037400012374200107458D48B2002424048403740001637420014397C55
+S32500004D8000010002388B397C00020002200B42404840388091C8504F4BF08A00200DEB804C
+S32500004DA09088E78090884BF30A60240D2208E7813782181817BC0080181A20024240484051
+S32500004DC01780181B37BCFA12181C4273181E52487A07BA886CC291C8327C2FD04BF08A008F
+S32500004DE0200DEB809088E78090884BF10A00200D240BD4802208E781378218584233185AE6
+S32500004E002002424048401780185B4273185C4273185E52484A886FC4397C0003000238BCB5
+S32500004E200004426C000238BC00015384660E2F03487AFEA661FF00000838600C30144283CB
+S32500004E4036000803000867E238BC010042B90000464C42B900004650426C000238BC000201
+S32500004E604CEE3C3CFFE04E5E4E756C655F706F6C6C006C65305F706F6C6C3A20726D642071
+S32500004E8073746174757320307825780A006C655F706F6C6C3A20636861696E6564207061FB
+S32500004EA0636B65740A0063737230207768656E20626164207468696E6773206861707065CF
+S32500004EC06E3A2025780A00004E56000048E72038267900004644287900004648426B00022B
+S32500004EE030130800000A670436BC040020390000464C45F40E18102A00026C0642806000DC
+S32500004F0000F630136C0C2F0B487AFF606100FD60504F102A0002080000066718102A00021D
+S32500004F2042A71F400003487AFF4A61FF0000074242826078102A0002020000030C00000380
+S32500004F406712487AFF4961FF0000072661FFFFFFF1AC584F302A0006428234000C820000B3
+S32500004F6005ED6F1A428230133F004267487AFF3861FF000006FC61FFFFFFF182602E4A823B
+S32500004F80672A59824A826F242F022F2E000820790000464C43F08A002009EB809088E780AF
+S32500004FA0908848740A6061FF0000062820790000464C43F08A002009EB809088E78090880C
+S32500004FC049F40A60200C34804240484015400003357CFA12000441F90000464C428072071A
+S32500004FE0B290670820390000464C52802080157C0080000220024CEE1C04FFF04E5E4E75B0
+S325000050006C655F70757428776179206265666F726520786D697429006C65303A206F757437
+S325000050207075742062756666657220627573790A006C655F707574286265666F72652078CE
+S325000050406D697429006C655F70757428616674657220786D697429006C65303A2074726167
+S325000050606E736D69742074696D656F75742C2073746174203D20307825780A006C655F7064
+S3250000508075742874696D656F757429006C655F7075743A20786D6974206572726F722C208E
+S325000050A06275662025640A006C655F70757428786D6974206572726F7229006C65303A20B9
+S325000050C07472616E736D6974206572726F722C206572726F72203D20307825780A004E5628
+S325000050E0000048E73838282E000C247900004644287900004648263C000186A0426A00021C
+S3250000510030126C0C2F0A487AFEF86100FB62504F20390000465047F40E58600C487AFEFACB
+S3250000512061FF0000054C584F102B00026DEE2F0420790000465043F08A002009EB809088AE
+S32500005140E7809088D080068000002FD0487408002F2E000861FF0000047A504F584F723FF7
+S32500005160B2846508377CFFC0000460083004444037400004426B000630126C0C2F0A487A0D
+S32500005180FEB16100FAEA504F177C0083000220790000465043F08A002009EB809088E7805F
+S325000051A09088D080068000002FD0D08C3680424048401740000334BC000830126C0C2F0A9B
+S325000051C0487AFE836100FAA8504F538366202F02487AFE8661FF000004983012504F6C1AAE
+S325000051E02F0A487AFE986100FA86504F600C3012428234000802000967D034BC0200301274
+S325000052006C2A3012024078000C40200067122F3900004650487AFE7661FF00000454504F86
+S325000052202F0A487AFE846100FA46504F42B900004650102B000208000006660420046014CD
+S32500005240302B00063F004267487AFE7161FF0000042070FF4CEE1C1CFFE84E5E4E754E566F
+S32500005260000048E73E20246E00082C2E000C242E001061FFFFFFF42C2A00DA8242844283AA
+S3250000528061FFFFFFF41E2400BA826F624A83665E2F062F0A6100FC322600504FB484670273
+S325000052A028024A8367DA1212B2390000465466CE122A0001B2390000465566C2122A0002AA
+S325000052C0B2390000465666B6122A0003B2390000465766AA122A0004B23900004658669E81
+S325000052E0122A0005B239000046596794609020034CEE047CFFE84E5E4E754552524F523AFB
+S325000053002065746865726E65742061646472657373206E6F74207365742120205573652077
+S325000053204C5341442E0A006C65303A2065746865726E657420616464726573733A20257854
+S325000053403A25783A25783A25783A25783A25780A00004E5600002F0A2F022439FFFE077823
+S32500005360200202802FFFFF000C802FFFFF006612487AFF8861FF000002F861FFFFFFED7EB9
+S32500005380584F45F90000465414BC000842390000465513FC003E00004656E08A43F900000B
+S325000053A046591282E08A41F9000046581082E08A13C200004657428010112F004280101010
+S325000053C02F002F024878003E42A748780008487AFF5761FF0000029A487800104879000013
+S325000053E0464461FF0000022823FCFFFE1800000046442239FFFE07740681FFF0000023C1A8
+S3250000540000004648DEFC00202E8A6100F8EC242EFFF8246EFFFC4E5E4E754E56000020797F
+S32500005420000046444268000230BC00044E5E4E75206F0004222F0008202F000C2F02080150
+S3250000544000006674080100016600008A2401EC8902820000003C4482023C000F4EFB284252
+S325000054602418D1822418D1822418D1822418D1822418D1822418D1822418D1822418D182AE
+S325000054802418D1822418D1822418D1822418D1822418D1822418D1822418D1822418D1828E
+S325000054A051C9FFBE22004841D1416402524002800000FFFF241F4E75080100016708428297
+S325000054C0343018FDD0824282143018FFE18AD0826000FF7A4282343018FED0826000FF6EE9
+S325000054E04E56000048E73038262E0008264349F9FFA018E261FF000003C2747FC4802F023E
+S325000055004E94584F7215B282670000886D20720AB282670000946D087208B2826738602ACE
+S32500005520720DB282677C7212B2826740601C7223B28267306D087217B2826756600C724087
+S32500005540B282674E727FB282670416C260A6487800084E94584F487800204E944878000813
+S325000055604E94504FB68B648C534B60884878000A4E942443584FB7CA6300FF7A121A49C1A0
+S325000055802F0161FF0000035E584FB7CA62EE6000FF644878000A61FF0000034A584F60005B
+S325000055A0FF4C4878000A4E9442134CEE1C0CFFEC4E5E4E754E560000226E000820494A11DD
+S325000055C0670652484A1066FA200890894E5E4E754E560000222E0010226E0008206E000C1E
+S325000055E0B1C9631AD3C1D1C1200153814A8067161121200153814A8066F6600A10D920018B
+S3250000560053814A8066F64E5E4E7500004E560000206E0008202E000C538072FFB280670C9E
+S32500005620421851C8FFFC4240538064F44E5E4E754E56000020790000402410AE000B52B965
+S32500005640000040244E5E4E754E56000023EE000800004024486E00102F2E000C487AFFD28E
+S32500005660612420790000402442104E5E4E754E560000486E000C2F2E00084879FFA018E2BC
+S3250000568061044E5E4E754E56000048E7303C2A6E0008286E000C266E0010594B600C4A822F
+S325000056A0670001782F024E95584F141C49C27625B68266EA95CA141C49C2224241E9FF9E26
+S325000056C07616B6886500013A303B8A064EFB0002003400A200CA013001300130013001307F
+S325000056E001300130002E0130013000EE01300130013000AE0130010401300130011A347C20
+S32500005700000160B2584B241B2453161A49C32F032F022F0D61000120504F584F4A82678AB7
+S3250000572091C8603A53817001E3A0C082672A703C4A886702702C2F004E95584F60082F0101
+S325000057404E95584F524A121249C17620B6816DEE307C00016008524A0C1200206EF8121A46
+S3250000576049C166C04A886700FF424878003E6000FF36584B767FC6932F036000FF2A584B97
+S325000057802453141A49C26700FF222F024E95584F141A49C266F46000FF12584B24136C0ABC
+S325000057A04878002D4E954482584F4878000A2F022F0D61000082504F584F6000FEEE584B57
+S325000057C02413487800082F022F0D616A504F584F6000FED8584B24134878000A2F022F0DFF
+S325000057E06154504F584F6000FEC2584B2413487800102F022F0D613E504F584F6000FEAC82
+S32500005800487800254E95584F4A8A6700FE984878006C4E95584F6000FE8C4CEE3C0CFFE839
+S325000058204E5E4E753031323334353637383961626364656600004E56FFF448E73038286ECD
+S325000058400008222E000C242E001045EEFFF441FAFFD44C42100014F008004A8166F447EE44
+S32500005860FFF4162249C32F034E94584FB7CA65F24CEE1C0CFFE04E5E4E757C2F2D5C000074
+S325000058804E5600002F0A7003C0B90000402041FAFFEA1030080049C02F0052B900004020CA
+S325000058A045F9FFA018E24E92487800084E92246EFFFC4E5E4E7500004E5600001F3C000088
+S325000058C04E4F0000101F49C04E5E4E754E56000042814E4F000167000004720142804E5E2D
+S325000058E04E754E5600002F02242E0008700AB08266064878000D61EA1F024E4F0020242E50
+S32500005900FFFC4E5E4E750000FFFE07F80000402800004036000040360000404A00004052AB
+S30D00005920000040520000405255
+S70300004000BB
--- /dev/null
+S00A0000000073626F6F74CE
+S3250000400013FC000000005ED4600813FC000100005ED42E7C00006FF04EB9000040484E7554
+S325000040200A73626F6F743A204D564D4531343720626F6F7473747261702070726F67726175
+S325000040406D0A003E3E3E20004E56FF802F0A61FFFFFFFFCE1D7C0030FF80487AFFC461FF55
+S325000040600000159E584F45EEFF80487AFFD761FF0000158E2F0A61FF000013F82F0A610055
+S3250000408001CA504F584F60E24E714E5600004E4F00634E5E4E754D7920697020616464727B
+S325000040A06573732069733A2025642E25642E25642E25640A005365727665722069702061B0
+S325000040C06464726573732069733A2025642E25642E25642E25640A004661696C65642E0ACA
+S325000040E00065786974696E6720746F20524F4D0A00446F776E6C6F6164204661696C65640A
+S325000041000A00446F776E6C6F61642077617320612073756363657373210A00636C69656E1C
+S325000041207420495020616464726573732025642E25642E25642E25640A00736572766572D7
+S3250000414020495020616464726573732025642E25642E25642E25640A005245564152503AB8
+S32500004160204661696C65642E0A007265636569766564207365636F6E6461727920626F6F0D
+S32500004180742070726F6772616D2E0A006273640076616C696420636F6D6D616E64730A0090
+S325000041A061202D2073656E64206120524152500A0062202D20626F6F7420746865207379B1
+S325000041C07374656D0A0071202D206578697420746F20524F4D0A0066202D206674702074B2
+S325000041E0686520626F6F742066696C650A0067202D20657865637574652074686520626F35
+S325000042006F742066696C650A0068202D2068656C700A0069202D20696E6974204C414E439B
+S325000042204520656E657420636869700A0073626F6F743A2025733A20556E6B6E6F776E2016
+S32500004240636F6D6D616E640A00004E5600002F0B2F0A246E000810120C000067670001F2CF
+S325000042606E2E0C000062670000F86E180C00006167364A00670001EC0C00003F670001925C
+S32500004280600001D40C000066670000AE600001C80C000069670001B26D0001760C00007143
+S325000042A067000084600001B061FF0000054C4A8067664280103900005EF72F00428010391A
+S325000042C000005EF62F004280103900005EF52F004280103900005EF42F00487AFDBA45F985
+S325000042E0000055FE4E924280103900005ED32F004280103900005ED22F00428010390000A5
+S325000043005ED12F004280103900005ED02F00487AFDA54E926000014C487AFDBE61FF000003
+S3250000432012E06000013E487AFDB961FF000012D26100FD586000012C61FF000007127201FB
+S32500004340B280660E487AFDAB61FF000012B460000112487AFDAE61FF000012A660000104C4
+S3250000436061FF00000F8061FF0000048E4A80660E487AFDE761FF00001288600000E6428070
+S32500004380103900005EF72F004280103900005EF62F004280103900005EF52F004280103924
+S325000043A000005EF42F00487AFD7347F9000055FE4E934280103900005ED32F00428010395A
+S325000043C000005ED22F004280103900005ED12F004280103900005ED02F00487AFD5E4E93A9
+S325000043E0DEFC002861FF000006667201B2806608487AFCFF4E93606A487AFD7061FF0000DF
+S325000044001200584F524A4A12664645FAFD806040487AFD7E45F9000055FE4E92487AFD82EE
+S325000044204E92487AFD8D4E92487AFD9C4E92487AFDA74E92487AFDB84E92487AFDCD4E9226
+S32500004440487AFDD14E92601A61FF00000E9860122F0A613C600C2F0A487AFDD361FF000087
+S3250000446011A0246EFFF8266EFFFC4E5E4E756A756D70696E6720746F20626F6F742070722B
+S325000044806F6772616D20617420307825782E0A004E56000048E7003C246E00083A7C70009F
+S325000044A02F0D487AFFCA61FF0000115642804281264A2F0A61FF0000108ED5C0284A4ED512
+S325000044C04CEE3C00FFF04E5E4E7500000000001F003B005A0078009700B500D400F30111B1
+S325000044E00130014E4E56000048E73F30266E00082C2E000C2A2E0010282E0014262E0018B4
+S32500004500242E001C200BE880244045F20C00200A720F2E0BC287244147F20A002006E8808A
+S32500004520244045F20C00200A720FC286244145F20A002C0A2005E880244045F20C00200AA1
+S32500004540720FC285244145F20A002A0A2004E880244045F20C00200A720FC284244145F2F3
+S325000045600A00280A2003E880244045F20C00200A720FC283244145F20A00260A2002E88077
+S32500004580720FC282244045F20C00200A244145F20A44240A7E45BE826D0274462003538045
+S325000045A07E0BBE80650A200453807E1EBE8064044280607293C97046B4806F1C307C016E06
+S325000045C0223C0000016DE8C007826604D3C86002D3C15280B4806EEE41FAFEF030703A0078
+S325000045E0D1C443F098FFE8C0078266087E02BE836C02524943F19A0020092200E981928058
+S325000046002401E9829481EF822005E7809085EB80D085E9802042D1C02006E980908641F0EB
+S325000046200C002008D08B4CEE0CFCFFE04E5E4E754E56000048E73E0020790000589810109B
+S325000046400000004010801C2800011A280002182800031628000514280006122800071010D2
+S32500004660020000BF108042A71F41000342A71F42000342A71F43000342A71F44000342A7C4
+S325000046801F45000342A71F4600036100FE584CEE007CFFEC4E5E4E754E5600002F0A4280F6
+S325000046A020790000589C11BC00FF080052807205B2806CEC4878000622390000589C5C81CE
+S325000046C02F01487900005EEC45F9000055604E9220790000589C317C8035000C2079000032
+S325000046E058A030BC0001317C08000002117C000600042079000058A0117C000400052079C1
+S32500004700000058A0317C00030006487800062239000058A050812F01487900005EEC4E92E0
+S32500004720487800067212D2B9000058A02F01487900005EEC4E924280DEFC00242079000032
+S3250000474058A0423008184230080E52807203B2806CEA4878004C4879000058C061FF00002D
+S325000047600910246EFFFC4E5E4E754E5600002F0A48780006487806004879000058C061FF7C
+S3250000478000000A6E20790000589C504F584F0C688035000C66562079000058A00C680004CE
+S325000047A00006664848780004487900005EF47218D2882F0145F9000055604E9248780004BD
+S325000047C0487900005ED0720ED2B9000058A02F014E9248780006487900005EC822390000C9
+S325000047E058A050812F014E92700160024280246EFFFC4E5E4E754E5600002F02428261004F
+S32500004800FE986100FF664A8067047001600A52827204B2826CE84280242EFFFC4E5E4E75D6
+S32500004820000178787878787878782E6D766D6536386B006F637465740000303132333435A7
+S325000048403637383941424344454600004E56FFFC48E73038242E000866322879000058AC12
+S3250000486047EC001961FFFFFFFDCA33C000005ED80C7903E700005ED86208067903E800001F
+S325000048805ED833FC004500005EC460082679000058B0584B487800062F390000589C4879B1
+S325000048A000005EC845F9000055604E924878000626390000589C5C832F03487900005EECC4
+S325000048C04E9220790000589C317C0800000C2079000058A47604EFD030042079000058A40D
+S325000048E07605EFD031042079000058A4422800012079000058A442680004317C400000060D
+S32500004900117C000300082079000058A4117C0011000948780004760CD6B9000058A42F03BA
+S32500004920487900005EF44E92DEFC00202EBC000000047610D6B9000058A42F034879000092
+S325000049405ED04E922079000058A44268000A384B98F9000058A6314C000242A748780014AC
+S325000049602F0861FF00000A5C2079000058A446403140000A2079000058A830B900005ED8E6
+S32500004980317900005EC4000242680006DEFC00184A8267102079000058B030BC000431425A
+S325000049A00002605448780004486EFFFC487900005EF445F9000055604E92487800192F399F
+S325000049C0000058AC487AFE5A4E927209DEFC001843FAFE682079000058AC700FC0AEFFFC3E
+S325000049E011B108001800202EFFFCE8882D40FFFC53817601B68165DC2079000058A8384BCF
+S32500004A0098F9000058AA314C000497FC000058C02F0B4879000058C061FF000006544CEECA
+S32500004A201C0CFFE84E5E4E750A002578200D00544654503A20446F776E6C6F616420657257
+S32500004A40726F722025643A2025730A004E56000048E73C304282283C0000700042B9000086
+S32500004A605EC042A76100FDE6584F428348780005487806004879000058C061FF000007723C
+S32500004A80504F584F4A8066304AB900005EC067082F3900005EC0600242A76100FDB0584F54
+S32500004AA052827A05BA826CC4487AFF7E61FF00000B507001600001002079000058B4362862
+S32500004AC0000220037A09EBA02F00487AFF5E61FF00000B2E20790000589C504F0C6808000E
+S32500004AE0000C66782079000058A40C2800110009666A0C79004500005EC4660C207900001C
+S32500004B0058A833D000005EC42079000058B40C500005661E2A0858852F0542803028000281
+S32500004B202F00487AFF0B61FF00000AD67001600000862079000058B44280302800022239C1
+S32500004B4000005EC05281B28067186F042F0060062F3900005EC06100FCF4584F52826000F3
+S32500004B60FF0C4282203900005EC0528023C000005EC02079000058A8366800042F0061004B
+S32500004B80FCCC45EBFFF42F0A2F042A39000058B458852F0561FF000009CAD88A504F504F65
+S32500004BA0B7FC0000020B6E00FEC4487AFE7C61FF00000A4E42804CEE0C3CFFE84E5E4E7571
+S32500004BC06C65303A206265656E20626162626C696E672C20666F756E642062792027257347
+S32500004BE0270A006C65303A206D656D6F7279206572726F7220696E20272573270A004E5695
+S32500004C0000002F0A2F02242E0008246E000C30120800000E67142F02487AFFA661FF000061
+S32500004C2009E061FFFFFFF466504F30120800000D670434BC200030120800000C670434BCAB
+S32500004C40100030120800000B67122F02487AFF9561FF000009AC61FFFFFFF432242EFFF807
+S32500004C60246EFFFC4E5E4E756C65303A20696E69742074696D656F75742C207374617420D4
+S32500004C803D20307825780A004E56000048E73C3C246E0008287900005EDC267900005EE0C5
+S32500004CA0283C000186A0426C000238BC0004487835BE2F0B61FF000008E64253176A000169
+S32500004CC0000217520003176A00030004176A00020005176A00050006176A0004000742AB4B
+S32500004CE0000842AB000C7418D48B2002424048400040600037400012374200107458D48BB9
+S32500004D002002424048403740001637420014397C00010002388B397C00020002200B424066
+S32500004D204840388091C8504F4BF08A00200DEB809088E78090884BF30A60240D2208E781D6
+S32500004D403782181817BC0080181A2002424048401780181B37BCFA12181C4273181E524831
+S32500004D607A07BA886CC291C8327C2FD04BF08A00200DEB809088E78090884BF10A00200DCF
+S32500004D80240BD4802208E781378218584233185A2002424048401780185B4273185C4273D4
+S32500004DA0185E52484A886FC4397C0003000238BC0004426C000238BC00015384660E2F0304
+S32500004DC0487AFEA661FF00000838600C3014428336000803000867E238BC010042B90000D0
+S32500004DE05EE442B900005EE8426C000238BC00024CEE3C3CFFE04E5E4E756C655F706F6C09
+S32500004E006C006C65305F706F6C6C3A20726D642073746174757320307825780A006C655F09
+S32500004E20706F6C6C3A20636861696E6564207061636B65740A0063737230207768656E2083
+S32500004E40626164207468696E67732068617070656E3A2025780A00004E56000048E72038B0
+S32500004E60267900005EDC287900005EE0426B000230130800000A670436BC040020390000B6
+S32500004E805EE445F40E18102A00026C064280600000F630136C0C2F0B487AFF606100FD60D1
+S32500004EA0504F102A0002080000066718102A000242A71F400003487AFF4A61FF0000074249
+S32500004EC042826078102A0002020000030C0000036712487AFF4961FF0000072661FFFFFF72
+S32500004EE0F1AC584F302A0006428234000C82000005ED6F1A428230133F004267487AFF381F
+S32500004F0061FF000006FC61FFFFFFF182602E4A82672A59824A826F242F022F2E0008207904
+S32500004F2000005EE443F08A002009EB809088E780908848740A6061FF0000062820790000F4
+S32500004F405EE443F08A002009EB809088E780908849F40A60200C3480424048401540000338
+S32500004F60357CFA12000441F900005EE442807207B2906708203900005EE452802080157C64
+S32500004F800080000220024CEE1C04FFF04E5E4E756C655F70757428776179206265666F727F
+S32500004FA06520786D697429006C65303A206F75747075742062756666657220627573790AE8
+S32500004FC0006C655F707574286265666F726520786D697429006C655F70757428616674654B
+S32500004FE07220786D697429006C65303A207472616E736D69742074696D656F75742C20737B
+S32500005000746174203D20307825780A006C655F7075742874696D656F757429006C655F70F4
+S3250000502075743A20786D6974206572726F722C206275662025640A006C655F7075742878B6
+S325000050406D6974206572726F7229006C65303A207472616E736D6974206572726F722C202A
+S325000050606572726F72203D20307825780A004E56000048E73838282E000C247900005EDCB8
+S32500005080287900005EE0263C000186A0426A000230126C0C2F0A487AFEF86100FB62504FEC
+S325000050A0203900005EE847F40E58600C487AFEFA61FF0000054C584F102B00026DEE2F0461
+S325000050C0207900005EE843F08A002009EB809088E7809088D080068000002FD0487408006A
+S325000050E02F2E000861FF0000047A504F584F723FB2846508377CFFC0000460083004444037
+S3250000510037400004426B000630126C0C2F0A487AFEB16100FAEA504F177C00830002207962
+S3250000512000005EE843F08A002009EB809088E7809088D080068000002FD0D08C36804240D2
+S3250000514048401740000334BC000830126C0C2F0A487AFE836100FAA8504F538366202F020A
+S32500005160487AFE8661FF000004983012504F6C1A2F0A487AFE986100FA86504F600C3012C1
+S32500005180428234000802000967D034BC020030126C2A3012024078000C40200067122F39B4
+S325000051A000005EE8487AFE7661FF00000454504F2F0A487AFE846100FA46504F42B900005E
+S325000051C05EE8102B000208000006660420046014302B00063F004267487AFE7161FF00005C
+S325000051E0042070FF4CEE1C1CFFE84E5E4E754E56000048E73E20246E00082C2E000C242ECB
+S32500005200001061FFFFFFF42C2A00DA824284428361FFFFFFF41E2400BA826F624A83665EB7
+S325000052202F062F0A6100FC322600504FB484670228024A8367DA1212B23900005EEC66CE40
+S32500005240122A0001B23900005EED66C2122A0002B23900005EEE66B6122A0003B2390000F2
+S325000052605EEF66AA122A0004B23900005EF0669E122A0005B23900005EF1679460902003C5
+S325000052804CEE047CFFE84E5E4E754552524F523A2065746865726E65742061646472657322
+S325000052A073206E6F7420736574212020557365204C5341442E0A006C65303A20657468658D
+S325000052C0726E657420616464726573733A2025783A25783A25783A25783A25783A25780AD5
+S325000052E000004E5600002F0A2F022439FFFE0778200202802FFFFF000C802FFFFF006612BF
+S32500005300487AFF8861FF000002F861FFFFFFED7E584F45F900005EEC14BC00084239000099
+S325000053205EED13FC003E00005EEEE08A43F900005EF11282E08A41F900005EF01082E08A0C
+S3250000534013C200005EEF428010112F00428010102F002F024878003E42A748780008487A60
+S32500005360FF5761FF0000029A48780010487900005EDC61FF0000022823FCFFFE180000004C
+S325000053805EDC2239FFFE07740681FFF0000023C100005EE0DEFC00202E8A6100F8EC242E19
+S325000053A0FFF8246EFFFC4E5E4E754E560000207900005EDC4268000230BC00044E5E4E7572
+S325000053C0206F0004222F0008202F000C2F02080100006674080100016600008A2401EC89D8
+S325000053E002820000003C4482023C000F4EFB28422418D1822418D1822418D1822418D182E5
+S325000054002418D1822418D1822418D1822418D1822418D1822418D1822418D1822418D1820E
+S325000054202418D1822418D1822418D1822418D18251C9FFBE22004841D1416402524002801C
+S325000054400000FFFF241F4E750801000167084282343018FDD0824282143018FFE18AD0825E
+S325000054606000FF7A4282343018FED0826000FF6E4E56000048E73038262E0008264349F9AE
+S325000054800000587261FF000003C2747FC4802F024E94584F7215B282670000886D20720A73
+S325000054A0B282670000946D087208B2826738602A720DB282677C7212B2826740601C722365
+S325000054C0B28267306D087217B2826756600C7240B282674E727FB282670416C260A64878D7
+S325000054E000084E94584F487800204E94487800084E94504FB68B648C534B60884878000A89
+S325000055004E942443584FB7CA6300FF7A121A49C12F0161FF0000035E584FB7CA62EE600039
+S32500005520FF644878000A61FF0000034A584F6000FF4C4878000A4E9442134CEE1C0CFFECEB
+S325000055404E5E4E754E560000226E000820494A11670652484A1066FA200890894E5E4E7565
+S325000055604E560000222E0010226E0008206E000CB1C9631AD3C1D1C1200153814A80671696
+S325000055801121200153814A8066F6600A10D9200153814A8066F64E5E4E7500004E56000037
+S325000055A0206E0008202E000C538072FFB280670C421851C8FFFC4240538064F44E5E4E7582
+S325000055C04E5600002079000058BC10AE000B52B9000058BC4E5E4E754E56000023EE000860
+S325000055E0000058BC486E00102F2E000C487AFFD261242079000058BC42104E5E4E754E5638
+S325000056000000486E000C2F2E000848790000587261044E5E4E754E56000048E7303C2A6E27
+S325000056200008286E000C266E0010594B600C4A82670001782F024E95584F141C49C27625C9
+S32500005640B68266EA95CA141C49C2224241E9FF9E7616B6886500013A303B8A064EFB000247
+S32500005660003400A200CA0130013001300130013001300130002E0130013000EE013001304D
+S32500005680013000AE0130010401300130011A347C000160B2584B241B2453161A49C32F03E8
+S325000056A02F022F0D61000120504F584F4A82678A91C8603A53817001E3A0C082672A703CB8
+S325000056C04A886702702C2F004E95584F60082F014E95584F524A121249C17620B6816DEE20
+S325000056E0307C00016008524A0C1200206EF8121A49C166C04A886700FF424878003E60001B
+S32500005700FF36584B767FC6932F036000FF2A584B2453141A49C26700FF222F024E95584F0C
+S32500005720141A49C266F46000FF12584B24136C0A4878002D4E954482584F4878000A2F02D7
+S325000057402F0D61000082504F584F6000FEEE584B2413487800082F022F0D616A504F584F72
+S325000057606000FED8584B24134878000A2F022F0D6154504F584F6000FEC2584B2413487827
+S3250000578000102F022F0D613E504F584F6000FEAC487800254E95584F4A8A6700FE98487897
+S325000057A0006C4E95584F6000FE8C4CEE3C0CFFE84E5E4E753031323334353637383961625B
+S325000057C06364656600004E56FFF448E73038286E0008222E000C242E001045EEFFF441FA46
+S325000057E0FFD44C42100014F008004A8166F447EEFFF4162249C32F034E94584FB7CA65F202
+S325000058004CEE1C0CFFE04E5E4E757C2F2D5C00004E5600002F0A7003C0B9000058B841FA8A
+S32500005820FFEA1030080049C02F0052B9000058B845F9000058724E92487800084E92246EBC
+S32500005840FFFC4E5E4E7500004E5600001F3C00004E4F0000101F49C04E5E4E754E560000F1
+S3250000586042814E4F000167000004720142804E5E4E754E5600002F02242E0008700AB082D7
+S3250000588066064878000D61EA1F024E4F0020242EFFFC4E5E4E750000FFFE07F8000058C0D0
+S31D000058A0000058CE000058CE000058E2000058EA000058EA000058EA9E
+S70300004000BB
--- /dev/null
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+#include "sboot.h"
+
+void
+main()
+{
+ char buf[128];
+
+ buf[0] = '0';
+ printf("\nsboot: MVME147 bootstrap program\n");
+ while (1) {
+ printf(">>> ");
+ gets(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':
+ break;
+ 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");
+ }
+ break;
+ case 'q':
+ printf("exiting to ROM\n");
+ callrom();
+ break;
+ case 'f':
+ if (do_get_file() == 1) {
+ printf("Download Failed\n");
+ } else {
+ printf("Download was a success!\n");
+ }
+ break;
+ case 'b':
+ le_init();
+ if (rev_arp()) {
+ printf("client IP address %d.%d.%d.%d\n", myip[0],
+ myip[1], myip[2], myip[3]);
+ printf("server IP address %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("received secondary boot program.\n");
+ }
+ if (*++buf == '\0')
+ buf = "bsd";
+ go(buf);
+ break;
+ case 'h':
+ case '?':
+ printf("valid commands\n");
+ printf("a - send a RARP\n");
+ printf("b - boot the system\n");
+ printf("q - 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");
+ break;
+ case 'i':
+ le_init();
+ break;
+ case 'g':
+ go(buf);
+ break;
+ default:
+ printf("sboot: %s: Unknown command\n", buf);
+ }
+}
+
+go(buf)
+ char *buf;
+{
+ void (*entry)() = (void (*))LOAD_ADDR;
+
+ printf("jumping to boot program at 0x%x.\n", entry);
+
+ asm("clrl d0; clrl d1"); /* XXX network device */
+ asm("movl %0, a3" : : "a" (buf) : "a3");
+ asm("movl %0, a4" : : "a" (buf + strlen(buf)) : "a4");
+ asm("jmp %0@" : : "a" (entry));
+}
--- /dev/null
+/*
+ * 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 __P((const void *, void *, size_t)); /* libc_sa */
+void *memset __P((void *, int, size_t)); /* libc_sa */
+int printf __P((const char *, ...)); /* libc_sa */
+
+/* console */
+void puts __P((char *));
+void putchar __P((char));
+char cngetc __P((void));
+void ngets __P((char *, int));
+
+/* sboot */
+void callrom __P((void));
+void do_cmd __P((char *));
+
+/* le */
+#define LANCE_ADDR 0xfffe0778
+#define ERAM_ADDR 0xfffe0774
+#define LANCE_REG_ADDR 0xfffe1800
+void le_end __P((void));
+void le_init __P((void));
+int le_get __P((u_char *, size_t, u_long));
+int le_put __P((u_char *, size_t));
+
+/* etherfun */
+#define READ 0
+#define ACKN 1
+void do_rev_arp __P((void));
+int get_rev_arp __P((void));
+int rev_arp __P((void));
+void do_send_tftp __P((int));
+int do_get_file __P((void));
+void tftp_file __P((char *, u_long));
+
+/* clock */
+u_long time __P((void));
+
+/* checksum */
+u_long oc_cksum __P((void *, u_long, u_long));
+
+#define CONS_ZS_ADDR (0xfffe3002)
+#define CLOCK_ADDR (0xfffe07f8)
+#define LOAD_ADDR 0x7000
+
+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;
--- /dev/null
+/*
+ * Public domain, believed to be by Mike Price.
+ *
+ * convert binary file to Srecord format
+ * XXX srec generates improper checksums for 4-byte dumps
+ */
+#include <stdio.h>
+#include <ctype.h>
+
+int get32();
+void put32();
+void sput();
+void put();
+int checksum();
+
+int mask;
+int size;
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char buf[32];
+ int cc;
+ int base;
+ int addr;
+ char *name;
+
+ if (argc != 4) {
+ fprintf(stderr, "usage: %s {size} {hex_addr} {name}\n", argv[0]);
+ fprintf(stderr, "Size = 2, 3, or 4 byte address\n");
+ exit(1);
+ }
+ sscanf(argv[1], "%x", &size);
+ mask = (1 << (size * 8)) - 1;
+ if (!mask)
+ mask = (-1);
+ sscanf(argv[2], "%x", &base);
+ name = argv[3];
+
+ if (size == 2)
+ printf("S0%02X%04X", 2 + strlen(name) + 1, 0);
+ if (size == 3)
+ printf("S0%02X%06X", 3 + strlen(name) + 1, 0);
+ if (size == 4)
+ printf("S0%02X%08X", 4 + strlen(name) + 1, 0);
+ sput(name);
+ printf("%02X\n", checksum(0, name, strlen(name), size));
+
+ addr = base;
+ for (;;) {
+ cc = get32(buf);
+ if (cc > 0) {
+ put32(cc, addr, buf, size, mask);
+ addr += cc;
+ } else
+ break;
+ }
+
+ buf[0] = base >> 8;
+ buf[1] = base;
+ printf("S%d%02X", 11 - size, 2 + 1);
+ switch (size) {
+ case 2:
+ printf("%04X", base & mask);
+ break;
+ case 3:
+ printf("%06X", base & mask);
+ break;
+ case 4:
+ printf("%08X", base & mask);
+ break;
+ }
+
+ /*
+ * kludge -> don't know why you have to add the +1 = works
+ * for size =3 at least
+ */
+ printf("%02X\n", checksum(base, (char *) 0, 0, size) + 1);
+ exit (0);
+}
+
+int
+get32(buf)
+ char buf[];
+{
+ char *cp = buf;
+ int i;
+ int c;
+
+ for (i = 0; i < 32; ++i) {
+ if ((c = getchar()) != EOF)
+ *cp++ = c;
+ else
+ break;
+ }
+ return (cp - buf);
+}
+
+void
+put32(len, addr, buf, size, mask)
+ int len;
+ int addr;
+ char buf[];
+ int size, mask;
+{
+ char *cp = buf;
+ int i;
+
+ if (size == 2)
+ printf("S1%02X%04X", 2 + len + 1, addr & mask);
+ if (size == 3)
+ printf("S2%02X%06X", 3 + len + 1, addr & mask);
+ if (size == 4)
+ printf("S3%02X%08X", 4 + len + 1, addr & mask);
+ for (i = 0; i < len; ++i)
+ put(*cp++);
+ printf("%02X\n", checksum(addr, buf, len, size));
+}
+
+void
+sput(s)
+ char *s;
+{
+ while (*s != '\0')
+ put(*s++);
+}
+
+void
+put(c)
+ int c;
+{
+ printf("%02X", c & 0xff);
+}
+
+int
+checksum(addr, buf, len, size)
+ int addr;
+ char buf[];
+ int len;
+ int size;
+{
+ char *cp = buf;
+ int sum = 0xff - 1 - size - (len & 0xff);
+ int i;
+
+ if (size == 4)
+ sum -= (addr >> 24) & 0xff;
+ if (size >= 3)
+ sum -= (addr >> 16) & 0xff;
+ sum -= (addr >> 8) & 0xff;
+ sum -= addr & 0xff;
+ for (i = 0; i < len; ++i) {
+ sum -= *cp++ & 0xff;
+ }
+ return (sum & 0xff);
+}
--- /dev/null
+PROG= wrtvid
+NOMAN=
+
+install:
+
+.include <bsd.prog.mk>
--- /dev/null
+WRTVID_BASE_DIR=${S}/arch/${MACHINE}/stand/wrtvid
+
+WRTVID_DIR!= cd ${WRTVID_BASE_DIR}; \
+ printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx
+
+WRTVID=${WRTVID_DIR}/wrtvid
+
+$(WRTVID): .NOTMAIN __always_make_WRTVID
+ @echo making sure the wrtvid is up to date...
+ @(cd ${WRTVID_BASE_DIR}; ${MAKE})
+
+__always_make_WRTVID: .NOTMAIN
--- /dev/null
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#define __DBINTERFACE_PRIVATE
+#include <db.h>
+#include <machine/disklabel.h>
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct cpu_disklabel *pcpul;
+ struct stat stat;
+ int exe_file;
+ int tape_vid;
+ int tape_exe;
+ unsigned int exe_addr;
+ unsigned short exe_addr_u;
+ unsigned short exe_addr_l;
+ char *filename;
+ char fileext[256];
+ char filebase[256];
+
+ if (argc == 0)
+ filename = "a.out";
+ else
+ filename = argv[1];
+
+ exe_file = open(filename, O_RDONLY,0444);
+ if (exe_file == -1) {
+ perror(filename);
+ exit(2);
+ }
+ sprintf(fileext, "%c%cboot", filename[4], filename[5]);
+ tape_vid = open(fileext, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ sprintf(fileext, "boot%c%c", filename[4], filename[5]);
+ tape_exe = open(fileext, O_WRONLY|O_CREAT|O_TRUNC,0644);
+
+ pcpul = (struct cpu_disklabel *)malloc(sizeof(struct cpu_disklabel));
+ bzero(pcpul, sizeof(struct cpu_disklabel));
+
+ strcpy(pcpul->vid_id, "NBSD");
+
+ fstat(exe_file, &stat);
+ /* size in 256 byte blocks round up after a.out header removed */
+
+ if (filename[5] == 't' ) {
+ pcpul->vid_oss = 1;
+ }else {
+ pcpul->vid_oss = 2;
+ }
+ pcpul->vid_osl = (((stat.st_size -0x20) +511) / 512) *2;
+
+ lseek(exe_file, 0x14, SEEK_SET);
+ read(exe_file, &exe_addr, 4);
+
+ /* check this, it may not work in both endian. */
+ {
+ union {
+ struct s {
+ unsigned short s1;
+ unsigned short s2;
+ } s;
+ unsigned long l;
+ } a;
+ a.l = exe_addr;
+ pcpul->vid_osa_u = a.s.s1;
+ pcpul->vid_osa_l = a.s.s2;
+
+ }
+ pcpul->vid_cas = 1;
+ pcpul->vid_cal = 1;
+ /* do not want to write past end of structure, not null terminated */
+ strncpy(pcpul->vid_mot, "MOTOROLA", 8);
+
+ if (BYTE_ORDER != BIG_ENDIAN)
+ swabvid(pcpul);
+
+ pcpul->cfg_rec = 0x100;
+ pcpul->cfg_psm = 0x200;
+
+ if (BYTE_ORDER != BIG_ENDIAN)
+ swabcfg(pcpul);
+
+ write(tape_vid, pcpul, sizeof(struct cpu_disklabel));
+
+ free(pcpul);
+
+ copy_exe(exe_file, tape_exe);
+ close(exe_file);
+ close(tape_vid);
+ close(tape_exe);
+ return (0);
+}
+
+#define BUF_SIZ 512
+copy_exe(exe_file, tape_exe)
+ int exe_file, tape_exe;
+{
+ char *buf;
+ int cnt = 0;
+
+ buf = (char *)malloc(BUF_SIZ);
+
+ lseek (exe_file, 0x20, SEEK_SET);
+ while (BUF_SIZ == (cnt = read(exe_file, buf, BUF_SIZ))) {
+ write(tape_exe, buf, cnt);
+ }
+ bzero(&buf[cnt], BUF_SIZ-cnt);
+ write(tape_exe, buf, BUF_SIZ);
+}
+
+swabvid(pcpul)
+ struct cpu_disklabel *pcpul;
+{
+ M_32_SWAP(pcpul->vid_oss);
+ M_16_SWAP(pcpul->vid_osl);
+ /*
+ M_16_SWAP(pcpul->vid_osa_u);
+ M_16_SWAP(pcpul->vid_osa_l);
+ */
+ M_32_SWAP(pcpul->vid_cas);
+}
+
+swabcfg(pcpul)
+ struct cpu_disklabel *pcpul;
+{
+ M_16_SWAP(pcpul->cfg_atm);
+ M_16_SWAP(pcpul->cfg_prm);
+ M_16_SWAP(pcpul->cfg_atm);
+ M_16_SWAP(pcpul->cfg_rec);
+ M_16_SWAP(pcpul->cfg_trk);
+ M_16_SWAP(pcpul->cfg_psm);
+ M_16_SWAP(pcpul->cfg_shd);
+ M_16_SWAP(pcpul->cfg_pcom);
+ M_16_SWAP(pcpul->cfg_rwcc);
+ M_16_SWAP(pcpul->cfg_ecc);
+ M_16_SWAP(pcpul->cfg_eatm);
+ M_16_SWAP(pcpul->cfg_eprm);
+ M_16_SWAP(pcpul->cfg_eatw);
+ M_16_SWAP(pcpul->cfg_rsvc1);
+ M_16_SWAP(pcpul->cfg_rsvc2);
+}
--- /dev/null
+PROG= prtvid
+NOMAN=
+
+install:
+
+.include <bsd.prog.mk>
--- /dev/null
+/*
+ * Copyright (c) 1993 Paul Kranenburg
+ * 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 Paul Kranenburg.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include <stdio.h>
+
+void cputobsdlabel __P((struct disklabel *lp, struct cpu_disklabel *clp));
+
+main(int argc, char *argv[])
+{
+ struct cpu_disklabel cpu_label;
+ struct disklabel sdlabel;
+ int i;
+
+ fread((void *)&cpu_label, sizeof(struct cpu_disklabel), 1, stdin);
+ cputobsdlabel(&sdlabel, (struct cpu_disklabel *)&cpu_label);
+
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ printf("part %x off %x size %x\n",
+ i, sdlabel.d_partitions[i].p_offset,
+ sdlabel.d_partitions[i].p_size);
+ }
+}
+
+void
+cputobsdlabel(struct disklabel *lp, struct cpu_disklabel *clp)
+{
+ int i;
+
+ lp->d_magic = clp->magic1;
+ lp->d_type = clp->type;
+ lp->d_subtype = clp->subtype;
+ bcopy(clp->vid_vd, lp->d_typename, 16);
+ bcopy(clp->packname, lp->d_packname, 16);
+ lp->d_secsize = clp->cfg_psm;
+ lp->d_nsectors = clp->cfg_spt;
+ lp->d_ncylinders = clp->cfg_trk; /* trk is really num of cyl! */
+ lp->d_ntracks = clp->cfg_hds;
+
+ lp->d_secpercyl = clp->secpercyl;
+ lp->d_secperunit = clp->secperunit;
+ lp->d_secpercyl = clp->secpercyl;
+ lp->d_secperunit = clp->secperunit;
+ lp->d_sparespertrack = clp->sparespertrack;
+ lp->d_sparespercyl = clp->sparespercyl;
+ lp->d_acylinders = clp->acylinders;
+ lp->d_rpm = clp->rpm;
+ lp->d_interleave = clp->cfg_ilv;
+ lp->d_trackskew = clp->cfg_sof;
+ lp->d_cylskew = clp->cylskew;
+ lp->d_headswitch = clp->headswitch;
+
+ /* this silly table is for winchester drives */
+ switch (clp->cfg_ssr) {
+ case 0:
+ lp->d_trkseek = 0;
+ break;
+ case 1:
+ lp->d_trkseek = 6;
+ break;
+ case 2:
+ lp->d_trkseek = 10;
+ break;
+ case 3:
+ lp->d_trkseek = 15;
+ break;
+ case 4:
+ lp->d_trkseek = 20;
+ break;
+ default:
+ lp->d_trkseek = 0;
+ break;
+ }
+ lp->d_flags = clp->flags;
+ for (i = 0; i < NDDATA; i++)
+ lp->d_drivedata[i] = clp->drivedata[i];
+ for (i = 0; i < NSPARE; i++)
+ lp->d_spare[i] = clp->spare[i];
+ lp->d_magic2 = clp->magic2;
+ lp->d_checksum = clp->checksum;
+ lp->d_npartitions = clp->partitions;
+ lp->d_bbsize = clp->bbsize;
+ lp->d_sbsize = clp->sbsize;
+ bcopy(clp->vid_4, &(lp->d_partitions[0]), sizeof (struct partition) * 4);
+ bcopy(clp->cfg_4, &(lp->d_partitions[4]), sizeof (struct partition) * 12);
+}
--- /dev/null
+#include <stdio.h>
+#define __DBINTERFACE_PRIVATE
+#include <db.h>
+#include "vid.h"
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ struct vid *pvid;
+ struct cfg *pcfg;
+
+ pvid = (struct vid *) malloc(sizeof (struct vid));
+
+ fread(pvid, sizeof(struct vid), 1, stdin);
+
+ if (BYTE_ORDER != BIG_ENDIAN)
+ swabvid(pvid);
+
+ printf("vid_id %s %x\n", pvid->vid_id,
+ (char *)&(pvid->vid_id[4]) - (char *)pvid);
+ printf("vid_oss %x %x\n", pvid->vid_oss,
+ (char *)&(pvid->vid_oss) - (char *)pvid);
+ printf("vid_osl %x %x\n", pvid->vid_osl,
+ (char *)&(pvid->vid_osl) - (char *)pvid);
+ printf("vid_osa_u %x %x\n", pvid->vid_osa_u,
+ (char *)&(pvid->vid_osa_u) - (char *)pvid);
+ printf("vid_osa_l %x %x\n", pvid->vid_osa_l,
+ (char *)&(pvid->vid_osa_l) - (char *)pvid);
+ printf("vid_vd %x\n",
+ (char *)&(pvid->vid_vd) - (char *)pvid);
+ printf("vid_cas %x %x\n", pvid->vid_cas,
+ (char *)&(pvid->vid_cas) - (char *)pvid);
+ printf("vid_cal %x %x\n", pvid->vid_cal,
+ (char *)&(pvid->vid_cal) - (char *)pvid);
+ printf("vid_moto %s %x\n", pvid->vid_mot,
+ (char *)&(pvid->vid_mot[0]) - (char *)pvid);
+
+ free(pvid);
+
+ pcfg = (struct cfg *) malloc(sizeof(struct cfg));
+
+ fread(pcfg, sizeof(struct cfg), 1, stdin);
+
+ if (BYTE_ORDER != BIG_ENDIAN)
+ swabcfg(pcfg);
+
+ printf("cfg_atm %x %x\n", pcfg->cfg_atm,
+ (char *)&(pcfg->cfg_atm) - (char *)(pcfg));
+ printf("cfg_prm %x %x\n", pcfg->cfg_prm,
+ (char *)&(pcfg->cfg_prm) - (char *)(pcfg));
+ printf("cfg_atw %x %x\n", pcfg->cfg_atw,
+ (char *)&(pcfg->cfg_atw) - (char *)(pcfg));
+ printf("cfg_rec %x %x\n",(long)pcfg->cfg_rec,
+ (char *)&(pcfg->cfg_rec) - (char *)(pcfg));
+ printf("cfg_spt %x %x\n", pcfg->cfg_spt,
+ (char *)&(pcfg->cfg_spt) - (char *)(pcfg));
+ printf("cfg_hds %x %x\n", pcfg->cfg_hds,
+ (char *)&(pcfg->cfg_hds) - (char *)(pcfg));
+ printf("cfg_trk %x %x\n", pcfg->cfg_trk,
+ (char *)&(pcfg->cfg_trk) - (char *)(pcfg));
+ printf("cfg_ilv %x %x\n", pcfg->cfg_ilv,
+ (char *)&(pcfg->cfg_ilv) - (char *)(pcfg));
+ printf("cfg_sof %x %x\n", pcfg->cfg_sof,
+ (char *)&(pcfg->cfg_sof) - (char *)(pcfg));
+ printf("cfg_psm %x %x\n", pcfg->cfg_psm,
+ (char *)&(pcfg->cfg_psm) - (char *)(pcfg));
+ printf("cfg_shd %x %x\n", pcfg->cfg_shd,
+ (char *)&(pcfg->cfg_shd) - (char *)(pcfg));
+ printf("cfg_pcom %x %x\n", pcfg->cfg_pcom,
+ (char *)&(pcfg->cfg_pcom) - (char *)(pcfg));
+ printf("cfg_ssr %x %x\n", pcfg->cfg_ssr,
+ (char *)&(pcfg->cfg_ssr) - (char *)(pcfg));
+ printf("cfg_rwcc %x %x\n", pcfg->cfg_rwcc,
+ (char *)&(pcfg->cfg_rwcc) - (char *)(pcfg));
+ printf("cfg_ecc %x %x\n", pcfg->cfg_ecc,
+ (char *)&(pcfg->cfg_ecc) - (char *)(pcfg));
+ printf("cfg_eatm %x %x\n", pcfg->cfg_eatm,
+ (char *)&(pcfg->cfg_eatm) - (char *)(pcfg));
+ printf("cfg_eprm %x %x\n", pcfg->cfg_eprm,
+ (char *)&(pcfg->cfg_eprm) - (char *)(pcfg));
+ printf("cfg_eatw %x %x\n", pcfg->cfg_eatw,
+ (char *)&(pcfg->cfg_eatw) - (char *)(pcfg));
+ printf("cfg_gpb1 %x %x\n", pcfg->cfg_gpb1,
+ (char *)&(pcfg->cfg_gpb1) - (char *)(pcfg));
+ printf("cfg_gpb2 %x %x\n", pcfg->cfg_gpb2,
+ (char *)&(pcfg->cfg_gpb2) - (char *)(pcfg));
+ printf("cfg_gpb3 %x %x\n", pcfg->cfg_gpb3,
+ (char *)&(pcfg->cfg_gpb3) - (char *)(pcfg));
+ printf("cfg_gpb4 %x %x\n", pcfg->cfg_gpb4,
+ (char *)&(pcfg->cfg_gpb4) - (char *)(pcfg));
+ printf("cfg_ssc %x %x\n", pcfg->cfg_ssc,
+ (char *)&(pcfg->cfg_ssc) - (char *)(pcfg));
+ printf("cfg_runit %x %x\n", pcfg->cfg_runit,
+ (char *)&(pcfg->cfg_runit) - (char *)(pcfg));
+ printf("cfg_rsvc1 %x %x\n", pcfg->cfg_rsvc1,
+ (char *)&(pcfg->cfg_rsvc1) - (char *)(pcfg));
+ printf("cfg_rsvc2 %x %x\n", pcfg->cfg_rsvc2,
+ (char *)&(pcfg->cfg_rsvc2) - (char *)(pcfg));
+}
+
+swabvid(pvid)
+ struct vid *pvid;
+{
+ M_32_SWAP(pvid->vid_oss);
+ M_16_SWAP(pvid->vid_osl);
+ M_16_SWAP(pvid->vid_osa_u);
+ M_16_SWAP(pvid->vid_osa_l);
+ M_32_SWAP(pvid->vid_cas);
+}
+
+swabcfg(pcfg)
+ struct cfg *pcfg;
+{
+ printf("swapping cfg\n");
+
+ M_16_SWAP(pcfg->cfg_atm);
+ M_16_SWAP(pcfg->cfg_prm);
+ M_16_SWAP(pcfg->cfg_atm);
+ M_16_SWAP(pcfg->cfg_rec);
+ M_16_SWAP(pcfg->cfg_trk);
+ M_16_SWAP(pcfg->cfg_psm);
+ M_16_SWAP(pcfg->cfg_shd);
+ M_16_SWAP(pcfg->cfg_pcom);
+ M_16_SWAP(pcfg->cfg_rwcc);
+ M_16_SWAP(pcfg->cfg_ecc);
+ M_16_SWAP(pcfg->cfg_eatm);
+ M_16_SWAP(pcfg->cfg_eprm);
+ M_16_SWAP(pcfg->cfg_eatw);
+ M_16_SWAP(pcfg->cfg_rsvc1);
+ M_16_SWAP(pcfg->cfg_rsvc2);
+}
--- /dev/null
+# $Id: Makefile,v 1.1.1.1 1997/03/03 19:30:41 rahnds Exp $
+
+S= ${.CURDIR}/../../../..
+INCL?= -I${.CURDIR} -I${.CURDIR}/../libsa -I${S}/lib/libsa -I${S}
+COPTS?= ${DEFS} ${INCL}
+
+.include "${S}/arch/${MACHINE}/stand/libsa/Makefile.inc"
+
+SRCS= sboot.c clock.c etherfun.c if_le.c
+
+OBJS= ${SRCS:S/.c/.o/g}
+CLEANFILES+=XBUG.o XSRT0.o oc_cksum.o sboot.tmp rboot.tmp srec sboot rboot
+MDEC_DIR?=/usr/mdec
+
+all: sboot rboot
+
+sboot.tmp: XSRT0.o oc_cksum.o ${OBJS} ${LIBSA}
+ ld -N -s -static -T 0x4000 XSRT0.o ${OBJS} oc_cksum.o -o sboot.tmp ${LIBSA}
+
+rboot.tmp: XBUG.o XSRT0.o oc_cksum.o ${OBJS} ${LIBSA}
+ ld -N -s -static -Ttext 0xffa00000 -Tdata 0x4000 XBUG.o XSRT0.o \
+ ${OBJS} oc_cksum.o -o rboot.tmp ${LIBSA}
+
+srec: srec.c
+ ${CC} ${.CURDIR}/srec.c -o srec
+
+sboot: sboot.tmp srec
+ dd ibs=32 skip=1 if=sboot.tmp | ${.OBJDIR}/srec 4 0x4000 sboot > sboot
+
+rboot: rboot.tmp srec
+ dd ibs=32 skip=1 if=rboot.tmp | ${.OBJDIR}/srec 4 0x4000 rboot > rboot
+
+install:
+ install ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
+ sboot ${DESTDIR}${MDEC_DIR}/sboot
+ install ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
+ rboot ${DESTDIR}${MDEC_DIR}/rboot
+
+.include <bsd.prog.mk>
--- /dev/null
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ */
+
+/*
+ * Theo sez: I wrote a bootrom for the MVME147 *years* ago. To write
+ * this ROM I copied a few chunks from the old bootrom, like this piece:
+ *
+ * "watch this, the moto bastard struck here, shouldn't have hired people
+ * from intel I tried to tell them...
+ * "BOOT"
+ * offset from baseaddr to entry point.
+ * offset from baseaddr to first word after checksum
+ * garbage
+ * checksum made with CS command
+ * No need to change any of this unless you try to take our names out
+ * of there. Ie. don't touch."
+ */
+
+ .text
+bootlabel: .ascii "BOOT"
+ .long bootstart-0xffa00000 | for rom install
+ .long bootlabelend - bootlabel
+ .asciz "VME147 rboot Copyright (c) 1995 Theo de Raadt"
+ .align 2
+bootstart: jmp bssclr
+ .word 0x229c | XXX bitching cksum!
+bootlabelend:
+ .word 0
+
+ | clear bss and the kernel location
+bssclr: movl #_edata,a0
+ movl #_end - _edata,d0
+1: clrb a0@+
+ subql #1,d0
+ bpl 1b
+
+ | rip the data segment from ROM into ram..
+ movl #_etext,a2 | start of data
+ movl #0x4000,a1 | shovel address
+ movl #_edata - _etext,d0
+1: movb a2@+,a1@+
+ subql #1,d0
+ bpl 1b
+
+ bra start
--- /dev/null
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ *
+ * 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 0x4000, load at 0xa000, stack at 0x9ff0.
+ .text
+ .globl start
+start: movb #0,_reboot
+ jra Ldoit
+restart: movb #1,_reboot | fall through
+
+Ldoit: movl #0x00006ff0,sp
+ jsr _main
+
+ .globl ___main
+___main: rts
--- /dev/null
+/* $Id: clock.c,v 1.1.1.1 1997/03/03 19:30:41 rahnds 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 <sys/cdefs.h>
+#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));
+}
--- /dev/null
+/* $Id: clockreg.h,v 1.1.1.1 1997/03/03 19:30:41 rahnds 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
--- /dev/null
+/*
+ *
+ * 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 <sys/cdefs.h>
+#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);
+}
+
+/* Receive 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
+ * acknowledgement
+ */
+void
+do_send_tftp(mesgtype)
+ 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 received the wrong block */
+ if (tftp->info.block < last_ack + 1) {
+ /* nack whatever we received */
+ do_send_tftp(tftp->info.block);
+ } else {
+ /* nack the last confirmed block */
+ do_send_tftp(last_ack);
+ }
+ 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);
+}
--- /dev/null
+/*
+ *
+ * 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.mvme68k\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));
--- /dev/null
+/* $Id: if_le.c,v 1.1.1.1 1997/03/03 19:30:41 rahnds Exp $ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ *
+ * 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 <sys/cdefs.h>
+#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;
+}
--- /dev/null
+/* $Id: if_lereg.h,v 1.1.1.1 1997/03/03 19:30:41 rahnds 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)
+
--- /dev/null
+| $Id: oc_cksum.S,v 1.1.1.1 1997/03/03 19:30:41 rahnds 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 ones 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) does not 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 do not 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 allocator, the data we are called with is almost
+| always longword aligned, there is no benefit to this added cost
+| and we are better off letting the loop take a big performance hit
+| in the rare cases where we are 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 is clear why this happens for a count of 40: unroll-8 pays a
+| loop branch cost and unroll-16 does not. But the tests also showed
+| that 16 was better than 8 for a count of 20. It is 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 <machine/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 are 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 does not affect X)
+
+ movl d0,d1 | fold 32 bit sum to 16 bits
+ swap d1 | (NB- swap does not 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
--- /dev/null
+S00A0000000072626F6F74CF
+S32500004000424F4F540000003C00000044564D453134372072626F6F7420436F70797269671F
+S325000040206874202863292031393935205468656F2064652052616164740000004EF9FFA047
+S325000040400046229C0000207C000040207000421853806A00FFFA247CFFA01908227C00005C
+S325000040604000700012DA53806A00FFFA6000000213FC00000000463C600813FC00010000FD
+S32500004080463C2E7C00006FF04EB9FFA000B84E750A73626F6F743A204D564D4531343720F2
+S325000040A0626F6F7473747261702070726F6772616D0A003E3E3E20004E56FF802F0A61FF64
+S325000040C0FFFFFFCE1D7C0030FF80487AFFC461FF0000159E584F45EEFF80487AFFD761FFDE
+S325000040E00000158E2F0A61FF000013F82F0A610001CA504F584F60E24E714E5600004E4F86
+S3250000410000634E5E4E754D7920697020616464726573732069733A2025642E25642E2564B5
+S325000041202E25640A0053657276657220697020616464726573732069733A2025642E2564AC
+S325000041402E25642E25640A004661696C65642E0A0065786974696E6720746F20524F4D0A51
+S3250000416000446F776E6C6F6164204661696C65640A00446F776E6C6F61642077617320616E
+S325000041802073756363657373210A00636C69656E7420495020616464726573732025642EC0
+S325000041A025642E25642E25640A0073657276657220495020616464726573732025642E25A6
+S325000041C0642E25642E25640A005245564152503A204661696C65642E0A00726563656976D8
+S325000041E06564207365636F6E6461727920626F6F742070726F6772616D2E0A0062736400AB
+S3250000420076616C696420636F6D6D616E64730A0061202D2073656E64206120524152500AB4
+S325000042200062202D20626F6F74207468652073797374656D0A0071202D2065786974207499
+S325000042406F20524F4D0A0066202D206674702074686520626F6F742066696C650A0067202E
+S325000042602D20657865637574652074686520626F6F742066696C650A0068202D2068656CEB
+S32500004280700A0069202D20696E6974204C414E434520656E657420636869700A0073626FB3
+S325000042A06F743A2025733A20556E6B6E6F776E20636F6D6D616E640A00004E5600002F0BF2
+S325000042C02F0A246E000810120C000067670001F26E2E0C000062670000F86E180C000061BA
+S325000042E067364A00670001EC0C00003F67000192600001D40C000066670000AE600001C853
+S325000043000C000069670001B26D0001760C00007167000084600001B061FF0000054C4A8030
+S325000043206766428010390000465F2F00428010390000465E2F00428010390000465D2F0010
+S32500004340428010390000465C2F00487AFDBA45F9FFA0166E4E92428010390000463B2F0006
+S32500004360428010390000463A2F0042801039000046392F0042801039000046382F00487A4A
+S32500004380FDA54E926000014C487AFDBE61FF000012E06000013E487AFDB961FF000012D2BE
+S325000043A06100FD586000012C61FF000007127201B280660E487AFDAB61FF000012B4600032
+S325000043C00112487AFDAE61FF000012A66000010461FF00000F8061FF0000048E4A80660EBB
+S325000043E0487AFDE761FF00001288600000E6428010390000465F2F00428010390000465E43
+S325000044002F00428010390000465D2F00428010390000465C2F00487AFD7347F9FFA0166E19
+S325000044204E93428010390000463B2F00428010390000463A2F0042801039000046392F0067
+S3250000444042801039000046382F00487AFD5E4E93DEFC002861FF000006667201B2806608BF
+S32500004460487AFCFF4E93606A487AFD7061FF00001200584F524A4A12664645FAFD80604086
+S32500004480487AFD7E45F9FFA0166E4E92487AFD824E92487AFD8D4E92487AFD9C4E92487A4E
+S325000044A0FDA74E92487AFDB84E92487AFDCD4E92487AFDD14E92601A61FF00000E9860124D
+S325000044C02F0A613C600C2F0A487AFDD361FF000011A0246EFFF8266EFFFC4E5E4E756A7552
+S325000044E06D70696E6720746F20626F6F742070726F6772616D20617420307825782E0A001A
+S325000045004E56000048E7003C246E00083A7C70002F0D487AFFCA61FF0000115642804281B3
+S32500004520264A2F0A61FF0000108ED5C0284A4ED54CEE3C00FFF04E5E4E7500000000001FB1
+S32500004540003B005A0078009700B500D400F301110130014E4E56000048E73F30266E0008C5
+S325000045602C2E000C2A2E0010282E0014262E0018242E001C200BE880244045F20C00200ABF
+S32500004580720F2E0BC287244147F20A002006E880244045F20C00200A720FC286244145F2A6
+S325000045A00A002C0A2005E880244045F20C00200A720FC285244145F20A002A0A2004E88029
+S325000045C0244045F20C00200A720FC284244145F20A00280A2003E880244045F20C00200A09
+S325000045E0720FC283244145F20A00260A2002E880720FC282244045F20C00200A244145F25D
+S325000046000A44240A7E45BE826D027446200353807E0BBE80650A200453807E1EBE80640487
+S325000046204280607293C97046B4806F1C307C016E223C0000016DE8C007826604D3C8600290
+S32500004640D3C15280B4806EEE41FAFEF030703A00D1C443F098FFE8C0078266087E02BE839C
+S325000046606C02524943F19A0020092200E98192802401E9829481EF822005E7809085EB8074
+S32500004680D085E9802042D1C02006E980908641F00C002008D08B4CEE0CFCFFE04E5E4E756E
+S325000046A04E56000048E73E0020790000400010100000004010801C2800011A280002182851
+S325000046C000031628000514280006122800071010020000BF108042A71F41000342A71F4204
+S325000046E0000342A71F43000342A71F44000342A71F45000342A71F4600036100FE584CEE82
+S32500004700007CFFEC4E5E4E754E5600002F0A428020790000400411BC00FF08005280720524
+S32500004720B2806CEC487800062239000040045C812F0148790000465445F9FFA015D04E927A
+S32500004740207900004004317C8035000C20790000400830BC0001317C08000002117C0006F0
+S325000047600004207900004008117C00040005207900004008317C0003000648780006223900
+S325000047800000400850812F014879000046544E92487800067212D2B9000040082F01487981
+S325000047A0000046544E924280DEFC0024207900004008423008184230080E52807203B28045
+S325000047C06CEA4878004C48790000402861FF00000910246EFFFC4E5E4E754E5600002F0AF6
+S325000047E0487800064878060048790000402861FF00000A6E207900004004504F584F0C688F
+S325000048008035000C66562079000040080C680004000666484878000448790000465C721857
+S32500004820D2882F0145F9FFA015D04E9248780004487900004638720ED2B9000040082F01C0
+S325000048404E924878000648790000463022390000400850812F014E92700160024280246ECA
+S32500004860FFFC4E5E4E754E5600002F0242826100FE986100FF664A8067047001600A52828E
+S325000048807204B2826CE84280242EFFFC4E5E4E75000178787878787878782E6D766D6536BC
+S325000048A0386B006F6374657400003031323334353637383941424344454600004E56FFFCEF
+S325000048C048E73038242E0008663228790000401447EC001961FFFFFFFDCA33C0000046406A
+S325000048E00C7903E7000046406208067903E80000464033FC00450000462C60082679000076
+S325000049004018584B487800062F390000400448790000463045F9FFA015D04E924878000685
+S325000049202639000040045C832F034879000046544E92207900004004317C0800000C20794B
+S325000049400000400C7604EFD0300420790000400C7605EFD0310420790000400C42280001F4
+S3250000496020790000400C42680004317C40000006117C0003000820790000400C117C001190
+S32500004980000948780004760CD6B90000400C2F0348790000465C4E92DEFC00202EBC00008E
+S325000049A000047610D6B90000400C2F034879000046384E9220790000400C4268000A384B1F
+S325000049C098F90000400E314C000242A7487800142F0861FF00000A5C20790000400C46404E
+S325000049E03140000A20790000401030B90000464031790000462C000242680006DEFC00181E
+S32500004A004A82671020790000401830BC000431420002605448780004486EFFFC487900000D
+S32500004A20465C45F9FFA015D04E92487800192F3900004014487AFE5A4E927209DEFC001830
+S32500004A4043FAFE68207900004014700FC0AEFFFC11B108001800202EFFFCE8882D40FFFCD5
+S32500004A6053817601B68165DC207900004010384B98F900004012314C000497FC00004028A2
+S32500004A802F0B48790000402861FF000006544CEE1C0CFFE84E5E4E750A002578200D005413
+S32500004AA04654503A20446F776E6C6F6164206572726F722025643A2025730A004E560000E1
+S32500004AC048E73C304282283C0000700042B90000462842A76100FDE6584F428348780005D6
+S32500004AE04878060048790000402861FF00000772504F584F4A8066304AB900004628670862
+S32500004B002F3900004628600242A76100FDB0584F52827A05BA826CC4487AFF7E61FF00005B
+S32500004B200B5070016000010020790000401C3628000220037A09EBA02F00487AFF5E61FF0E
+S32500004B4000000B2E207900004004504F0C680800000C667820790000400C0C280011000901
+S32500004B60666A0C7900450000462C660C20790000401033D00000462C20790000401C0C5002
+S32500004B800005661E2A0858852F054280302800022F00487AFF0B61FF00000AD6700160001B
+S32500004BA0008620790000401C4280302800022239000046285281B28067186F042F00600603
+S32500004BC02F39000046286100FCF4584F52826000FF0C4282203900004628528023C0000082
+S32500004BE04628207900004010366800042F006100FCCC45EBFFF42F0A2F042A390000401C10
+S32500004C0058852F0561FF000009CAD88A504F504FB7FC0000020B6E00FEC4487AFE7C61FF1E
+S32500004C2000000A4E42804CEE0C3CFFE84E5E4E756C65303A206265656E20626162626C690B
+S32500004C406E672C20666F756E6420627920272573270A006C65303A206D656D6F727920658D
+S32500004C6072726F7220696E20272573270A004E5600002F0A2F02242E0008246E000C30121A
+S32500004C800800000E67142F02487AFFA661FF000009E061FFFFFFF466504F30120800000DEE
+S32500004CA0670434BC200030120800000C670434BC100030120800000B67122F02487AFF955D
+S32500004CC061FF000009AC61FFFFFFF432242EFFF8246EFFFC4E5E4E756C65303A20696E6955
+S32500004CE0742074696D656F75742C2073746174203D20307825780A004E56000048E73C3CF4
+S32500004D00246E0008287900004644267900004648283C000186A0426C000238BC00044878A8
+S32500004D2035BE2F0B61FF000008E64253176A0001000217520003176A00030004176A000262
+S32500004D400005176A00050006176A0004000742AB000842AB000C7418D48B2002424048402B
+S32500004D600040600037400012374200107458D48B2002424048403740001637420014397C55
+S32500004D8000010002388B397C00020002200B42404840388091C8504F4BF08A00200DEB804C
+S32500004DA09088E78090884BF30A60240D2208E7813782181817BC0080181A20024240484051
+S32500004DC01780181B37BCFA12181C4273181E52487A07BA886CC291C8327C2FD04BF08A008F
+S32500004DE0200DEB809088E78090884BF10A00200D240BD4802208E781378218584233185AE6
+S32500004E002002424048401780185B4273185C4273185E52484A886FC4397C0003000238BCB5
+S32500004E200004426C000238BC00015384660E2F03487AFEA661FF00000838600C30144283CB
+S32500004E4036000803000867E238BC010042B90000464C42B900004650426C000238BC000201
+S32500004E604CEE3C3CFFE04E5E4E756C655F706F6C6C006C65305F706F6C6C3A20726D642071
+S32500004E8073746174757320307825780A006C655F706F6C6C3A20636861696E6564207061FB
+S32500004EA0636B65740A0063737230207768656E20626164207468696E6773206861707065CF
+S32500004EC06E3A2025780A00004E56000048E72038267900004644287900004648426B00022B
+S32500004EE030130800000A670436BC040020390000464C45F40E18102A00026C0642806000DC
+S32500004F0000F630136C0C2F0B487AFF606100FD60504F102A0002080000066718102A00021D
+S32500004F2042A71F400003487AFF4A61FF0000074242826078102A0002020000030C00000380
+S32500004F406712487AFF4961FF0000072661FFFFFFF1AC584F302A0006428234000C820000B3
+S32500004F6005ED6F1A428230133F004267487AFF3861FF000006FC61FFFFFFF182602E4A823B
+S32500004F80672A59824A826F242F022F2E000820790000464C43F08A002009EB809088E780AF
+S32500004FA0908848740A6061FF0000062820790000464C43F08A002009EB809088E78090880C
+S32500004FC049F40A60200C34804240484015400003357CFA12000441F90000464C428072071A
+S32500004FE0B290670820390000464C52802080157C0080000220024CEE1C04FFF04E5E4E75B0
+S325000050006C655F70757428776179206265666F726520786D697429006C65303A206F757437
+S325000050207075742062756666657220627573790A006C655F707574286265666F72652078CE
+S325000050406D697429006C655F70757428616674657220786D697429006C65303A2074726167
+S325000050606E736D69742074696D656F75742C2073746174203D20307825780A006C655F7064
+S3250000508075742874696D656F757429006C655F7075743A20786D6974206572726F722C208E
+S325000050A06275662025640A006C655F70757428786D6974206572726F7229006C65303A20B9
+S325000050C07472616E736D6974206572726F722C206572726F72203D20307825780A004E5628
+S325000050E0000048E73838282E000C247900004644287900004648263C000186A0426A00021C
+S3250000510030126C0C2F0A487AFEF86100FB62504F20390000465047F40E58600C487AFEFACB
+S3250000512061FF0000054C584F102B00026DEE2F0420790000465043F08A002009EB809088AE
+S32500005140E7809088D080068000002FD0487408002F2E000861FF0000047A504F584F723FF7
+S32500005160B2846508377CFFC0000460083004444037400004426B000630126C0C2F0A487A0D
+S32500005180FEB16100FAEA504F177C0083000220790000465043F08A002009EB809088E7805F
+S325000051A09088D080068000002FD0D08C3680424048401740000334BC000830126C0C2F0A9B
+S325000051C0487AFE836100FAA8504F538366202F02487AFE8661FF000004983012504F6C1AAE
+S325000051E02F0A487AFE986100FA86504F600C3012428234000802000967D034BC0200301274
+S325000052006C2A3012024078000C40200067122F3900004650487AFE7661FF00000454504F86
+S325000052202F0A487AFE846100FA46504F42B900004650102B000208000006660420046014CD
+S32500005240302B00063F004267487AFE7161FF0000042070FF4CEE1C1CFFE84E5E4E754E566F
+S32500005260000048E73E20246E00082C2E000C242E001061FFFFFFF42C2A00DA8242844283AA
+S3250000528061FFFFFFF41E2400BA826F624A83665E2F062F0A6100FC322600504FB484670273
+S325000052A028024A8367DA1212B2390000465466CE122A0001B2390000465566C2122A0002AA
+S325000052C0B2390000465666B6122A0003B2390000465766AA122A0004B23900004658669E81
+S325000052E0122A0005B239000046596794609020034CEE047CFFE84E5E4E754552524F523AFB
+S325000053002065746865726E65742061646472657373206E6F74207365742120205573652077
+S325000053204C5341442E0A006C65303A2065746865726E657420616464726573733A20257854
+S325000053403A25783A25783A25783A25783A25780A00004E5600002F0A2F022439FFFE077823
+S32500005360200202802FFFFF000C802FFFFF006612487AFF8861FF000002F861FFFFFFED7EB9
+S32500005380584F45F90000465414BC000842390000465513FC003E00004656E08A43F900000B
+S325000053A046591282E08A41F9000046581082E08A13C200004657428010112F004280101010
+S325000053C02F002F024878003E42A748780008487AFF5761FF0000029A487800104879000013
+S325000053E0464461FF0000022823FCFFFE1800000046442239FFFE07740681FFF0000023C1A8
+S3250000540000004648DEFC00202E8A6100F8EC242EFFF8246EFFFC4E5E4E754E56000020797F
+S32500005420000046444268000230BC00044E5E4E75206F0004222F0008202F000C2F02080150
+S3250000544000006674080100016600008A2401EC8902820000003C4482023C000F4EFB284252
+S325000054602418D1822418D1822418D1822418D1822418D1822418D1822418D1822418D182AE
+S325000054802418D1822418D1822418D1822418D1822418D1822418D1822418D1822418D1828E
+S325000054A051C9FFBE22004841D1416402524002800000FFFF241F4E75080100016708428297
+S325000054C0343018FDD0824282143018FFE18AD0826000FF7A4282343018FED0826000FF6EE9
+S325000054E04E56000048E73038262E0008264349F9FFA018E261FF000003C2747FC4802F023E
+S325000055004E94584F7215B282670000886D20720AB282670000946D087208B2826738602ACE
+S32500005520720DB282677C7212B2826740601C7223B28267306D087217B2826756600C724087
+S32500005540B282674E727FB282670416C260A6487800084E94584F487800204E944878000813
+S325000055604E94504FB68B648C534B60884878000A4E942443584FB7CA6300FF7A121A49C1A0
+S325000055802F0161FF0000035E584FB7CA62EE6000FF644878000A61FF0000034A584F60005B
+S325000055A0FF4C4878000A4E9442134CEE1C0CFFEC4E5E4E754E560000226E000820494A11DD
+S325000055C0670652484A1066FA200890894E5E4E754E560000222E0010226E0008206E000C1E
+S325000055E0B1C9631AD3C1D1C1200153814A8067161121200153814A8066F6600A10D920018B
+S3250000560053814A8066F64E5E4E7500004E560000206E0008202E000C538072FFB280670C9E
+S32500005620421851C8FFFC4240538064F44E5E4E754E56000020790000402410AE000B52B965
+S32500005640000040244E5E4E754E56000023EE000800004024486E00102F2E000C487AFFD28E
+S32500005660612420790000402442104E5E4E754E560000486E000C2F2E00084879FFA018E2BC
+S3250000568061044E5E4E754E56000048E7303C2A6E0008286E000C266E0010594B600C4A822F
+S325000056A0670001782F024E95584F141C49C27625B68266EA95CA141C49C2224241E9FF9E26
+S325000056C07616B6886500013A303B8A064EFB0002003400A200CA013001300130013001307F
+S325000056E001300130002E0130013000EE01300130013000AE0130010401300130011A347C20
+S32500005700000160B2584B241B2453161A49C32F032F022F0D61000120504F584F4A82678AB7
+S3250000572091C8603A53817001E3A0C082672A703C4A886702702C2F004E95584F60082F0101
+S325000057404E95584F524A121249C17620B6816DEE307C00016008524A0C1200206EF8121A46
+S3250000576049C166C04A886700FF424878003E6000FF36584B767FC6932F036000FF2A584B97
+S325000057802453141A49C26700FF222F024E95584F141A49C266F46000FF12584B24136C0ABC
+S325000057A04878002D4E954482584F4878000A2F022F0D61000082504F584F6000FEEE584B57
+S325000057C02413487800082F022F0D616A504F584F6000FED8584B24134878000A2F022F0DFF
+S325000057E06154504F584F6000FEC2584B2413487800102F022F0D613E504F584F6000FEAC82
+S32500005800487800254E95584F4A8A6700FE984878006C4E95584F6000FE8C4CEE3C0CFFE839
+S325000058204E5E4E753031323334353637383961626364656600004E56FFF448E73038286ECD
+S325000058400008222E000C242E001045EEFFF441FAFFD44C42100014F008004A8166F447EE44
+S32500005860FFF4162249C32F034E94584FB7CA65F24CEE1C0CFFE04E5E4E757C2F2D5C000074
+S325000058804E5600002F0A7003C0B90000402041FAFFEA1030080049C02F0052B900004020CA
+S325000058A045F9FFA018E24E92487800084E92246EFFFC4E5E4E7500004E5600001F3C000088
+S325000058C04E4F0000101F49C04E5E4E754E56000042814E4F000167000004720142804E5E2D
+S325000058E04E754E5600002F02242E0008700AB08266064878000D61EA1F024E4F0020242E50
+S32500005900FFFC4E5E4E750000FFFE07F80000402800004036000040360000404A00004052AB
+S30D00005920000040520000405255
+S70300004000BB
--- /dev/null
+S00A0000000073626F6F74CE
+S3250000400013FC000000005ED4600813FC000100005ED42E7C00006FF04EB9000040484E7554
+S325000040200A73626F6F743A204D564D4531343720626F6F7473747261702070726F67726175
+S325000040406D0A003E3E3E20004E56FF802F0A61FFFFFFFFCE1D7C0030FF80487AFFC461FF55
+S325000040600000159E584F45EEFF80487AFFD761FF0000158E2F0A61FF000013F82F0A610055
+S3250000408001CA504F584F60E24E714E5600004E4F00634E5E4E754D7920697020616464727B
+S325000040A06573732069733A2025642E25642E25642E25640A005365727665722069702061B0
+S325000040C06464726573732069733A2025642E25642E25642E25640A004661696C65642E0ACA
+S325000040E00065786974696E6720746F20524F4D0A00446F776E6C6F6164204661696C65640A
+S325000041000A00446F776E6C6F61642077617320612073756363657373210A00636C69656E1C
+S325000041207420495020616464726573732025642E25642E25642E25640A00736572766572D7
+S3250000414020495020616464726573732025642E25642E25642E25640A005245564152503AB8
+S32500004160204661696C65642E0A007265636569766564207365636F6E6461727920626F6F0D
+S32500004180742070726F6772616D2E0A006273640076616C696420636F6D6D616E64730A0090
+S325000041A061202D2073656E64206120524152500A0062202D20626F6F7420746865207379B1
+S325000041C07374656D0A0071202D206578697420746F20524F4D0A0066202D206674702074B2
+S325000041E0686520626F6F742066696C650A0067202D20657865637574652074686520626F35
+S325000042006F742066696C650A0068202D2068656C700A0069202D20696E6974204C414E439B
+S325000042204520656E657420636869700A0073626F6F743A2025733A20556E6B6E6F776E2016
+S32500004240636F6D6D616E640A00004E5600002F0B2F0A246E000810120C000067670001F2CF
+S325000042606E2E0C000062670000F86E180C00006167364A00670001EC0C00003F670001925C
+S32500004280600001D40C000066670000AE600001C80C000069670001B26D0001760C00007143
+S325000042A067000084600001B061FF0000054C4A8067664280103900005EF72F00428010391A
+S325000042C000005EF62F004280103900005EF52F004280103900005EF42F00487AFDBA45F985
+S325000042E0000055FE4E924280103900005ED32F004280103900005ED22F00428010390000A5
+S325000043005ED12F004280103900005ED02F00487AFDA54E926000014C487AFDBE61FF000003
+S3250000432012E06000013E487AFDB961FF000012D26100FD586000012C61FF000007127201FB
+S32500004340B280660E487AFDAB61FF000012B460000112487AFDAE61FF000012A660000104C4
+S3250000436061FF00000F8061FF0000048E4A80660E487AFDE761FF00001288600000E6428070
+S32500004380103900005EF72F004280103900005EF62F004280103900005EF52F004280103924
+S325000043A000005EF42F00487AFD7347F9000055FE4E934280103900005ED32F00428010395A
+S325000043C000005ED22F004280103900005ED12F004280103900005ED02F00487AFD5E4E93A9
+S325000043E0DEFC002861FF000006667201B2806608487AFCFF4E93606A487AFD7061FF0000DF
+S325000044001200584F524A4A12664645FAFD806040487AFD7E45F9000055FE4E92487AFD82EE
+S325000044204E92487AFD8D4E92487AFD9C4E92487AFDA74E92487AFDB84E92487AFDCD4E9226
+S32500004440487AFDD14E92601A61FF00000E9860122F0A613C600C2F0A487AFDD361FF000087
+S3250000446011A0246EFFF8266EFFFC4E5E4E756A756D70696E6720746F20626F6F742070722B
+S325000044806F6772616D20617420307825782E0A004E56000048E7003C246E00083A7C70009F
+S325000044A02F0D487AFFCA61FF0000115642804281264A2F0A61FF0000108ED5C0284A4ED512
+S325000044C04CEE3C00FFF04E5E4E7500000000001F003B005A0078009700B500D400F30111B1
+S325000044E00130014E4E56000048E73F30266E00082C2E000C2A2E0010282E0014262E0018B4
+S32500004500242E001C200BE880244045F20C00200A720F2E0BC287244147F20A002006E8808A
+S32500004520244045F20C00200A720FC286244145F20A002C0A2005E880244045F20C00200AA1
+S32500004540720FC285244145F20A002A0A2004E880244045F20C00200A720FC284244145F2F3
+S325000045600A00280A2003E880244045F20C00200A720FC283244145F20A00260A2002E88077
+S32500004580720FC282244045F20C00200A244145F20A44240A7E45BE826D0274462003538045
+S325000045A07E0BBE80650A200453807E1EBE8064044280607293C97046B4806F1C307C016E06
+S325000045C0223C0000016DE8C007826604D3C86002D3C15280B4806EEE41FAFEF030703A0078
+S325000045E0D1C443F098FFE8C0078266087E02BE836C02524943F19A0020092200E981928058
+S325000046002401E9829481EF822005E7809085EB80D085E9802042D1C02006E980908641F0EB
+S325000046200C002008D08B4CEE0CFCFFE04E5E4E754E56000048E73E0020790000589810109B
+S325000046400000004010801C2800011A280002182800031628000514280006122800071010D2
+S32500004660020000BF108042A71F41000342A71F42000342A71F43000342A71F44000342A7C4
+S325000046801F45000342A71F4600036100FE584CEE007CFFEC4E5E4E754E5600002F0A4280F6
+S325000046A020790000589C11BC00FF080052807205B2806CEC4878000622390000589C5C81CE
+S325000046C02F01487900005EEC45F9000055604E9220790000589C317C8035000C2079000032
+S325000046E058A030BC0001317C08000002117C000600042079000058A0117C000400052079C1
+S32500004700000058A0317C00030006487800062239000058A050812F01487900005EEC4E92E0
+S32500004720487800067212D2B9000058A02F01487900005EEC4E924280DEFC00242079000032
+S3250000474058A0423008184230080E52807203B2806CEA4878004C4879000058C061FF00002D
+S325000047600910246EFFFC4E5E4E754E5600002F0A48780006487806004879000058C061FF7C
+S3250000478000000A6E20790000589C504F584F0C688035000C66562079000058A00C680004CE
+S325000047A00006664848780004487900005EF47218D2882F0145F9000055604E9248780004BD
+S325000047C0487900005ED0720ED2B9000058A02F014E9248780006487900005EC822390000C9
+S325000047E058A050812F014E92700160024280246EFFFC4E5E4E754E5600002F02428261004F
+S32500004800FE986100FF664A8067047001600A52827204B2826CE84280242EFFFC4E5E4E75D6
+S32500004820000178787878787878782E6D766D6536386B006F637465740000303132333435A7
+S325000048403637383941424344454600004E56FFFC48E73038242E000866322879000058AC12
+S3250000486047EC001961FFFFFFFDCA33C000005ED80C7903E700005ED86208067903E800001F
+S325000048805ED833FC004500005EC460082679000058B0584B487800062F390000589C4879B1
+S325000048A000005EC845F9000055604E924878000626390000589C5C832F03487900005EECC4
+S325000048C04E9220790000589C317C0800000C2079000058A47604EFD030042079000058A40D
+S325000048E07605EFD031042079000058A4422800012079000058A442680004317C400000060D
+S32500004900117C000300082079000058A4117C0011000948780004760CD6B9000058A42F03BA
+S32500004920487900005EF44E92DEFC00202EBC000000047610D6B9000058A42F034879000092
+S325000049405ED04E922079000058A44268000A384B98F9000058A6314C000242A748780014AC
+S325000049602F0861FF00000A5C2079000058A446403140000A2079000058A830B900005ED8E6
+S32500004980317900005EC4000242680006DEFC00184A8267102079000058B030BC000431425A
+S325000049A00002605448780004486EFFFC487900005EF445F9000055604E92487800192F399F
+S325000049C0000058AC487AFE5A4E927209DEFC001843FAFE682079000058AC700FC0AEFFFC3E
+S325000049E011B108001800202EFFFCE8882D40FFFC53817601B68165DC2079000058A8384BCF
+S32500004A0098F9000058AA314C000497FC000058C02F0B4879000058C061FF000006544CEECA
+S32500004A201C0CFFE84E5E4E750A002578200D00544654503A20446F776E6C6F616420657257
+S32500004A40726F722025643A2025730A004E56000048E73C304282283C0000700042B9000086
+S32500004A605EC042A76100FDE6584F428348780005487806004879000058C061FF000007723C
+S32500004A80504F584F4A8066304AB900005EC067082F3900005EC0600242A76100FDB0584F54
+S32500004AA052827A05BA826CC4487AFF7E61FF00000B507001600001002079000058B4362862
+S32500004AC0000220037A09EBA02F00487AFF5E61FF00000B2E20790000589C504F0C6808000E
+S32500004AE0000C66782079000058A40C2800110009666A0C79004500005EC4660C207900001C
+S32500004B0058A833D000005EC42079000058B40C500005661E2A0858852F0542803028000281
+S32500004B202F00487AFF0B61FF00000AD67001600000862079000058B44280302800022239C1
+S32500004B4000005EC05281B28067186F042F0060062F3900005EC06100FCF4584F52826000F3
+S32500004B60FF0C4282203900005EC0528023C000005EC02079000058A8366800042F0061004B
+S32500004B80FCCC45EBFFF42F0A2F042A39000058B458852F0561FF000009CAD88A504F504F65
+S32500004BA0B7FC0000020B6E00FEC4487AFE7C61FF00000A4E42804CEE0C3CFFE84E5E4E7571
+S32500004BC06C65303A206265656E20626162626C696E672C20666F756E642062792027257347
+S32500004BE0270A006C65303A206D656D6F7279206572726F7220696E20272573270A004E5695
+S32500004C0000002F0A2F02242E0008246E000C30120800000E67142F02487AFFA661FF000061
+S32500004C2009E061FFFFFFF466504F30120800000D670434BC200030120800000C670434BCAB
+S32500004C40100030120800000B67122F02487AFF9561FF000009AC61FFFFFFF432242EFFF807
+S32500004C60246EFFFC4E5E4E756C65303A20696E69742074696D656F75742C207374617420D4
+S32500004C803D20307825780A004E56000048E73C3C246E0008287900005EDC267900005EE0C5
+S32500004CA0283C000186A0426C000238BC0004487835BE2F0B61FF000008E64253176A000169
+S32500004CC0000217520003176A00030004176A00020005176A00050006176A0004000742AB4B
+S32500004CE0000842AB000C7418D48B2002424048400040600037400012374200107458D48BB9
+S32500004D002002424048403740001637420014397C00010002388B397C00020002200B424066
+S32500004D204840388091C8504F4BF08A00200DEB809088E78090884BF30A60240D2208E781D6
+S32500004D403782181817BC0080181A2002424048401780181B37BCFA12181C4273181E524831
+S32500004D607A07BA886CC291C8327C2FD04BF08A00200DEB809088E78090884BF10A00200DCF
+S32500004D80240BD4802208E781378218584233185A2002424048401780185B4273185C4273D4
+S32500004DA0185E52484A886FC4397C0003000238BC0004426C000238BC00015384660E2F0304
+S32500004DC0487AFEA661FF00000838600C3014428336000803000867E238BC010042B90000D0
+S32500004DE05EE442B900005EE8426C000238BC00024CEE3C3CFFE04E5E4E756C655F706F6C09
+S32500004E006C006C65305F706F6C6C3A20726D642073746174757320307825780A006C655F09
+S32500004E20706F6C6C3A20636861696E6564207061636B65740A0063737230207768656E2083
+S32500004E40626164207468696E67732068617070656E3A2025780A00004E56000048E72038B0
+S32500004E60267900005EDC287900005EE0426B000230130800000A670436BC040020390000B6
+S32500004E805EE445F40E18102A00026C064280600000F630136C0C2F0B487AFF606100FD60D1
+S32500004EA0504F102A0002080000066718102A000242A71F400003487AFF4A61FF0000074249
+S32500004EC042826078102A0002020000030C0000036712487AFF4961FF0000072661FFFFFF72
+S32500004EE0F1AC584F302A0006428234000C82000005ED6F1A428230133F004267487AFF381F
+S32500004F0061FF000006FC61FFFFFFF182602E4A82672A59824A826F242F022F2E0008207904
+S32500004F2000005EE443F08A002009EB809088E780908848740A6061FF0000062820790000F4
+S32500004F405EE443F08A002009EB809088E780908849F40A60200C3480424048401540000338
+S32500004F60357CFA12000441F900005EE442807207B2906708203900005EE452802080157C64
+S32500004F800080000220024CEE1C04FFF04E5E4E756C655F70757428776179206265666F727F
+S32500004FA06520786D697429006C65303A206F75747075742062756666657220627573790AE8
+S32500004FC0006C655F707574286265666F726520786D697429006C655F70757428616674654B
+S32500004FE07220786D697429006C65303A207472616E736D69742074696D656F75742C20737B
+S32500005000746174203D20307825780A006C655F7075742874696D656F757429006C655F70F4
+S3250000502075743A20786D6974206572726F722C206275662025640A006C655F7075742878B6
+S325000050406D6974206572726F7229006C65303A207472616E736D6974206572726F722C202A
+S325000050606572726F72203D20307825780A004E56000048E73838282E000C247900005EDCB8
+S32500005080287900005EE0263C000186A0426A000230126C0C2F0A487AFEF86100FB62504FEC
+S325000050A0203900005EE847F40E58600C487AFEFA61FF0000054C584F102B00026DEE2F0461
+S325000050C0207900005EE843F08A002009EB809088E7809088D080068000002FD0487408006A
+S325000050E02F2E000861FF0000047A504F584F723FB2846508377CFFC0000460083004444037
+S3250000510037400004426B000630126C0C2F0A487AFEB16100FAEA504F177C00830002207962
+S3250000512000005EE843F08A002009EB809088E7809088D080068000002FD0D08C36804240D2
+S3250000514048401740000334BC000830126C0C2F0A487AFE836100FAA8504F538366202F020A
+S32500005160487AFE8661FF000004983012504F6C1A2F0A487AFE986100FA86504F600C3012C1
+S32500005180428234000802000967D034BC020030126C2A3012024078000C40200067122F39B4
+S325000051A000005EE8487AFE7661FF00000454504F2F0A487AFE846100FA46504F42B900005E
+S325000051C05EE8102B000208000006660420046014302B00063F004267487AFE7161FF00005C
+S325000051E0042070FF4CEE1C1CFFE84E5E4E754E56000048E73E20246E00082C2E000C242ECB
+S32500005200001061FFFFFFF42C2A00DA824284428361FFFFFFF41E2400BA826F624A83665EB7
+S325000052202F062F0A6100FC322600504FB484670228024A8367DA1212B23900005EEC66CE40
+S32500005240122A0001B23900005EED66C2122A0002B23900005EEE66B6122A0003B2390000F2
+S325000052605EEF66AA122A0004B23900005EF0669E122A0005B23900005EF1679460902003C5
+S325000052804CEE047CFFE84E5E4E754552524F523A2065746865726E65742061646472657322
+S325000052A073206E6F7420736574212020557365204C5341442E0A006C65303A20657468658D
+S325000052C0726E657420616464726573733A2025783A25783A25783A25783A25783A25780AD5
+S325000052E000004E5600002F0A2F022439FFFE0778200202802FFFFF000C802FFFFF006612BF
+S32500005300487AFF8861FF000002F861FFFFFFED7E584F45F900005EEC14BC00084239000099
+S325000053205EED13FC003E00005EEEE08A43F900005EF11282E08A41F900005EF01082E08A0C
+S3250000534013C200005EEF428010112F00428010102F002F024878003E42A748780008487A60
+S32500005360FF5761FF0000029A48780010487900005EDC61FF0000022823FCFFFE180000004C
+S325000053805EDC2239FFFE07740681FFF0000023C100005EE0DEFC00202E8A6100F8EC242E19
+S325000053A0FFF8246EFFFC4E5E4E754E560000207900005EDC4268000230BC00044E5E4E7572
+S325000053C0206F0004222F0008202F000C2F02080100006674080100016600008A2401EC89D8
+S325000053E002820000003C4482023C000F4EFB28422418D1822418D1822418D1822418D182E5
+S325000054002418D1822418D1822418D1822418D1822418D1822418D1822418D1822418D1820E
+S325000054202418D1822418D1822418D1822418D18251C9FFBE22004841D1416402524002801C
+S325000054400000FFFF241F4E750801000167084282343018FDD0824282143018FFE18AD0825E
+S325000054606000FF7A4282343018FED0826000FF6E4E56000048E73038262E0008264349F9AE
+S325000054800000587261FF000003C2747FC4802F024E94584F7215B282670000886D20720A73
+S325000054A0B282670000946D087208B2826738602A720DB282677C7212B2826740601C722365
+S325000054C0B28267306D087217B2826756600C7240B282674E727FB282670416C260A64878D7
+S325000054E000084E94584F487800204E94487800084E94504FB68B648C534B60884878000A89
+S325000055004E942443584FB7CA6300FF7A121A49C12F0161FF0000035E584FB7CA62EE600039
+S32500005520FF644878000A61FF0000034A584F6000FF4C4878000A4E9442134CEE1C0CFFECEB
+S325000055404E5E4E754E560000226E000820494A11670652484A1066FA200890894E5E4E7565
+S325000055604E560000222E0010226E0008206E000CB1C9631AD3C1D1C1200153814A80671696
+S325000055801121200153814A8066F6600A10D9200153814A8066F64E5E4E7500004E56000037
+S325000055A0206E0008202E000C538072FFB280670C421851C8FFFC4240538064F44E5E4E7582
+S325000055C04E5600002079000058BC10AE000B52B9000058BC4E5E4E754E56000023EE000860
+S325000055E0000058BC486E00102F2E000C487AFFD261242079000058BC42104E5E4E754E5638
+S325000056000000486E000C2F2E000848790000587261044E5E4E754E56000048E7303C2A6E27
+S325000056200008286E000C266E0010594B600C4A82670001782F024E95584F141C49C27625C9
+S32500005640B68266EA95CA141C49C2224241E9FF9E7616B6886500013A303B8A064EFB000247
+S32500005660003400A200CA0130013001300130013001300130002E0130013000EE013001304D
+S32500005680013000AE0130010401300130011A347C000160B2584B241B2453161A49C32F03E8
+S325000056A02F022F0D61000120504F584F4A82678A91C8603A53817001E3A0C082672A703CB8
+S325000056C04A886702702C2F004E95584F60082F014E95584F524A121249C17620B6816DEE20
+S325000056E0307C00016008524A0C1200206EF8121A49C166C04A886700FF424878003E60001B
+S32500005700FF36584B767FC6932F036000FF2A584B2453141A49C26700FF222F024E95584F0C
+S32500005720141A49C266F46000FF12584B24136C0A4878002D4E954482584F4878000A2F02D7
+S325000057402F0D61000082504F584F6000FEEE584B2413487800082F022F0D616A504F584F72
+S325000057606000FED8584B24134878000A2F022F0D6154504F584F6000FEC2584B2413487827
+S3250000578000102F022F0D613E504F584F6000FEAC487800254E95584F4A8A6700FE98487897
+S325000057A0006C4E95584F6000FE8C4CEE3C0CFFE84E5E4E753031323334353637383961625B
+S325000057C06364656600004E56FFF448E73038286E0008222E000C242E001045EEFFF441FA46
+S325000057E0FFD44C42100014F008004A8166F447EEFFF4162249C32F034E94584FB7CA65F202
+S325000058004CEE1C0CFFE04E5E4E757C2F2D5C00004E5600002F0A7003C0B9000058B841FA8A
+S32500005820FFEA1030080049C02F0052B9000058B845F9000058724E92487800084E92246EBC
+S32500005840FFFC4E5E4E7500004E5600001F3C00004E4F0000101F49C04E5E4E754E560000F1
+S3250000586042814E4F000167000004720142804E5E4E754E5600002F02242E0008700AB082D7
+S3250000588066064878000D61EA1F024E4F0020242EFFFC4E5E4E750000FFFE07F8000058C0D0
+S31D000058A0000058CE000058CE000058E2000058EA000058EA000058EA9E
+S70300004000BB
--- /dev/null
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+#include "sboot.h"
+
+void
+main()
+{
+ char buf[128];
+
+ buf[0] = '0';
+ printf("\nsboot: MVME147 bootstrap program\n");
+ while (1) {
+ printf(">>> ");
+ gets(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':
+ break;
+ 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");
+ }
+ break;
+ case 'q':
+ printf("exiting to ROM\n");
+ callrom();
+ break;
+ case 'f':
+ if (do_get_file() == 1) {
+ printf("Download Failed\n");
+ } else {
+ printf("Download was a success!\n");
+ }
+ break;
+ case 'b':
+ le_init();
+ if (rev_arp()) {
+ printf("client IP address %d.%d.%d.%d\n", myip[0],
+ myip[1], myip[2], myip[3]);
+ printf("server IP address %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("received secondary boot program.\n");
+ }
+ if (*++buf == '\0')
+ buf = "bsd";
+ go(buf);
+ break;
+ case 'h':
+ case '?':
+ printf("valid commands\n");
+ printf("a - send a RARP\n");
+ printf("b - boot the system\n");
+ printf("q - 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");
+ break;
+ case 'i':
+ le_init();
+ break;
+ case 'g':
+ go(buf);
+ break;
+ default:
+ printf("sboot: %s: Unknown command\n", buf);
+ }
+}
+
+go(buf)
+ char *buf;
+{
+ void (*entry)() = (void (*))LOAD_ADDR;
+
+ printf("jumping to boot program at 0x%x.\n", entry);
+
+ asm("clrl d0; clrl d1"); /* XXX network device */
+ asm("movl %0, a3" : : "a" (buf) : "a3");
+ asm("movl %0, a4" : : "a" (buf + strlen(buf)) : "a4");
+ asm("jmp %0@" : : "a" (entry));
+}
--- /dev/null
+/*
+ * 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 __P((const void *, void *, size_t)); /* libc_sa */
+void *memset __P((void *, int, size_t)); /* libc_sa */
+int printf __P((const char *, ...)); /* libc_sa */
+
+/* console */
+void puts __P((char *));
+void putchar __P((char));
+char cngetc __P((void));
+void ngets __P((char *, int));
+
+/* sboot */
+void callrom __P((void));
+void do_cmd __P((char *));
+
+/* le */
+#define LANCE_ADDR 0xfffe0778
+#define ERAM_ADDR 0xfffe0774
+#define LANCE_REG_ADDR 0xfffe1800
+void le_end __P((void));
+void le_init __P((void));
+int le_get __P((u_char *, size_t, u_long));
+int le_put __P((u_char *, size_t));
+
+/* etherfun */
+#define READ 0
+#define ACKN 1
+void do_rev_arp __P((void));
+int get_rev_arp __P((void));
+int rev_arp __P((void));
+void do_send_tftp __P((int));
+int do_get_file __P((void));
+void tftp_file __P((char *, u_long));
+
+/* clock */
+u_long time __P((void));
+
+/* checksum */
+u_long oc_cksum __P((void *, u_long, u_long));
+
+#define CONS_ZS_ADDR (0xfffe3002)
+#define CLOCK_ADDR (0xfffe07f8)
+#define LOAD_ADDR 0x7000
+
+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;
--- /dev/null
+/*
+ * Public domain, believed to be by Mike Price.
+ *
+ * convert binary file to Srecord format
+ * XXX srec generates improper checksums for 4-byte dumps
+ */
+#include <stdio.h>
+#include <ctype.h>
+
+int get32();
+void put32();
+void sput();
+void put();
+int checksum();
+
+int mask;
+int size;
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char buf[32];
+ int cc;
+ int base;
+ int addr;
+ char *name;
+
+ if (argc != 4) {
+ fprintf(stderr, "usage: %s {size} {hex_addr} {name}\n", argv[0]);
+ fprintf(stderr, "Size = 2, 3, or 4 byte address\n");
+ exit(1);
+ }
+ sscanf(argv[1], "%x", &size);
+ mask = (1 << (size * 8)) - 1;
+ if (!mask)
+ mask = (-1);
+ sscanf(argv[2], "%x", &base);
+ name = argv[3];
+
+ if (size == 2)
+ printf("S0%02X%04X", 2 + strlen(name) + 1, 0);
+ if (size == 3)
+ printf("S0%02X%06X", 3 + strlen(name) + 1, 0);
+ if (size == 4)
+ printf("S0%02X%08X", 4 + strlen(name) + 1, 0);
+ sput(name);
+ printf("%02X\n", checksum(0, name, strlen(name), size));
+
+ addr = base;
+ for (;;) {
+ cc = get32(buf);
+ if (cc > 0) {
+ put32(cc, addr, buf, size, mask);
+ addr += cc;
+ } else
+ break;
+ }
+
+ buf[0] = base >> 8;
+ buf[1] = base;
+ printf("S%d%02X", 11 - size, 2 + 1);
+ switch (size) {
+ case 2:
+ printf("%04X", base & mask);
+ break;
+ case 3:
+ printf("%06X", base & mask);
+ break;
+ case 4:
+ printf("%08X", base & mask);
+ break;
+ }
+
+ /*
+ * kludge -> don't know why you have to add the +1 = works
+ * for size =3 at least
+ */
+ printf("%02X\n", checksum(base, (char *) 0, 0, size) + 1);
+ exit (0);
+}
+
+int
+get32(buf)
+ char buf[];
+{
+ char *cp = buf;
+ int i;
+ int c;
+
+ for (i = 0; i < 32; ++i) {
+ if ((c = getchar()) != EOF)
+ *cp++ = c;
+ else
+ break;
+ }
+ return (cp - buf);
+}
+
+void
+put32(len, addr, buf, size, mask)
+ int len;
+ int addr;
+ char buf[];
+ int size, mask;
+{
+ char *cp = buf;
+ int i;
+
+ if (size == 2)
+ printf("S1%02X%04X", 2 + len + 1, addr & mask);
+ if (size == 3)
+ printf("S2%02X%06X", 3 + len + 1, addr & mask);
+ if (size == 4)
+ printf("S3%02X%08X", 4 + len + 1, addr & mask);
+ for (i = 0; i < len; ++i)
+ put(*cp++);
+ printf("%02X\n", checksum(addr, buf, len, size));
+}
+
+void
+sput(s)
+ char *s;
+{
+ while (*s != '\0')
+ put(*s++);
+}
+
+void
+put(c)
+ int c;
+{
+ printf("%02X", c & 0xff);
+}
+
+int
+checksum(addr, buf, len, size)
+ int addr;
+ char buf[];
+ int len;
+ int size;
+{
+ char *cp = buf;
+ int sum = 0xff - 1 - size - (len & 0xff);
+ int i;
+
+ if (size == 4)
+ sum -= (addr >> 24) & 0xff;
+ if (size >= 3)
+ sum -= (addr >> 16) & 0xff;
+ sum -= (addr >> 8) & 0xff;
+ sum -= addr & 0xff;
+ for (i = 0; i < len; ++i) {
+ sum -= *cp++ & 0xff;
+ }
+ return (sum & 0xff);
+}
--- /dev/null
+PROG= wrtvid
+NOMAN=
+
+install:
+
+.include <bsd.prog.mk>
--- /dev/null
+head 1.1;
+access;
+symbols;
+locks
+ drahn:1.1; strict;
+comment @# @;
+
+
+1.1
+date 95.09.28.19.00.28; author drahn; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@PROG= wrtvid
+NOMAN=
+
+install:
+
+.include <bsd.prog.mk>
+@
--- /dev/null
+WRTVID_BASE_DIR=${S}/arch/${MACHINE}/stand/wrtvid
+
+WRTVID_DIR!= cd ${WRTVID_BASE_DIR}; \
+ printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx
+
+WRTVID=${WRTVID_DIR}/wrtvid
+
+$(WRTVID): .NOTMAIN __always_make_WRTVID
+ @echo making sure the wrtvid is up to date...
+ @(cd ${WRTVID_BASE_DIR}; ${MAKE})
+
+__always_make_WRTVID: .NOTMAIN
--- /dev/null
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#define __DBINTERFACE_PRIVATE
+#include <db.h>
+#include <machine/disklabel.h>
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct cpu_disklabel *pcpul;
+ struct stat stat;
+ int exe_file;
+ int tape_vid;
+ int tape_exe;
+ unsigned int exe_addr;
+ unsigned short exe_addr_u;
+ unsigned short exe_addr_l;
+ char *filename;
+ char fileext[256];
+ char filebase[256];
+
+ if (argc == 0)
+ filename = "a.out";
+ else
+ filename = argv[1];
+
+ exe_file = open(filename, O_RDONLY,0444);
+ if (exe_file == -1) {
+ perror(filename);
+ exit(2);
+ }
+ sprintf(fileext, "%c%cboot", filename[4], filename[5]);
+ tape_vid = open(fileext, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ sprintf(fileext, "boot%c%c", filename[4], filename[5]);
+ tape_exe = open(fileext, O_WRONLY|O_CREAT|O_TRUNC,0644);
+
+ pcpul = (struct cpu_disklabel *)malloc(sizeof(struct cpu_disklabel));
+ bzero(pcpul, sizeof(struct cpu_disklabel));
+
+ pcpul->version = 1;
+ strcpy(pcpul->vid_id, "NBSD");
+
+ fstat(exe_file, &stat);
+ /* size in 256 byte blocks round up after a.out header removed */
+
+ if (filename[5] == 't' ) {
+ pcpul->vid_oss = 1;
+ }else {
+ pcpul->vid_oss = 2;
+ }
+ pcpul->vid_osl = (((stat.st_size -0x20) +511) / 512) *2;
+
+ lseek(exe_file, 0x14, SEEK_SET);
+ read(exe_file, &exe_addr, 4);
+
+ /* check this, it may not work in both endian. */
+ {
+ union {
+ struct s {
+ unsigned short s1;
+ unsigned short s2;
+ } s;
+ unsigned long l;
+ } a;
+ a.l = exe_addr;
+ pcpul->vid_osa_u = a.s.s1;
+ pcpul->vid_osa_l = a.s.s2;
+
+ }
+ pcpul->vid_cas = 1;
+ pcpul->vid_cal = 1;
+ /* do not want to write past end of structure, not null terminated */
+ strncpy(pcpul->vid_mot, "MOTOROLA", 8);
+
+ if (BYTE_ORDER != BIG_ENDIAN)
+ swabvid(pcpul);
+
+ pcpul->cfg_rec = 0x100;
+ pcpul->cfg_psm = 0x200;
+
+ if (BYTE_ORDER != BIG_ENDIAN)
+ swabcfg(pcpul);
+
+ write(tape_vid, pcpul, sizeof(struct cpu_disklabel));
+
+ free(pcpul);
+
+ copy_exe(exe_file, tape_exe);
+ close(exe_file);
+ close(tape_vid);
+ close(tape_exe);
+ return (0);
+}
+
+#define BUF_SIZ 512
+copy_exe(exe_file, tape_exe)
+ int exe_file, tape_exe;
+{
+ char *buf;
+ int cnt = 0;
+
+ buf = (char *)malloc(BUF_SIZ);
+
+ lseek (exe_file, 0x20, SEEK_SET);
+ while (BUF_SIZ == (cnt = read(exe_file, buf, BUF_SIZ))) {
+ write(tape_exe, buf, cnt);
+ }
+ bzero(&buf[cnt], BUF_SIZ-cnt);
+ write(tape_exe, buf, BUF_SIZ);
+}
+
+swabvid(pcpul)
+ struct cpu_disklabel *pcpul;
+{
+ M_32_SWAP(pcpul->vid_oss);
+ M_16_SWAP(pcpul->vid_osl);
+ /*
+ M_16_SWAP(pcpul->vid_osa_u);
+ M_16_SWAP(pcpul->vid_osa_l);
+ */
+ M_32_SWAP(pcpul->vid_cas);
+}
+
+swabcfg(pcpul)
+ struct cpu_disklabel *pcpul;
+{
+ M_16_SWAP(pcpul->cfg_atm);
+ M_16_SWAP(pcpul->cfg_prm);
+ M_16_SWAP(pcpul->cfg_atm);
+ M_16_SWAP(pcpul->cfg_rec);
+ M_16_SWAP(pcpul->cfg_trk);
+ M_16_SWAP(pcpul->cfg_psm);
+ M_16_SWAP(pcpul->cfg_shd);
+ M_16_SWAP(pcpul->cfg_pcom);
+ M_16_SWAP(pcpul->cfg_rwcc);
+ M_16_SWAP(pcpul->cfg_ecc);
+ M_16_SWAP(pcpul->cfg_eatm);
+ M_16_SWAP(pcpul->cfg_eprm);
+ M_16_SWAP(pcpul->cfg_eatw);
+ M_16_SWAP(pcpul->cfg_rsvc1);
+ M_16_SWAP(pcpul->cfg_rsvc2);
+}