summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authornisimura <nisimura@NetBSD.org>2000-01-05 08:48:53 +0000
committernisimura <nisimura@NetBSD.org>2000-01-05 08:48:53 +0000
commit95d00ea75d53c2f18b36eaa2bb7f5bf4ce38b733 (patch)
tree5ffef25ee0d0d225561ab8b8b61c40a1507d65de /sys
parente7552e93d728e62c90c4b413dd4e86eb0293b4fa (diff)
Introduce NetBSD/luna68k port into CVS repository.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/luna68k/Makefile31
-rw-r--r--sys/arch/luna68k/conf/GENERIC150
-rw-r--r--sys/arch/luna68k/conf/Makefile.luna68k199
-rw-r--r--sys/arch/luna68k/conf/files.luna68k67
-rw-r--r--sys/arch/luna68k/conf/std.luna68k10
-rw-r--r--sys/arch/luna68k/dev/if_le.c236
-rw-r--r--sys/arch/luna68k/dev/lcd.c170
-rw-r--r--sys/arch/luna68k/dev/lunafb.c495
-rw-r--r--sys/arch/luna68k/dev/lunaws.c465
-rw-r--r--sys/arch/luna68k/dev/md_root.c91
-rw-r--r--sys/arch/luna68k/dev/omrasops.c518
-rw-r--r--sys/arch/luna68k/dev/sio.c131
-rw-r--r--sys/arch/luna68k/dev/sioreg.h136
-rw-r--r--sys/arch/luna68k/dev/siotty.c623
-rw-r--r--sys/arch/luna68k/dev/siovar.h59
-rw-r--r--sys/arch/luna68k/dev/spc.c104
-rw-r--r--sys/arch/luna68k/dev/timekeeper.c248
-rw-r--r--sys/arch/luna68k/dev/timekeeper.h95
-rw-r--r--sys/arch/luna68k/include/Makefile12
-rw-r--r--sys/arch/luna68k/include/ansi.h4
-rw-r--r--sys/arch/luna68k/include/aout_machdep.h8
-rw-r--r--sys/arch/luna68k/include/asm.h3
-rw-r--r--sys/arch/luna68k/include/autoconf.h43
-rw-r--r--sys/arch/luna68k/include/bswap.h3
-rw-r--r--sys/arch/luna68k/include/bus.h604
-rw-r--r--sys/arch/luna68k/include/cdefs.h8
-rw-r--r--sys/arch/luna68k/include/cpu.h179
-rw-r--r--sys/arch/luna68k/include/db_machdep.h4
-rw-r--r--sys/arch/luna68k/include/disklabel.h57
-rw-r--r--sys/arch/luna68k/include/endian.h4
-rw-r--r--sys/arch/luna68k/include/float.h8
-rw-r--r--sys/arch/luna68k/include/frame.h3
-rw-r--r--sys/arch/luna68k/include/ieee.h3
-rw-r--r--sys/arch/luna68k/include/ieeefp.h4
-rw-r--r--sys/arch/luna68k/include/intr.h68
-rw-r--r--sys/arch/luna68k/include/kcore.h8
-rw-r--r--sys/arch/luna68k/include/limits.h9
-rw-r--r--sys/arch/luna68k/include/math.h3
-rw-r--r--sys/arch/luna68k/include/param.h81
-rw-r--r--sys/arch/luna68k/include/pcb.h3
-rw-r--r--sys/arch/luna68k/include/pmap.h150
-rw-r--r--sys/arch/luna68k/include/proc.h53
-rw-r--r--sys/arch/luna68k/include/profile.h3
-rw-r--r--sys/arch/luna68k/include/psl.h3
-rw-r--r--sys/arch/luna68k/include/pte.h152
-rw-r--r--sys/arch/luna68k/include/ptrace.h4
-rw-r--r--sys/arch/luna68k/include/reg.h8
-rw-r--r--sys/arch/luna68k/include/setjmp.h3
-rw-r--r--sys/arch/luna68k/include/signal.h4
-rw-r--r--sys/arch/luna68k/include/stdarg.h4
-rw-r--r--sys/arch/luna68k/include/trap.h3
-rw-r--r--sys/arch/luna68k/include/types.h8
-rw-r--r--sys/arch/luna68k/include/varargs.h4
-rw-r--r--sys/arch/luna68k/include/vmparam.h142
-rw-r--r--sys/arch/luna68k/luna68k/autoconf.c116
-rw-r--r--sys/arch/luna68k/luna68k/clock.c222
-rw-r--r--sys/arch/luna68k/luna68k/clockvar.h53
-rw-r--r--sys/arch/luna68k/luna68k/conf.c257
-rw-r--r--sys/arch/luna68k/luna68k/db_memrw.c230
-rw-r--r--sys/arch/luna68k/luna68k/disksubr.c487
-rw-r--r--sys/arch/luna68k/luna68k/genassym.cf205
-rw-r--r--sys/arch/luna68k/luna68k/isr.c356
-rw-r--r--sys/arch/luna68k/luna68k/isr.h92
-rw-r--r--sys/arch/luna68k/luna68k/locore.s1427
-rw-r--r--sys/arch/luna68k/luna68k/machdep.c991
-rw-r--r--sys/arch/luna68k/luna68k/mainbus.c109
-rw-r--r--sys/arch/luna68k/luna68k/mem.c232
-rw-r--r--sys/arch/luna68k/luna68k/pmap.c2520
-rw-r--r--sys/arch/luna68k/luna68k/pmap_bootstrap.c474
-rw-r--r--sys/arch/luna68k/luna68k/sys_machdep.c310
-rw-r--r--sys/arch/luna68k/luna68k/trap.c1062
-rw-r--r--sys/arch/luna68k/luna68k/vectors.s134
-rw-r--r--sys/arch/luna68k/luna68k/vm_machdep.c374
73 files changed, 15139 insertions, 0 deletions
diff --git a/sys/arch/luna68k/Makefile b/sys/arch/luna68k/Makefile
new file mode 100644
index 00000000000..ee8175b68e2
--- /dev/null
+++ b/sys/arch/luna68k/Makefile
@@ -0,0 +1,31 @@
+# $NetBSD: Makefile,v 1.1 2000/01/05 08:48:53 nisimura Exp $
+
+# Makefile for luna68k tags file
+
+# Find where mips source files are for inclusion in tags
+.include <../m68k/Makefile.inc>
+
+TLUNA68K= ../luna68k/tags
+SLUNA68K= ../luna68k/luna68k/*.[ch] ../luna68k/include/*.h \
+ ../luna68k/dev/*.[ch]
+ALUNA68K= ../luna68k/luna68k/*.s
+
+# Directories in which to place tags links
+DLUNA68K= dev include
+
+.include "../../kern/Make.tags.inc"
+
+tags:
+ -ctags -wdtf ${TLUNA68K} ${SLUNA68K} ${COMM}
+ egrep "^ENTRY(.*)|^ALTENTRY(.*)" ${ALUNA68K} | \
+ sed "s;\([^:]*\):\([^(]*\)(\([^, )]*\)\(.*\);\3 \1 /^\2(\3\4$$/;" \
+ >> ${TLUNA68K}
+ sort -o ${TLUNA68K} ${TLUNA68K}
+
+links:
+ -for i in ${DLUNA68K}; do \
+ cd $$i && rm -f tags; ln -s ../tags tags; done
+
+SUBDIR= include
+
+.include <bsd.subdir.mk>
diff --git a/sys/arch/luna68k/conf/GENERIC b/sys/arch/luna68k/conf/GENERIC
new file mode 100644
index 00000000000..e82c84ebc39
--- /dev/null
+++ b/sys/arch/luna68k/conf/GENERIC
@@ -0,0 +1,150 @@
+# $NetBSD: GENERIC,v 1.1 2000/01/05 08:48:54 nisimura Exp $
+#
+# GENERIC LUNA68K
+#
+include "arch/luna68k/conf/std.luna68k"
+
+maxusers 8
+
+options M68030
+#options M68040
+#options FPSP # on m68040 to emulate some missing FP instructions
+
+# Needs to be set per system. i.e change these as you see fit
+
+# Standard system options
+options NTP # NTP phase/frequency locked loop
+options KTRACE
+#options SYSVMSG # System V message queues
+#options SYSVSEM # System V semaphores
+#options SYSVSHM # System V shared memory
+#optoins SHMMAXPGS=1024 # 1024 pages is the default
+#options LKM # loadable kernel modules
+#options NKMEMCLUSTERS=1024 # 4K pages in kernel malloc pool
+#options UCONSOLE # users can redirect console (unsafe)
+
+# Debugging options
+options DDB
+#options DDB_HISTORY_SIZE=100 # enable history editing in DDB
+#options SYMTAB_SPACE=72000 # place DDB symbols in data segment
+options DEBUG # extra kernel debugging support
+options DIAGNOSTIC # extra kernel sanity checking
+options SCSIVERBOSE # Verbose SCSI errors
+options SCSIDEBUG
+#makeoptions DEBUG="-g" # compile full symbol table
+
+# Compatability options
+options COMPAT_43 # and 4.3BSD and ...
+options COMPAT_12 # NetBSD 1.2 binary compatibility
+options COMPAT_13 # NetBSD 1.3 binary compatibility
+options COMPAT_14 # NetBSD 1.4 binary compatibility
+
+# Filesystem options
+file-system FFS # ufs file system
+#file-system LFS # log-structured file system
+file-system NFS # nfs client support
+file-system MFS
+#file-system CD9660 # ISO 9660 + Rock Ridge file system
+#file-system MSDOSFS # MS-DOS FAT file system
+file-system KERNFS # /kern
+file-system PROCFS # /proc
+#file-system FDESC # /dev/fd/*
+file-system NULLFS # loopback file system
+#file-system PORTAL # portal filesystem (still experimental)
+#file-system UMAPFS # NULLFS + uid and gid remapping
+#file-system UNION # union file system
+#file-system CODA # Coda File System; also needs vcode (below)
+
+#options NFSSERVER # nfs server support
+#options QUOTA # ffs quotas
+#options FFS_EI # ffs endian independant support
+#options SOFTDEP # ffs soft updates support
+
+# Pull in config fragments for kernel crypto. This is required for
+# options IPSEC etc. to work. If you want to run with IPSEC, uncomment
+# one of these, based on whether you use crypto-us or crypto-intl, and
+# adjust the prefixes as necessary.
+
+#prefix ../crypto-us/sys
+#cinclude "conf/files.crypto-us"
+#prefix
+
+#prefix ../crypto-intl/sys
+#cinclude "conf/files.crypto-intl"
+#prefix
+
+# Networking options
+options INET # IP prototol stack support
+#options INET6 # IPV6
+#options IPSEC # IP security
+#options IPSEC_ESP # IP securyty (encryption part; define w/IPSEC)
+#options IPSEC_DEBUG # debug for IP security
+#options GATEWAY # IP packet forwarding
+#options MROUTING # IP multicast routing
+#options TCP_COMPAT_42 # TCP bug compatibility with 4.2BSD
+#options NS # XNS
+#options NSIP # XNS tunneling over IP
+#options ISO,TPIP # OSI
+#options EON # OSI tunneling over IP
+#options CCITT,LLC,HDLC # X.25
+#options NETATALK # AppleTalk networking protocols
+#options PPP_BSDCOMP # BSD-Compress compression support for PPP
+#options PPP_DEFLATE # Deflate compression support for PPP
+#options PPP_FILTER # Active filter support for PPP (requires bpf)
+#options PFIL_HOOKS # pfil(9) packet filter hooks
+#options IPFILTER_LOG # ipmon(8) log support
+options NFS_BOOT_DHCP # superset of BOOTP
+
+# WS console uses SUN or VT100 terminal emulation
+options WSEMUL_VT100
+
+config netbsd root on ? type nfs
+
+mainbus0 at root
+
+clock0 at mainbus0
+
+# uPD7201 SIO
+sio0 at mainbus0
+siotty0 at sio0 # ttya
+ws0 at sio0 # port for keyboard and mouse
+# AM7990 LANCE
+le0 at mainbus0
+# MB89532 SPC
+spc0 at mainbus0
+#spc1 at mainbus0 # 2nd SCSI on LUNA-II
+# framebuffer
+fb0 at mainbus0 # 16 or 256 pseudo color
+
+# Workstation Console attachments
+wsdisplay* at fb?
+wskbd* at ws? console ?
+#wsmouse* at ws? # not supported, yet...
+
+# SCSI bus support
+scsibus* at spc?
+
+# SCSI devices
+sd* at scsibus? target ? lun ? # SCSI disks
+st* at scsibus? target ? lun ? # SCSI tapes
+#cd* at scsibus? target ? lun ? # SCSI CD-ROMs
+#ch* at scsibus? target ? lun ? # SCSI changer devices
+#ss* at scsibus? target ? lun ? # SCSI scanners
+#uk* at scsibus? target ? lun ? # unknown SCSI devices
+
+pseudo-device bpfilter 2 # Berkeley Packet Filter
+#pseudo-device ccd 2 # concatenated and striped disks
+#pseudo-device gre 2 # generic L3 over IP tunnel
+#pseudo-device ipfilter 1 # ip filter
+pseudo-device loop 1 # loopback interface; required
+pseudo-device md 1 # memory disk device
+#pseudo-device ppp 1 # PPP interfaces
+pseudo-device pty 32 # pseudo-terminals
+#pseudo-device raid 2 # RAIDframe disk driver
+#pseudo-device sl 1 # SLIP interfaces
+#pseudo-device tun 2 # Network "tunnel" device
+#pseudo-device vnd 2 # disk-like interface to files
+
+# rnd is EXPERIMENTAL
+#pseudo-device rnd # /dev/random and in-kernel generator
+#options RND_COM # use "com" randomness too
diff --git a/sys/arch/luna68k/conf/Makefile.luna68k b/sys/arch/luna68k/conf/Makefile.luna68k
new file mode 100644
index 00000000000..aa46085a2ce
--- /dev/null
+++ b/sys/arch/luna68k/conf/Makefile.luna68k
@@ -0,0 +1,199 @@
+# $NetBSD: Makefile.luna68k,v 1.1 2000/01/05 08:48:54 nisimura 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/luna68k/conf/``machineid''
+# after which you should do
+# config machineid
+# Machine generic makefile changes should be made in
+# /sys/arch/luna68k/conf/Makefile.luna68k
+# 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 if debugging.
+# PROF is set to -pg if profiling.
+
+AR?= ar
+AS?= as
+CC?= cc
+CPP?= cpp
+LD?= ld
+LORDER?=lorder
+MKDEP?= mkdep
+NM?= nm
+RANLIB?=ranlib
+SIZE?= size
+STRIP?= strip
+TSORT?= tsort -q
+OBJCOPY?= objcopy
+
+COPTS?= -O2
+
+# source tree is located via $S relative to the compilation directory
+.ifndef S
+S!= cd ../../../..; pwd
+.endif
+LUNA68K=$S/arch/luna68k
+
+# Override CPP defaults entirely, so cross-compilation works.
+# Keep -nostdinc before all -I flags, similar for -undef ...
+HAVE_GCC28!= ${CC} --version | egrep "^(2\.8|egcs)" ; echo
+INCLUDES= -nostdinc -I. -I$S/arch -I$S
+CPPFLAGS= ${INCLUDES} ${IDENT} ${PARAM} -D_KERNEL -Dluna68k
+CWARNFLAGS?= -Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes
+.if (${HAVE_GCC28} != "")
+CWARNFLAGS+= -Wno-main
+.endif
+CFLAGS= ${DEBUG} ${COPTS} ${CWARNFLAGS} -msoft-float
+AFLAGS= -x assembler-with-cpp -traditional-cpp -D_LOCORE
+LINKFLAGS= -N -Ttext 0xc000 -e start
+STRIPFLAGS= -d
+
+%INCLUDES
+
+HOSTED_CC= ${CC}
+HOSTED_CPPFLAGS=${CPPFLAGS:S/^-nostdinc$//}
+HOSTED_CFLAGS= ${CFLAGS}
+
+### 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
+
+### for the Motorola 68040 Floating Point Software Product
+# .include "$S/arch/m68k/fpsp/Makefile.inc"
+
+# compile rules: rules are named ${TYPE}_${SUFFIX} where TYPE is NORMAL or
+# HOSTED}, and SUFFIX is the file suffix, capitalized (e.g. C for a .c file).
+
+NORMAL_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $<
+NOPROF_C= ${CC} ${CFLAGS} ${CPPFLAGS} -c $<
+NORMAL_S= ${CC} ${AFLAGS} ${CPPFLAGS} -c $<
+
+HOSTED_C= ${HOSTED_CC} ${HOSTED_CFLAGS} ${HOSTED_CPPFLAGS} -c $<
+
+%OBJS
+
+%CFILES
+
+%SFILES
+
+# load lines for config "xxx" will be emitted as:
+# xxx: ${SYSTEM_DEP} swapxxx.o
+# ${SYSTEM_LD_HEAD}
+# ${SYSTEM_LD} swapxxx.o
+# ${SYSTEM_LD_TAIL}
+SYSTEM_OBJ= locore.o ${FPSP} \
+ param.o ioconf.o ${OBJS} ${LIBCOMPAT} ${LIBKERN}
+SYSTEM_DEP= Makefile ${SYSTEM_OBJ}
+SYSTEM_LD_HEAD= @rm -f $@
+SYSTEM_LD= @echo ${LD} ${LINKFLAGS} -o $@ '$${SYSTEM_OBJ}' vers.o; \
+ ${LD} ${LINKFLAGS} -o $@ ${SYSTEM_OBJ} vers.o
+SYSTEM_LD_TAIL= @${SIZE} $@; chmod 755 $@
+
+DEBUG?=
+.if ${DEBUG} == "-g"
+LINKFLAGS+= -X
+SYSTEM_LD_TAIL+=; \
+ echo mv -f $@ $@.gdb; mv -f $@ $@.gdb; \
+ echo ${STRIP} ${STRIPFLAGS} -o $@ $@.gdb; \
+ ${STRIP} ${STRIPFLAGS} -o $@ $@.gdb
+.else
+LINKFLAGS+= -S
+.endif
+
+%LOAD
+
+assym.h: $S/kern/genassym.sh ${LUNA68K}/luna68k/genassym.cf
+ sh $S/kern/genassym.sh ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} \
+ < ${LUNA68K}/luna68k/genassym.cf > assym.h.tmp && \
+ mv -f assym.h.tmp assym.h
+
+param.c: $S/conf/param.c
+ rm -f param.c
+ cp $S/conf/param.c .
+
+param.o: param.c Makefile
+ ${NORMAL_C}
+
+ioconf.o: ioconf.c
+ ${NORMAL_C}
+
+newvers: ${SYSTEM_DEP} ${SYSTEM_SWAP_DEP}
+ sh $S/conf/newvers.sh
+ ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c vers.c
+
+__CLEANKERNEL: .USE
+ @echo "${.TARGET}ing the kernel objects"
+ rm -f eddep *netbsd netbsd.gdb tags *.[io] [a-z]*.s \
+ [Ee]rrs linterrs makelinks assym.h.tmp assym.h
+
+__CLEANDEPEND: .USE
+ rm -f .depend
+
+clean: __CLEANKERNEL
+
+cleandir distclean: __CLEANKERNEL __CLEANDEPEND
+
+lint:
+ @lint -hbxncez -Dvolatile= ${CPPFLAGS} -UKGDB \
+ ${CFILES} ioconf.c param.c | \
+ grep -v 'static function .* unused'
+
+tags:
+ @echo "see $S/kern/Makefile for tags"
+
+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
+
+SRCS= ${LUNA68K}/luna68k/locore.s \
+ param.c ioconf.c ${CFILES} ${SFILES}
+depend: .depend
+.depend: ${SRCS} assym.h param.c
+ ${MKDEP} ${AFLAGS} ${CPPFLAGS} ${LUNA68K}/luna68k/locore.s
+ ${MKDEP} -a ${CFLAGS} ${CPPFLAGS} param.c ioconf.c ${CFILES}
+ sh $S/kern/genassym.sh ${MKDEP} -f assym.dep ${CFLAGS} \
+ ${CPPFLAGS} < ${LUNA68K}/luna68k/genassym.cf
+ @sed -e 's/.*\.o:.*\.c/assym.h:/' < assym.dep >> .depend
+ @rm -f assym.dep
+
+# depend on root or device configuration
+autoconf.o conf.o: Makefile
+
+# depend on network or filesystem configuration
+uipc_proto.o vfs_conf.o: Makefile
+
+# depend on maxusers
+machdep.o: Makefile
+
+# depend on CPU configuration
+machdep.c trap.o: Makefile
+
+locore.o: ${LUNA68K}/luna68k/locore.s assym.h
+ ${NORMAL_S}
+
+%RULES
diff --git a/sys/arch/luna68k/conf/files.luna68k b/sys/arch/luna68k/conf/files.luna68k
new file mode 100644
index 00000000000..4356510b659
--- /dev/null
+++ b/sys/arch/luna68k/conf/files.luna68k
@@ -0,0 +1,67 @@
+#
+# $NetBSD: files.luna68k,v 1.1 2000/01/05 08:48:54 nisimura Exp $
+#
+maxpartitions 8
+maxusers 2 8 64
+
+file arch/luna68k/luna68k/autoconf.c
+file arch/luna68k/luna68k/clock.c
+file arch/luna68k/luna68k/conf.c
+file arch/luna68k/luna68k/db_memrw.c ddb | kgdb
+file arch/luna68k/luna68k/disksubr.c
+file arch/luna68k/luna68k/isr.c
+file arch/luna68k/luna68k/machdep.c
+file arch/luna68k/luna68k/mem.c
+file arch/luna68k/luna68k/pmap.c
+file arch/luna68k/luna68k/pmap_bootstrap.c
+file arch/luna68k/luna68k/sys_machdep.c
+file arch/luna68k/luna68k/trap.c
+file arch/luna68k/luna68k/vm_machdep.c
+file arch/m68k/m68k/cacheops.c
+file dev/clock_subr.c
+file dev/cons.c
+file arch/luna68k/dev/lcd.c
+
+device mainbus {}
+attach mainbus at root
+file arch/luna68k/luna68k/mainbus.c
+
+device clock
+attach clock at mainbus
+file arch/luna68k/dev/timekeeper.c clock
+
+attach le at mainbus: le24
+file arch/luna68k/dev/if_le.c le
+
+device sio { [channel = -1] }
+attach sio at mainbus
+file arch/luna68k/dev/sio.c sio
+
+device siotty: tty
+attach siotty at sio
+file arch/luna68k/dev/siotty.c siotty needs-flag
+device ws: wskbddev,wsmousedev
+attach ws at sio
+file arch/luna68k/dev/lunaws.c ws
+
+device fb: wsemuldisplaydev
+attach fb at mainbus
+file arch/luna68k/dev/lunafb.c fb
+file arch/luna68k/dev/omrasops.c fb
+
+device spc: scsi
+attach spc at mainbus
+file arch/luna68k/dev/spc.c spc
+file dev/ic/mb89352.c spc
+
+# Machine-idependent SCSI driver.
+include "dev/scsipi/files.scsipi"
+major {sd = 2} # SCSI disk
+major {cd = 4} # SCSI CD-ROM
+
+# Memory Disk for boot tape
+file arch/luna68k/dev/md_root.c memory_disk_hooks
+major {md = 7} # Memory disk (for mini-kernel)
+
+# "Workstation Console" glue.
+include "dev/wscons/files.wscons"
diff --git a/sys/arch/luna68k/conf/std.luna68k b/sys/arch/luna68k/conf/std.luna68k
new file mode 100644
index 00000000000..1763e2ae954
--- /dev/null
+++ b/sys/arch/luna68k/conf/std.luna68k
@@ -0,0 +1,10 @@
+# $NetBSD: std.luna68k,v 1.1 2000/01/05 08:48:54 nisimura Exp $
+
+machine luna68k m68k
+
+prefix ../gnu/sys
+cinclude "conf/files.softdep"
+prefix
+
+options EXEC_AOUT # exec a.out binaries
+options EXEC_SCRIPT # exec #! scripts
diff --git a/sys/arch/luna68k/dev/if_le.c b/sys/arch/luna68k/dev/if_le.c
new file mode 100644
index 00000000000..67b615805ed
--- /dev/null
+++ b/sys/arch/luna68k/dev/if_le.c
@@ -0,0 +1,236 @@
+/* $NetBSD: if_le.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 1995 Charles M. Hannum. All rights reserved.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell and Rick Macklem.
+ *
+ * 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_le.c 8.2 (Berkeley) 11/16/93
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: if_le.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $");
+
+#include "opt_inet.h"
+#include "bpfilter.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/device.h>
+
+#include <net/if.h>
+#include <net/if_ether.h>
+#include <net/if_media.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/if_inarp.h>
+#endif
+
+#include <machine/cpu.h>
+#include <machine/autoconf.h>
+
+#include <luna68k/luna68k/isr.h>
+
+#include <dev/ic/lancereg.h>
+#include <dev/ic/lancevar.h>
+#include <dev/ic/am7990reg.h>
+#include <dev/ic/am7990var.h>
+
+/*
+ * LANCE registers.
+ */
+struct lereg1 {
+ volatile u_int16_t ler1_rdp; /* data port */
+ volatile u_int16_t ler1_rap; /* register select port */
+};
+
+/*
+ * Ethernet software status per interface.
+ *
+ * Each interface is referenced by a network interface structure,
+ * arpcom.ac_if, which the routing code uses to locate the interface.
+ * This structure contains the output queue for the interface, its address, ...
+ */
+struct le_softc {
+ struct am7990_softc sc_am7990; /* glue to MI code */
+
+ struct lereg1 *sc_r1; /* LANCE registers */
+};
+
+static int le_match __P((struct device *, struct cfdata *, void *));
+static void le_attach __P((struct device *, struct device *, void *));
+
+const struct cfattach le_ca = {
+ sizeof(struct le_softc), le_match, le_attach
+};
+extern struct cfdriver le_cd;
+
+static void lesrcsr __P((struct lance_softc *, u_int16_t, u_int16_t));
+static u_int16_t lerdcsr __P((struct lance_softc *, u_int16_t));
+static void myetheraddr __P((u_int8_t *));
+
+static void
+lesrcsr(sc, port, val)
+ struct lance_softc *sc;
+ u_int16_t port, val;
+{
+ struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1;
+
+ ler1->ler1_rap = port;
+ ler1->ler1_rdp = val;
+}
+
+static u_int16_t
+lerdcsr(sc, port)
+ struct lance_softc *sc;
+ u_int16_t port;
+{
+ struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1;
+ u_int16_t val;
+
+ ler1->ler1_rap = port;
+ val = ler1->ler1_rdp;
+ return (val);
+}
+
+static int
+le_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct mainbus_attach_args *ma = aux;
+
+ if (strcmp(ma->ma_name, le_cd.cd_name))
+ return (0);
+
+ return (1);
+}
+
+void
+le_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct le_softc *lesc = (void *)self;
+ struct lance_softc *sc = &lesc->sc_am7990.lsc;
+ struct mainbus_attach_args *ma = aux;
+
+ /* Map control registers. */
+ lesc->sc_r1 = (struct lereg1 *)ma->ma_addr; /* LANCE */
+
+ sc->sc_mem = (void *)0x71010000; /* SRAM */
+ sc->sc_conf3 = LE_C3_BSWP;
+ sc->sc_addr = (u_long)sc->sc_mem & 0xffffff;
+ sc->sc_memsize = 64 * 1024; /* 64KB */
+
+ myetheraddr(sc->sc_enaddr);
+
+ sc->sc_copytodesc = lance_copytobuf_contig;
+ sc->sc_copyfromdesc = lance_copyfrombuf_contig;
+ sc->sc_copytobuf = lance_copytobuf_contig;
+ sc->sc_copyfrombuf = lance_copyfrombuf_contig;
+ sc->sc_zerobuf = lance_zerobuf_contig;
+
+ sc->sc_rdcsr = lerdcsr;
+ sc->sc_wrcsr = lesrcsr;
+ sc->sc_hwinit = NULL;
+
+ am7990_config(&lesc->sc_am7990);
+
+ isrlink_autovec(am7990_intr, (void *)sc, ma->ma_ilvl, ISRPRI_NET);
+}
+
+/*
+ * LUNA-I has 1Mbit CPU ROM, which contains MAC address directly
+ * readable at 0x4100FFE0 as a sequence of 12 ASCII characters.
+ *
+ * LUNA-II has 16Kbit NVSRAM on its ethercard, whose contents are
+ * accessible 4bit-wise by ctl register operation. The register is
+ * mapped at 0xF1000004.
+ */
+void
+myetheraddr(ether)
+ u_int8_t *ether;
+{
+ unsigned i, loc;
+ u_int8_t *ea;
+ volatile struct { u_int32_t ctl; } *ds1220;
+
+ switch (machtype) {
+ case LUNA_I:
+ ea = (u_int8_t *)0x4101FFE0;
+ for (i = 0; i < 6; i++) {
+ int u, l;
+
+ u = ea[0];
+ u = (u < 'A') ? u & 0xf : u - 'A' + 10;
+ l = ea[1];
+ l = (l < 'A') ? l & 0xf : l - 'A' + 10;
+
+ ether[i] = l | (u << 4);
+ ea += 2;
+ }
+ break;
+ case LUNA_II:
+ ds1220 = (void *)0xF1000004;
+ loc = 12;
+ for (i = 0; i < 6; i++) {
+ unsigned u, l, hex;
+
+ ds1220->ctl = (loc) << 16;
+ u = 0xf0 & (ds1220->ctl >> 12);
+ ds1220->ctl = (loc + 1) << 16;
+ l = 0x0f & (ds1220->ctl >> 16);
+ hex = (u < '9') ? l : l + 9;
+
+ ds1220->ctl = (loc + 2) << 16;
+ u = 0xf0 & (ds1220->ctl >> 12);
+ ds1220->ctl = (loc + 3) << 16;
+ l = 0x0f & (ds1220->ctl >> 16);
+
+ ether[i] = ((u < '9') ? l : l + 9) | (hex << 4);
+ loc += 4;
+ }
+ break;
+ default:
+ ether[0] = 0x00; ether[1] = 0x00; ether[2] = 0x0a;
+ ether[3] = 0xDE; ether[4] = 0xAD; ether[5] = 0x00;
+ break;
+ }
+}
diff --git a/sys/arch/luna68k/dev/lcd.c b/sys/arch/luna68k/dev/lcd.c
new file mode 100644
index 00000000000..d69a1b610d2
--- /dev/null
+++ b/sys/arch/luna68k/dev/lcd.c
@@ -0,0 +1,170 @@
+/* $NetBSD: lcd.c,v 1.1 2000/01/05 08:48:55 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: lcd.c,v 1.1 2000/01/05 08:48:55 nisimura Exp $");
+
+/*
+ * XXX
+ * Following code segments are subject to change.
+ * XXX
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#define PIO1_MODE_OUTPUT 0x84
+#define PIO1_MODE_INPUT 0x94
+
+#define POWER 0x10
+
+#define ENABLE 0x80
+#define DISABLE 0x00
+
+#define WRITE_CMD (0x00 | 0x00)
+#define WRITE_DATA (0x00 | 0x40)
+#define READ_BUSY (0x20 | 0x00)
+#define READ_DATA (0x20 | 0x40)
+
+#define LCD_INIT 0x38
+#define LCD_ENTRY 0x06
+#define LCD_ON 0x0c
+#define LCD_CLS 0x01
+#define LCD_HOME 0x02
+#define LCD_LOCATE(X, Y) (((Y) & 1 ? 0xc0 : 0x80) | ((X) & 0x0f))
+
+struct pio {
+ u_int8_t portA;
+ u_int8_t portB;
+ u_int8_t portC;
+ u_int8_t cntrl;
+};
+
+void lcdbusywait __P((void));
+void lcdput __P((int));
+void lcdctrl __P((int));
+void lcdshow __P((char *));
+void greeting __P((void));
+ /* "1234567890123456" */
+static char lcd_boot_message1[] = " NetBSD/luna68k ";
+static char lcd_boot_message2[] = " SX-9100/DT ";
+
+void
+lcdbusywait()
+{
+ struct pio *p1 = (struct pio *)0x4D000000;
+ int msb, s;
+
+ s = splhigh();
+ p1->cntrl = PIO1_MODE_INPUT;
+ p1->portC = POWER | READ_BUSY | ENABLE;
+ splx(s);
+
+ do {
+ msb = p1->portA & ENABLE;
+ delay(5);
+ } while (msb != 0);
+
+ s = splhigh();
+ p1->portC = POWER | READ_BUSY | DISABLE;
+ splx(s);
+}
+
+void
+lcdput(cc)
+ int cc;
+{
+ struct pio *p1 = (struct pio *)0x4D000000;
+ int s;
+
+ lcdbusywait();
+
+ s = splhigh();
+ p1->cntrl = PIO1_MODE_OUTPUT;
+
+ p1->portC = POWER | WRITE_DATA | ENABLE;
+ p1->portA = cc;
+ p1->portC = POWER | WRITE_DATA | DISABLE;
+ splx(s);
+}
+
+void
+lcdctrl(cc)
+ int cc;
+{
+ struct pio *p1 = (struct pio *)0x4D000000;
+ int s;
+
+ lcdbusywait();
+
+ s = splhigh();
+ p1->cntrl = PIO1_MODE_OUTPUT;
+
+ p1->portC = POWER | WRITE_CMD | ENABLE;
+ p1->portA = cc;
+ p1->portC = POWER | WRITE_CMD | DISABLE;
+ splx(s);
+}
+
+void
+lcdshow(s)
+ char *s;
+{
+ int cc;
+
+ while ((cc = *s++) != '\0')
+ lcdput(cc);
+}
+
+void
+greeting()
+{
+ lcdctrl(LCD_INIT);
+ lcdctrl(LCD_ENTRY);
+ lcdctrl(LCD_ON);
+
+ lcdctrl(LCD_CLS);
+ lcdctrl(LCD_HOME);
+
+ lcdctrl(LCD_LOCATE(0, 0));
+ lcdshow(lcd_boot_message1);
+ lcdctrl(LCD_LOCATE(0, 1));
+ lcdshow(lcd_boot_message2);
+}
diff --git a/sys/arch/luna68k/dev/lunafb.c b/sys/arch/luna68k/dev/lunafb.c
new file mode 100644
index 00000000000..8e361e9b344
--- /dev/null
+++ b/sys/arch/luna68k/dev/lunafb.c
@@ -0,0 +1,495 @@
+/* $NetBSD: lunafb.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: lunafb.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/mman.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/errno.h>
+#include <sys/buf.h>
+#include <vm/vm.h>
+#include <uvm/uvm_extern.h>
+
+#include <dev/rcons/raster.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wscons_raster.h>
+#include <dev/wscons/wsdisplayvar.h>
+
+#include <machine/cpu.h>
+#include <machine/autoconf.h>
+
+struct bt454 {
+ u_int8_t bt_addr; /* map address register */
+ u_int8_t bt_cmap; /* colormap data register */
+};
+
+struct bt458 {
+ u_int8_t bt_addr; /* map address register */
+ unsigned :24;
+ u_int8_t bt_cmap; /* colormap data register */
+ unsigned :24;
+ u_int8_t bt_ctrl; /* control register */
+ unsigned :24;
+ u_int8_t bt_omap; /* overlay (cursor) map register */
+ unsigned :24;
+};
+
+#define OMFB_RFCNT 0xB1000000 /* video h-origin/v-origin */
+#define OMFB_PLANEMASK 0xB1040000 /* planemask register */
+#define OMFB_FB_WADDR 0xB1080008 /* common plane */
+#define OMFB_FB_RADDR 0xB10C0008 /* plane #0 */
+#define OMFB_ROPFUNC 0xB12C0000 /* ROP function code */
+#define OMFB_RAMDAC 0xC1100000 /* Bt454/Bt458 RAMDAC */
+#define OMFB_SIZE (0xB1300000 - 0xB1080000 + NBPG)
+
+struct om_hwdevconfig {
+ int dc_wid; /* width of frame buffer */
+ int dc_ht; /* height of frame buffer */
+ int dc_depth; /* depth, bits per pixel */
+ int dc_rowbytes; /* bytes in a FB scan line */
+ int dc_cmsize; /* colormap size */
+ vaddr_t dc_videobase; /* base of flat frame buffer */
+ struct raster dc_raster; /* raster description */
+ struct rcons dc_rcons; /* raster blitter control info */
+};
+
+struct hwcmap {
+#define CMAP_SIZE 256
+ u_int8_t r[CMAP_SIZE];
+ u_int8_t g[CMAP_SIZE];
+ u_int8_t b[CMAP_SIZE];
+};
+
+struct omfb_softc {
+ struct device sc_dev; /* base device */
+ struct om_hwdevconfig *sc_dc; /* device configuration */
+ struct hwcmap sc_cmap; /* software copy of colormap */
+ int nscreens;
+};
+
+static int omgetcmap __P((struct omfb_softc *, struct wsdisplay_cmap *));
+static int omsetcmap __P((struct omfb_softc *, struct wsdisplay_cmap *));
+
+static struct om_hwdevconfig omfb_console_dc;
+static void omfb_getdevconfig __P((paddr_t, struct om_hwdevconfig *));
+
+extern struct wsdisplay_emulops omfb_emulops;
+
+static struct wsscreen_descr omfb_stdscreen = {
+ "std", 0, 0,
+ &omfb_emulops,
+ 0, 0,
+ 0
+};
+
+static const struct wsscreen_descr *_omfb_scrlist[] = {
+ &omfb_stdscreen,
+};
+
+static const struct wsscreen_list omfb_screenlist = {
+ sizeof(_omfb_scrlist) / sizeof(struct wsscreen_descr *), _omfb_scrlist
+};
+
+static int omfbioctl __P((void *, u_long, caddr_t, int, struct proc *));
+static int omfbmmap __P((void *, off_t, int));
+static int omfb_alloc_screen __P((void *, const struct wsscreen_descr *,
+ void **, int *, int *, long *));
+static void omfb_free_screen __P((void *, void *));
+static int omfb_show_screen __P((void *, void *, int,
+ void (*) (void *, int, int), void *));
+
+static const struct wsdisplay_accessops omfb_accessops = {
+ omfbioctl,
+ omfbmmap,
+ omfb_alloc_screen,
+ omfb_free_screen,
+ omfb_show_screen,
+ 0 /* load_font */
+};
+
+static int omfbmatch __P((struct device *, struct cfdata *, void *));
+static void omfbattach __P((struct device *, struct device *, void *));
+
+const struct cfattach fb_ca = {
+ sizeof(struct omfb_softc), omfbmatch, omfbattach
+};
+extern struct cfdriver fb_cd;
+
+extern int hwplanemask; /* hardware planemask; retrieved at boot */
+
+static int omfb_console;
+int omfb_cnattach __P((void));
+
+static int
+omfbmatch(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct mainbus_attach_args *ma = aux;
+
+ if (strcmp(ma->ma_name, fb_cd.cd_name))
+ return (0);
+ if (badaddr((caddr_t)ma->ma_addr, 4))
+ return (0);
+ return (1);
+}
+
+static void
+omfbattach(parent, self, args)
+ struct device *parent, *self;
+ void *args;
+{
+ struct omfb_softc *sc = (struct omfb_softc *)self;
+ struct wsemuldisplaydev_attach_args waa;
+
+ if (omfb_console) {
+ sc->sc_dc = &omfb_console_dc;
+ sc->nscreens = 1;
+ }
+ else {
+ sc->sc_dc = (struct om_hwdevconfig *)
+ malloc(sizeof(struct om_hwdevconfig), M_DEVBUF, M_WAITOK);
+ omfb_getdevconfig(OMFB_FB_WADDR, sc->sc_dc);
+ }
+ printf(": %d x %d, %dbpp\n", sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
+ sc->sc_dc->dc_depth);
+
+#if 0 /* WHITE on BLACK */
+ cm = &sc->sc_cmap;
+ memset(cm, 255, sizeof(struct hwcmap));
+ cm->r[0] = cm->g[0] = cm->b[0] = 0;
+#endif
+ waa.console = omfb_console;
+ waa.scrdata = &omfb_screenlist;
+ waa.accessops = &omfb_accessops;
+ waa.accesscookie = sc;
+
+ config_found(self, &waa, wsemuldisplaydevprint);
+}
+
+/* EXPORT */ int
+omfb_cnattach()
+{
+ struct om_hwdevconfig *dc = &omfb_console_dc;
+ long defattr;
+
+ omfb_getdevconfig(OMFB_FB_WADDR, dc);
+ (*omfb_emulops.alloc_attr)(&dc->dc_rcons, 0, 0, 0, &defattr);
+ wsdisplay_cnattach(&omfb_stdscreen, &dc->dc_rcons, 0, 0, defattr);
+ omfb_console = 1;
+ return (0);
+}
+
+static int
+omfbioctl(v, cmd, data, flag, p)
+ void *v;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ struct omfb_softc *sc = v;
+ struct om_hwdevconfig *dc = sc->sc_dc;
+
+ switch (cmd) {
+ case WSDISPLAYIO_GTYPE:
+ *(u_int *)data = 0x19990927;
+ return (0);
+
+ case WSDISPLAYIO_GINFO:
+#define wsd_fbip ((struct wsdisplay_fbinfo *)data)
+ wsd_fbip->height = dc->dc_ht;
+ wsd_fbip->width = dc->dc_wid;
+ wsd_fbip->depth = dc->dc_depth;
+ wsd_fbip->cmsize = dc->dc_cmsize;
+#undef fbt
+ return (0);
+
+ case WSDISPLAYIO_GETCMAP:
+ return omgetcmap(sc, (struct wsdisplay_cmap *)data);
+
+ case WSDISPLAYIO_PUTCMAP:
+ return omsetcmap(sc, (struct wsdisplay_cmap *)data);
+
+ case WSDISPLAYIO_SVIDEO:
+ case WSDISPLAYIO_GVIDEO:
+ case WSDISPLAYIO_GCURPOS:
+ case WSDISPLAYIO_SCURPOS:
+ case WSDISPLAYIO_GCURMAX:
+ case WSDISPLAYIO_GCURSOR:
+ case WSDISPLAYIO_SCURSOR:
+ break;
+ }
+ return (ENOTTY);
+}
+
+/*
+ * Return the address that would map the given device at the given
+ * offset, allowing for the given protection, or return -1 for error.
+ */
+static int
+omfbmmap(v, offset, prot)
+ void *v;
+ off_t offset;
+ int prot;
+{
+ struct omfb_softc *sc = v;
+
+ if (offset >= OMFB_SIZE || offset < 0)
+ return (-1);
+ return m68k_btop(m68k_trunc_page(sc->sc_dc->dc_videobase) + offset);
+}
+
+static int
+omgetcmap(sc, p)
+ struct omfb_softc *sc;
+ struct wsdisplay_cmap *p;
+{
+ u_int index = p->index, count = p->count;
+ int cmsize;
+
+ cmsize = sc->sc_dc->dc_cmsize;
+ if (index >= cmsize || (index + count) > cmsize)
+ return (EINVAL);
+
+ if (!uvm_useracc(p->red, count, B_WRITE) ||
+ !uvm_useracc(p->green, count, B_WRITE) ||
+ !uvm_useracc(p->blue, count, B_WRITE))
+ return (EFAULT);
+
+ copyout(&sc->sc_cmap.r[index], p->red, count);
+ copyout(&sc->sc_cmap.g[index], p->green, count);
+ copyout(&sc->sc_cmap.b[index], p->blue, count);
+
+ return (0);
+}
+
+static int
+omsetcmap(sc, p)
+ struct omfb_softc *sc;
+ struct wsdisplay_cmap *p;
+{
+ u_int index = p->index, count = p->count;
+ int cmsize, i;
+
+ cmsize = sc->sc_dc->dc_cmsize;
+ if (index >= cmsize || (index + count) > cmsize)
+ return (EINVAL);
+
+ if (!uvm_useracc(p->red, count, B_READ) ||
+ !uvm_useracc(p->green, count, B_READ) ||
+ !uvm_useracc(p->blue, count, B_READ))
+ return (EFAULT);
+
+ copyin(p->red, &sc->sc_cmap.r[index], count);
+ copyin(p->green, &sc->sc_cmap.g[index], count);
+ copyin(p->blue, &sc->sc_cmap.b[index], count);
+
+ if (hwplanemask == 0x0f) {
+ struct bt454 *odac = (struct bt454 *)OMFB_RAMDAC;
+ odac->bt_addr = index;
+ for (i = index; i < count; i++) {
+ odac->bt_cmap = sc->sc_cmap.r[i];
+ odac->bt_cmap = sc->sc_cmap.g[i];
+ odac->bt_cmap = sc->sc_cmap.b[i];
+ }
+ }
+ else if (hwplanemask == 0xff) {
+ struct bt458 *ndac = (struct bt458 *)OMFB_RAMDAC;
+ ndac->bt_addr = index;
+ for (i = index; i < count; i++) {
+ ndac->bt_cmap = sc->sc_cmap.r[i];
+ ndac->bt_cmap = sc->sc_cmap.g[i];
+ ndac->bt_cmap = sc->sc_cmap.b[i];
+ }
+ }
+ return (0);
+}
+
+static void
+omfb_getdevconfig(paddr, dc)
+ paddr_t paddr;
+ struct om_hwdevconfig *dc;
+{
+ int bpp, i;
+ struct raster *rap;
+ struct rcons *rcp;
+ struct { short h, v; } *rfcnt;
+
+ switch (hwplanemask) {
+ case 0xff:
+ bpp = 8; /* XXX check monochrome bit in DIPSW */
+ break;
+ default:
+ case 0x0f:
+ bpp = 4; /* XXX check monochrome bit in DIPSW */
+ break;
+ case 1:
+ bpp = 1;
+ break;
+ }
+ dc->dc_wid = 1240;
+ dc->dc_ht = 1024;
+ dc->dc_depth = bpp;
+ dc->dc_rowbytes = 2048 / 8;
+ dc->dc_cmsize = (bpp == 1) ? 0 : 1 << bpp;
+ dc->dc_videobase = paddr;
+
+#if 0 /* WHITE on BLACK */
+ if (hwplanemask == 0x0f) {
+ /* XXX Need Bt454 initialization */
+ struct bt454 *odac = (struct bt454 *)OMFB_RAMDAC;
+ odac->bt_addr = 0;
+ odac->bt_cmap = 0;
+ odac->bt_cmap = 0;
+ odac->bt_cmap = 0;
+ for (i = 1; i < 16; i++) {
+ odac->bt_cmap = 255;
+ odac->bt_cmap = 255;
+ odac->bt_cmap = 255;
+ }
+ }
+ else if (hwplanemask == 0xff) {
+ struct bt458 *ndac = (struct bt458 *)OMFB_RAMDAC;
+
+ ndac->bt_addr = 0x04;
+ ndac->bt_ctrl = 0xff; /* all planes will be read */
+ ndac->bt_ctrl = 0x00; /* all planes have non-blink */
+ ndac->bt_ctrl = 0x43; /* pallete enabled, ovly plane */
+ ndac->bt_ctrl = 0x00; /* no test mode */
+ ndac->bt_addr = 0;
+ ndac->bt_cmap = 0;
+ ndac->bt_cmap = 0;
+ ndac->bt_cmap = 0;
+ for (i = 1; i < 256; i++) {
+ ndac->bt_cmap = 255;
+ ndac->bt_cmap = 255;
+ ndac->bt_cmap = 255;
+ }
+ }
+#endif
+
+ /* adjust h/v orgin on screen */
+ /* XXX not sure it's necessary XXX */
+ rfcnt = (void *)OMFB_RFCNT;
+ rfcnt->h = 0;
+ rfcnt->v = 0;
+
+ /* clear the screen */
+ *(u_int32_t *)OMFB_PLANEMASK = 0xff;
+ ((u_int32_t *)OMFB_ROPFUNC)[5] = ~0; /* ROP copy */
+ for (i = 0; i < dc->dc_ht * dc->dc_rowbytes/sizeof(u_int32_t); i++)
+ *(u_int32_t *)(dc->dc_videobase + i) = 0;
+ *(u_int32_t *)OMFB_PLANEMASK = 0x01;
+
+ /* initialize the raster */
+ rap = &dc->dc_raster;
+ rap->width = dc->dc_wid;
+ rap->height = dc->dc_ht;
+ rap->depth = dc->dc_depth;
+ rap->linelongs = dc->dc_rowbytes / sizeof(u_int32_t);
+ rap->pixels = (u_int32_t *)dc->dc_videobase;
+
+ /* initialize the raster console blitter */
+ rcp = &dc->dc_rcons;
+ rcp->rc_sp = rap;
+ rcp->rc_crow = rcp->rc_ccol = -1;
+ rcp->rc_crowp = &rcp->rc_crow;
+ rcp->rc_ccolp = &rcp->rc_ccol;
+ rcons_init(rcp, 34, 80);
+
+ omfb_stdscreen.nrows = dc->dc_rcons.rc_maxrow;
+ omfb_stdscreen.ncols = dc->dc_rcons.rc_maxcol;
+}
+
+static int
+omfb_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
+ void *v;
+ const struct wsscreen_descr *type;
+ void **cookiep;
+ int *curxp, *curyp;
+ long *attrp;
+{
+ struct omfb_softc *sc = v;
+ long defattr;
+
+ if (sc->nscreens > 0)
+ return (ENOMEM);
+
+ *cookiep = &sc->sc_dc->dc_rcons; /* one and only for now */
+ *curxp = 0;
+ *curyp = 0;
+ (*omfb_emulops.alloc_attr)(&sc->sc_dc->dc_rcons, 0, 0, 0, &defattr);
+ *attrp = defattr;
+ sc->nscreens++;
+ return (0);
+}
+
+static void
+omfb_free_screen(v, cookie)
+ void *v;
+ void *cookie;
+{
+ struct omfb_softc *sc = v;
+
+ if (sc->sc_dc == &omfb_console_dc)
+ panic("omfb_free_screen: console");
+
+ sc->nscreens--;
+}
+
+static int
+omfb_show_screen(v, cookie, waitok, cb, cbarg)
+ void *v;
+ void *cookie;
+ int waitok;
+ void (*cb) __P((void *, int, int));
+ void *cbarg;
+{
+ return 0;
+}
diff --git a/sys/arch/luna68k/dev/lunaws.c b/sys/arch/luna68k/dev/lunaws.c
new file mode 100644
index 00000000000..82d0ea70574
--- /dev/null
+++ b/sys/arch/luna68k/dev/lunaws.c
@@ -0,0 +1,465 @@
+/* $NetBSD: lunaws.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: lunaws.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $");
+
+#include "wsmouse.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wskbdvar.h>
+#include <dev/wscons/wsksymdef.h>
+#include <dev/wscons/wsksymvar.h>
+#include <dev/wscons/wsmousevar.h>
+
+#include <luna68k/dev/sioreg.h>
+#include <luna68k/dev/siovar.h>
+
+static const u_int8_t ch1_regs[6] = {
+ WR0_RSTINT, /* Reset E/S Interrupt */
+ WR1_RXALLS, /* Rx per char, No Tx */
+ 0, /* */
+ WR3_RX8BIT | WR3_RXENBL, /* Rx */
+ WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY, /* Tx/Rx */
+ WR5_TX8BIT | WR5_TXENBL, /* Tx */
+};
+
+struct ws_softc {
+ struct device sc_dv;
+ struct device *sc_wskbddev;
+ struct device *sc_wsmousedev;
+ struct sioreg *sc_ctl;
+ u_int8_t sc_wr[6];
+};
+
+static void omkbd_input __P((void *, int));
+static int omkbd_decode __P((void *, int, u_int *, int *));
+static int omkbd_enable __P((void *, int));
+static void omkbd_set_leds __P((void *, int));
+static int omkbd_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
+
+struct wscons_keydesc omkbd_keydesctab[];
+
+static const struct wskbd_mapdata omkbd_keymapdata = {
+ omkbd_keydesctab,
+ KB_JP,
+};
+static const struct wskbd_accessops omkbd_accessops = {
+ omkbd_enable,
+ omkbd_set_leds,
+ omkbd_ioctl,
+};
+
+void ws_cnattach __P((void));
+static void ws_cngetc __P((void *, u_int *, int *));
+static void ws_cnpollc __P((void *, int));
+static const struct wskbd_consops ws_consops = {
+ ws_cngetc,
+ ws_cnpollc,
+};
+
+#if NWSMOUSE > 0
+static int omms_enable __P((void *));
+static int omms_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
+static void omms_disable __P((void *));
+
+static const struct wsmouse_accessops omms_accessops = {
+ omms_enable,
+ omms_ioctl,
+ omms_disable,
+};
+#endif
+
+static void wsintr __P((int));
+
+static int wsmatch __P((struct device *, struct cfdata *, void *));
+static void wsattach __P((struct device *, struct device *, void *));
+
+const struct cfattach ws_ca = {
+ sizeof(struct ws_softc), wsmatch, wsattach
+};
+extern struct cfdriver ws_cd;
+
+extern int syscngetc __P((dev_t));
+extern void syscnputc __P((dev_t, int));
+
+static int
+wsmatch(parent, match, aux)
+ struct device *parent;
+ struct cfdata *match;
+ void *aux;
+{
+ struct sio_attach_args *args = aux;
+
+ if (args->channel != 1)
+ return 0;
+ return 1;
+}
+
+static void
+wsattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct ws_softc *sc = (struct ws_softc *)self;
+ struct sio_softc *scp = (struct sio_softc *)parent;
+ struct sio_attach_args *args = aux;
+ struct wskbddev_attach_args a;
+
+ sc->sc_ctl = (struct sioreg *)scp->scp_ctl + 1;
+ bcopy(ch1_regs, sc->sc_wr, sizeof(ch1_regs));
+ scp->scp_intr[1] = wsintr;
+
+ setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
+ setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]);
+ setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]);
+ setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]);
+ setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
+ setsioreg(sc->sc_ctl, WR1, sc->sc_wr[WR1]);
+
+ syscnputc((dev_t)1, 0x20); /* keep quiet mouse */
+
+ printf("\n");
+
+ a.console = (args->hwflags == 1);
+ a.keymap = &omkbd_keymapdata;
+ a.accessops = &omkbd_accessops;
+ a.accesscookie = (void *)sc;
+ sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
+
+#if NWSMOUSE > 0
+ {
+ struct wsmousedev_attach_args b;
+ b.accessops = &omms_accessops;
+ b.accesscookie = (void *)sc;
+ sc->sc_wsmousedev = config_found(self, &b, wsmousedevprint);
+ }
+#endif
+}
+
+/*ARGSUSED*/
+static void
+wsintr(chan)
+ int chan;
+{
+ struct ws_softc *sc = ws_cd.cd_devs[0];
+ struct sioreg *sio = sc->sc_ctl;
+ u_int code;
+ int rr;
+ extern int getsiocsr __P((struct sioreg *));
+
+ rr = getsiocsr(sio);
+ if (rr & RR_RXRDY) {
+ do {
+ code = sio->sio_data;
+ if (rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) {
+ sio->sio_cmd = WR0_ERRRST;
+#if 0
+ if (sio->sio_stat & RR_FRAMING)
+ code |= TTY_FE;
+ else if (sio->sio_stat & RR_PARITY)
+ code |= TTY_PE;
+#endif
+ continue;
+ }
+#if 0
+ /*
+ * if (code >= 0x80 || code <= 0x87), then
+ * it's the first byte of 3 byte long mouse report
+ * code[0] & 07 -> LMR button condition
+ * code[1], [2] -> x,y delta
+ */
+#endif
+ omkbd_input(sc, code & 0xff);
+ } while ((rr = getsiocsr(sio)) & RR_RXRDY);
+ }
+ if (rr && RR_TXRDY)
+ sio->sio_cmd = WR0_RSTPEND;
+ /* not capable of transmit, yet */
+}
+
+static void
+omkbd_input(v, data)
+ void *v;
+ int data;
+{
+ struct ws_softc *sc = v;
+ u_int type;
+ int key;
+
+ if (omkbd_decode(v, data, &type, &key))
+ wskbd_input(sc->sc_wskbddev, type, key);
+}
+
+static int
+omkbd_decode(v, datain, type, dataout)
+ void *v;
+ int datain;
+ u_int *type;
+ int *dataout;
+{
+ *type = (datain & 0x80) ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
+ *dataout = datain & 0x7f;
+ return 1;
+}
+
+#define KC(n) KS_KEYCODE(n)
+
+static const keysym_t omkbd_keydesc_1[] = {
+/* pos command normal shifted */
+ KC(0x9), KS_Tab,
+ KC(0xa), KS_Control_L,
+ KC(0xb), KS_Mode_switch, /* Kana */
+ KC(0xc), KS_Shift_R,
+ KC(0xd), KS_Shift_L,
+ KC(0xe), KS_Caps_Lock,
+ KC(0xf), KS_Meta_L, /* Zenmen */
+ KC(0x10), KS_Escape,
+ KC(0x11), KS_BackSpace,
+ KC(0x12), KS_Return,
+ KC(0x14), KS_space,
+ KC(0x15), KS_Delete,
+ KC(0x16), KS_Alt_L, /* Henkan */
+ KC(0x17), KS_Alt_R, /* Kakutei */
+ KC(0x18), KS_f11, /* Shokyo */
+ KC(0x19), KS_f12, /* Yobidashi */
+ KC(0x1a), KS_f13, /* Bunsetsu L */
+ KC(0x1b), KS_f14, /* Bunsetsu R */
+ KC(0x1c), KS_KP_Up,
+ KC(0x1d), KS_KP_Left,
+ KC(0x1e), KS_KP_Right,
+ KC(0x1f), KS_KP_Down,
+ /* KC(0x20), KS_f11, */
+ /* KC(0x21), KS_f12, */
+ KC(0x22), KS_1, KS_exclam,
+ KC(0x23), KS_2, KS_quotedbl,
+ KC(0x24), KS_3, KS_numbersign,
+ KC(0x25), KS_4, KS_dollar,
+ KC(0x26), KS_5, KS_percent,
+ KC(0x27), KS_6, KS_ampersand,
+ KC(0x28), KS_7, KS_apostrophe,
+ KC(0x29), KS_8, KS_parenleft,
+ KC(0x2a), KS_9, KS_parenright,
+ KC(0x2b), KS_0,
+ KC(0x2c), KS_minus, KS_equal,
+ KC(0x2d), KS_asciicircum, KS_asciitilde,
+ KC(0x2e), KS_backslash, KS_bar,
+ /* KC(0x30), KS_f13, */
+ /* KC(0x31), KS_f14, */
+ KC(0x32), KS_q,
+ KC(0x33), KS_w,
+ KC(0x34), KS_e,
+ KC(0x35), KS_r,
+ KC(0x36), KS_t,
+ KC(0x37), KS_y,
+ KC(0x38), KS_u,
+ KC(0x39), KS_i,
+ KC(0x3a), KS_o,
+ KC(0x3b), KS_p,
+ KC(0x3c), KS_at, KS_grave,
+ KC(0x3d), KS_bracketleft, KS_braceleft,
+ KC(0x42), KS_a,
+ KC(0x43), KS_s,
+ KC(0x44), KS_d,
+ KC(0x45), KS_f,
+ KC(0x46), KS_g,
+ KC(0x47), KS_h,
+ KC(0x48), KS_j,
+ KC(0x49), KS_k,
+ KC(0x4a), KS_l,
+ KC(0x4b), KS_semicolon, KS_plus,
+ KC(0x4c), KS_colon, KS_asterisk,
+ KC(0x4d), KS_bracketright, KS_braceright,
+ KC(0x52), KS_z,
+ KC(0x53), KS_x,
+ KC(0x54), KS_c,
+ KC(0x55), KS_v,
+ KC(0x56), KS_b,
+ KC(0x57), KS_n,
+ KC(0x58), KS_m,
+ KC(0x59), KS_comma, KS_less,
+ KC(0x5a), KS_period, KS_greater,
+ KC(0x5b), KS_slash, KS_question,
+ KC(0x5c), KS_underscore,
+ KC(0x60), KS_KP_Delete,
+ KC(0x61), KS_KP_Add,
+ KC(0x62), KS_KP_Subtract,
+ KC(0x63), KS_KP_7,
+ KC(0x64), KS_KP_8,
+ KC(0x65), KS_KP_9,
+ KC(0x66), KS_KP_4,
+ KC(0x67), KS_KP_5,
+ KC(0x68), KS_KP_6,
+ KC(0x69), KS_KP_1,
+ KC(0x6a), KS_KP_2,
+ KC(0x6b), KS_KP_3,
+ KC(0x6c), KS_KP_0,
+ KC(0x6d), KS_KP_Decimal,
+ KC(0x6e), KS_KP_Enter,
+ KC(0x72), KS_f1,
+ KC(0x73), KS_f2,
+ KC(0x74), KS_f3,
+ KC(0x75), KS_f4,
+ KC(0x76), KS_f5,
+ KC(0x77), KS_f6,
+ KC(0x78), KS_f7,
+ KC(0x79), KS_f8,
+ KC(0x7a), KS_f9,
+ KC(0x7b), KS_f10,
+ KC(0x7c), KS_KP_Multiply,
+ KC(0x7d), KS_KP_Divide,
+ KC(0x7e), KS_KP_Equal,
+ KC(0x7f), KS_KP_Separator,
+};
+
+#define SIZE(map) (sizeof(map)/sizeof(keysym_t))
+
+struct wscons_keydesc omkbd_keydesctab[] = {
+ { KB_JP, 0, SIZE(omkbd_keydesc_1), omkbd_keydesc_1, },
+ { 0, 0, 0, 0 },
+};
+
+static void
+ws_cngetc(v, type, data)
+ void *v;
+ u_int *type;
+ int *data;
+{
+ int code;
+
+ do {
+ code = syscngetc((dev_t)1);
+ } while (!omkbd_decode(v, code, type, data));
+}
+
+static void
+ws_cnpollc(v, on)
+ void *v;
+ int on;
+{
+}
+
+/* EXPORT */ void
+ws_cnattach()
+{
+ static int voidfill;
+
+ wskbd_cnattach(&ws_consops, &voidfill, &omkbd_keymapdata);
+}
+
+static int
+omkbd_enable(v, on)
+ void *v;
+ int on;
+{
+ return 0;
+}
+
+static void
+omkbd_set_leds(v, leds)
+ void *v;
+ int leds;
+{
+#if 0
+ syscnputc((dev_t)1, 0x10); /* kana LED on */
+ syscnputc((dev_t)1, 0x00); /* kana LED off */
+ syscnputc((dev_t)1, 0x11); /* caps LED off */
+ syscnputc((dev_t)1, 0x01); /* caps LED off */
+#endif
+}
+
+static int
+omkbd_ioctl(v, cmd, data, flag, p)
+ void *v;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ switch (cmd) {
+ case WSKBDIO_GTYPE:
+ *(int *)data = 0x19991005 /* XXX */;
+ return 0;
+ case WSKBDIO_SETLEDS:
+ case WSKBDIO_GETLEDS:
+ case WSKBDIO_COMPLEXBELL:
+ return 0;
+ }
+ return -1;
+}
+
+#if NWSMOUSE > 0
+
+static int
+omms_enable(v)
+ void *v;
+{
+ syscnputc((dev_t)1, 0x60); /* enable 3 byte long mouse reporting */
+ return 0;
+}
+
+/*ARGUSED*/
+static int
+omms_ioctl(v, cmd, data, flag, p)
+ void *v;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ if (cmd == WSMOUSEIO_GTYPE) {
+ *(u_int *)data = 0x19991005; /* XXX */
+ return 0;
+ }
+ return ENOTTY;
+}
+
+static void
+omms_disable(v)
+ void *v;
+{
+ syscnputc((dev_t)1, 0x20); /* quiet mouse */
+}
+#endif
diff --git a/sys/arch/luna68k/dev/md_root.c b/sys/arch/luna68k/dev/md_root.c
new file mode 100644
index 00000000000..0db9aae1b51
--- /dev/null
+++ b/sys/arch/luna68k/dev/md_root.c
@@ -0,0 +1,91 @@
+/* $NetBSD: md_root.c,v 1.1 2000/01/05 08:48:55 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Gordon W. Ross.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/systm.h>
+
+#include <dev/md.h>
+
+#include "opt_mdsize.h"
+
+extern int boothowto;
+
+#ifndef MINIROOTSIZE
+#define MINIROOTSIZE 512
+#endif
+
+#define ROOTBYTES (MINIROOTSIZE << DEV_BSHIFT)
+
+/*
+ * This array will be patched to contain a file-system image.
+ * See the program: src/distrib/sun3/common/rdsetroot.c
+ */
+int md_root_size = ROOTBYTES;
+char md_root_image[ROOTBYTES] = "|This is the root ramdisk!\n";
+
+/*
+ * This is called during autoconfig.
+ */
+void
+md_attach_hook(unit, md)
+ int unit;
+ struct md_conf *md;
+{
+ if (unit == 0) {
+ /* Setup root ramdisk */
+ md->md_addr = (caddr_t) md_root_image;
+ md->md_size = (size_t) md_root_size;
+ md->md_type = MD_KMEM_FIXED;
+ printf(" fixed, %d blocks", MINIROOTSIZE);
+ }
+}
+
+/*
+ * This is called during open (i.e. mountroot)
+ */
+void
+md_open_hook(unit, md)
+ int unit;
+ struct md_conf *md;
+{
+ if (unit == 0) {
+ /* The root ramdisk only works single-user. */
+ boothowto |= RB_SINGLE;
+ }
+}
diff --git a/sys/arch/luna68k/dev/omrasops.c b/sys/arch/luna68k/dev/omrasops.c
new file mode 100644
index 00000000000..8b4e364e2de
--- /dev/null
+++ b/sys/arch/luna68k/dev/omrasops.c
@@ -0,0 +1,518 @@
+/* $NetBSD: omrasops.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: omrasops.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $");
+
+/*
+ * Designed speficically for 'm68k bitorder';
+ * - most significant byte is stored at lower address,
+ * - most significant bit is displayed at left most on screen.
+ * Implementation relys on;
+ * - every memory references is done in aligned 32bit chunk,
+ * - font glyphs are stored in 32bit padded.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/rcons/raster.h>
+#include <dev/wscons/wscons_raster.h>
+#include <dev/wscons/wscons_rfont.h>
+#include <dev/wscons/wsdisplayvar.h>
+
+void rcons_init __P((struct rcons *, int, int));
+
+/* wscons emulator operations */
+static void om_cursor __P((void *, int, int, int));
+static int om_mapchar __P((void *, int, unsigned int *));
+static void om_putchar __P((void *, int, int, u_int, long));
+static void om_copycols __P((void *, int, int, int, int));
+static void om_copyrows __P((void *, int, int, int num));
+static void om_erasecols __P((void *, int, int, int, long));
+static void om_eraserows __P((void *, int, int, long));
+static int om_alloc_attr __P((void *, int, int, int, long *));
+
+struct wsdisplay_emulops omfb_emulops = {
+ om_cursor,
+ om_mapchar,
+ om_putchar,
+ om_copycols,
+ om_erasecols,
+ om_copyrows,
+ om_eraserows,
+ om_alloc_attr
+};
+
+#define ALL1BITS (~0U)
+#define ALL0BITS (0U)
+#define BLITWIDTH (32)
+#define ALIGNMASK (0x1f)
+#define BYTESDONE (4)
+
+#define W(p) (*(u_int32_t *)(p))
+#define R(p) (*(u_int32_t *)((caddr_t)(p) + 0x40000))
+
+/*
+ * Blit a character at the specified co-ordinates.
+ */
+static void
+om_putchar(cookie, row, startcol, uc, attr)
+ void *cookie;
+ int row, startcol;
+ u_int uc;
+ long attr;
+{
+ struct rcons *rc = cookie;
+ struct raster *rap = rc->rc_sp;
+ caddr_t p;
+ int scanspan, startx, height, width, align, y;
+ u_int32_t lmask, rmask, glyph, inverse;
+ u_int32_t *g;
+
+ scanspan = rap->linelongs * 4;
+ y = rc->rc_yorigin + rc->rc_font->height * row;
+ startx = rc->rc_xorigin + rc->rc_font->width * startcol;
+ height = rc->rc_font->height;
+ g = rc->rc_font->chars[uc].r->pixels;
+ inverse = (attr != 0) ? ALL1BITS : ALL0BITS;
+
+ p = (caddr_t)rap->pixels + y * scanspan + ((startx / 32) * 4);
+ align = startx & ALIGNMASK;
+ width = rc->rc_font->width + align;
+ lmask = ALL1BITS >> align;
+ rmask = ALL1BITS << (-width & ALIGNMASK);
+ if (width <= BLITWIDTH) {
+ lmask &= rmask;
+ while (height > 0) {
+ glyph = *g;
+ glyph = (glyph >> align) ^ inverse;
+ W(p) = (R(p) & ~lmask) | (glyph & lmask);
+ p += scanspan;
+ g += 1;
+ height--;
+ }
+ }
+ else {
+ caddr_t q = p;
+ u_int32_t lhalf, rhalf;
+
+ while (height > 0) {
+ glyph = *g;
+ lhalf = (glyph >> align) ^ inverse;
+ W(p) = (R(p) & ~lmask) | (lhalf & lmask);
+ p += BYTESDONE;
+ rhalf = (glyph << (BLITWIDTH - align)) ^ inverse;
+ W(p) = (rhalf & rmask) | (R(p) & ~rmask);
+
+ p = (q += scanspan);
+ g += 1;
+ height--;
+ }
+ }
+}
+
+static void
+om_erasecols(cookie, row, startcol, ncols, attr)
+ void *cookie;
+ int row, startcol, ncols;
+ long attr;
+{
+ struct rcons *rc = cookie;
+ struct raster *rap = rc->rc_sp;
+ caddr_t p;
+ int scanspan, startx, height, width, align, w, y;
+ u_int32_t lmask, rmask, fill;
+
+ scanspan = rap->linelongs * 4;
+ y = rc->rc_yorigin + rc->rc_font->height * row;
+ startx = rc->rc_xorigin + rc->rc_font->width * startcol;
+ height = rc->rc_font->height;
+ w = rc->rc_font->width * ncols;
+ fill = (attr != 0) ? ALL1BITS : ALL0BITS;
+
+ p = (caddr_t)rap->pixels + y * scanspan + ((startx / 32) * 4);
+ align = startx & ALIGNMASK;
+ width = w + align;
+ lmask = ALL1BITS >> align;
+ rmask = ALL1BITS << (-width & ALIGNMASK);
+ if (width <= BLITWIDTH) {
+ lmask &= rmask;
+ fill &= lmask;
+ while (height > 0) {
+ W(p) = (R(p) & ~lmask) | fill;
+ p += scanspan;
+ height--;
+ }
+ }
+ else {
+ caddr_t q = p;
+ while (height > 0) {
+ W(p) = (R(p) & ~lmask) | (fill & lmask);
+ width -= 2 * BLITWIDTH;
+ while (width > 0) {
+ p += BYTESDONE;
+ W(p) = fill;
+ width -= BLITWIDTH;
+ }
+ p += BYTESDONE;
+ W(p) = (fill & rmask) | (R(p) & ~rmask);
+
+ p = (q += scanspan);
+ width = w + align;
+ height--;
+ }
+ }
+}
+
+static void
+om_eraserows(cookie, startrow, nrows, attr)
+ void *cookie;
+ int startrow, nrows;
+ long attr;
+{
+ struct rcons *rc = cookie;
+ struct raster *rap = rc->rc_sp;
+ caddr_t p, q;
+ int scanspan, starty, height, width, w;
+ u_int32_t rmask, fill;
+
+ scanspan = rap->linelongs * 4;
+ starty = rc->rc_yorigin + rc->rc_font->height * startrow;
+ height = rc->rc_font->height * nrows;
+ w = rc->rc_font->width * rc->rc_maxcol;
+ fill = (attr == 1) ? ALL1BITS : ALL0BITS;
+
+ p = (caddr_t)rap->pixels + starty * scanspan;
+ p += (rc->rc_xorigin / 32) * 4;
+ width = w;
+ rmask = ALL1BITS << (-width & ALIGNMASK);
+ q = p;
+ while (height > 0) {
+ W(p) = fill; /* always aligned */
+ width -= 2 * BLITWIDTH;
+ while (width > 0) {
+ p += BYTESDONE;
+ W(p) = fill;
+ width -= BLITWIDTH;
+ }
+ p += BYTESDONE;
+ W(p) = (fill & rmask) | (R(p) & ~rmask);
+ p = (q += scanspan);
+ width = w;
+ height--;
+ }
+}
+
+static void
+om_copyrows(cookie, srcrow, dstrow, nrows)
+ void *cookie;
+ int srcrow, dstrow, nrows;
+{
+ struct rcons *rc = cookie;
+ struct raster *rap = rc->rc_sp;
+ caddr_t p, q;
+ int scanspan, offset, srcy, height, width, w;
+ u_int32_t rmask;
+
+ scanspan = rap->linelongs * 4;
+ height = rc->rc_font->height * nrows;
+ offset = (dstrow - srcrow) * scanspan * rc->rc_font->height;
+ srcy = rc->rc_yorigin + rc->rc_font->height * srcrow;
+ if (srcrow < dstrow && srcrow + nrows > dstrow) {
+ scanspan = -scanspan;
+ srcy += height;
+ }
+
+ p = (caddr_t)rap->pixels + srcy * (rap->linelongs * 4);
+ p += (rc->rc_xorigin / 32) * 4;
+ w = rc->rc_font->width * rc->rc_maxcol;
+ width = w;
+ rmask = ALL1BITS << (-width & ALIGNMASK);
+ q = p;
+ while (height > 0) {
+ W(p + offset) = R(p); /* always aligned */
+ width -= 2 * BLITWIDTH;
+ while (width > 0) {
+ p += BYTESDONE;
+ W(p + offset) = R(p);
+ width -= BLITWIDTH;
+ }
+ p += BYTESDONE;
+ W(p + offset) = (R(p) & rmask) | (R(p + offset) & ~rmask);
+
+ p = (q += scanspan);
+ width = w;
+ height--;
+ }
+}
+
+static void
+om_copycols(cookie, startrow, srccol, dstcol, ncols)
+ void *cookie;
+ int startrow, srccol, dstcol, ncols;
+{
+ struct rcons *rc = cookie;
+ struct raster *rap = rc->rc_sp;
+ caddr_t sp, dp, basep;
+ int scanspan, height, width, align, shift, w, y, srcx, dstx;
+ u_int32_t lmask, rmask;
+
+ scanspan = rap->linelongs * 4;
+ y = rc->rc_yorigin + rc->rc_font->height * startrow;
+ srcx = rc->rc_xorigin + rc->rc_font->width * srccol;
+ dstx = rc->rc_xorigin + rc->rc_font->width * dstcol;
+ height = rc->rc_font->height;
+ w = rc->rc_font->width * ncols;
+ basep = (caddr_t)rap->pixels + y * scanspan;
+
+ align = shift = srcx & ALIGNMASK;
+ width = w + align;
+ align = dstx & ALIGNMASK;
+ lmask = ALL1BITS >> align;
+ rmask = ALL1BITS << (-(w + align) & ALIGNMASK);
+ shift = align - shift;
+ sp = basep + (srcx / 32) * 4;
+ dp = basep + (dstx / 32) * 4;
+
+ if (shift != 0)
+ goto hardluckalignment;
+
+ /* alignments comfortably match */
+ if (width <= BLITWIDTH) {
+ lmask &= rmask;
+ while (height > 0) {
+ W(dp) = (R(dp) & ~lmask) | (R(sp) & lmask);
+ dp += scanspan;
+ sp += scanspan;
+ height--;
+ }
+ }
+ /* copy forward (left-to-right) */
+ else if (dstcol < srccol || srccol + ncols < dstcol) {
+ caddr_t sq = sp, dq = dp;
+
+ w = width;
+ while (height > 0) {
+ W(dp) = (R(dp) & ~lmask) | (R(sp) & lmask);
+ width -= 2 * BLITWIDTH;
+ while (width > 0) {
+ sp += BYTESDONE;
+ dp += BYTESDONE;
+ W(dp) = R(sp);
+ width -= BLITWIDTH;
+ }
+ sp += BYTESDONE;
+ dp += BYTESDONE;
+ W(dp) = (R(sp) & rmask) | (R(dp) & ~rmask);
+ sp = (sq += scanspan);
+ dp = (dq += scanspan);
+ width = w;
+ height--;
+ }
+ }
+ /* copy backward (right-to-left) */
+ else {
+ caddr_t sq, dq;
+
+ sq = (sp += width / 32 * 4);
+ dq = (dp += width / 32 * 4);
+ w = width;
+ while (height > 0) {
+ W(dp) = (R(sp) & rmask) | (R(dp) & ~rmask);
+ width -= 2 * BLITWIDTH;
+ while (width > 0) {
+ sp -= BYTESDONE;
+ dp -= BYTESDONE;
+ W(dp) = R(sp);
+ width -= BLITWIDTH;
+ }
+ sp -= BYTESDONE;
+ dp -= BYTESDONE;
+ W(dp) = (R(dp) & ~lmask) | (R(sp) & lmask);
+
+ sp = (sq += scanspan);
+ dp = (dq += scanspan);
+ width = w;
+ height--;
+ }
+ }
+ return;
+
+ hardluckalignment:
+ /* alignments painfully disagree */
+}
+
+/*
+ * Map a character.
+ */
+static int
+om_mapchar(cookie, c, cp)
+ void *cookie;
+ int c;
+ u_int *cp;
+{
+ if (c < 128) {
+ *cp = c;
+ return (5);
+ }
+ *cp = ' ';
+ return (0);
+}
+
+/*
+ * Position|{enable|disable} the cursor at the specified location.
+ */
+static void
+om_cursor(cookie, on, row, col)
+ void *cookie;
+ int on, row, col;
+{
+ struct rcons *rc = cookie;
+ struct raster *rap = rc->rc_sp;
+ caddr_t p;
+ int scanspan, startx, height, width, align, y;
+ u_int32_t lmask, rmask, image;
+
+ if (!on) {
+ /* make sure it's on */
+ if ((rc->rc_bits & RC_CURSOR) == 0)
+ return;
+
+ row = *rc->rc_crowp;
+ col = *rc->rc_ccolp;
+ } else {
+ /* unpaint the old copy. */
+ *rc->rc_crowp = row;
+ *rc->rc_ccolp = col;
+ }
+
+ scanspan = rap->linelongs * 4;
+ y = rc->rc_yorigin + rc->rc_font->height * row;
+ startx = rc->rc_xorigin + rc->rc_font->width * col;
+ height = rc->rc_font->height;
+
+ p = (caddr_t)rap->pixels + y * scanspan + ((startx / 32) * 4);
+ align = startx & ALIGNMASK;
+ width = rc->rc_font->width + align;
+ lmask = ALL1BITS >> align;
+ rmask = ALL1BITS << (-width & ALIGNMASK);
+ if (width <= BLITWIDTH) {
+ lmask &= rmask;
+ while (height > 0) {
+ image = R(p);
+ W(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask);
+ p += scanspan;
+ height--;
+ }
+ }
+ else {
+ caddr_t q = p;
+
+ while (height > 0) {
+ image = R(p);
+ W(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask);
+ p += BYTESDONE;
+ image = R(p);
+ W(p) = ((image ^ ALL1BITS) & rmask) | (image & ~rmask);
+
+ p = (q += scanspan);
+ height--;
+ }
+ }
+ rc->rc_bits ^= RC_CURSOR;
+}
+
+/*
+ * Allocate attribute. We just pack these into an integer.
+ */
+static int
+om_alloc_attr(id, fg, bg, flags, attrp)
+ void *id;
+ int fg, bg, flags;
+ long *attrp;
+{
+ if (flags & (WSATTR_HILIT | WSATTR_BLINK |
+ WSATTR_UNDERLINE | WSATTR_WSCOLORS))
+ return (EINVAL);
+ if (flags & WSATTR_REVERSE)
+ *attrp = 1;
+ else
+ *attrp = 0;
+ return (0);
+}
+
+void
+rcons_init(rc, mrow, mcol)
+ struct rcons *rc;
+ int mrow, mcol;
+{
+ struct raster *rp = rc->rc_sp;
+ int i;
+
+ rc->rc_font = &gallant19; /* 12x22 monospacing font */
+
+ /* Get distance to top and bottom of font from font origin */
+ rc->rc_font_ascent = -(rc->rc_font->chars)['a'].homey;
+
+ i = rp->height / rc->rc_font->height;
+ rc->rc_maxrow = min(i, mrow);
+
+ i = rp->width / rc->rc_font->width;
+ rc->rc_maxcol = min(i, mcol);
+
+ /* Center emulator screen (but align x origin to 32 bits) */
+ rc->rc_xorigin =
+ ((rp->width - rc->rc_maxcol * rc->rc_font->width) / 2) & ~ALIGNMASK;
+ rc->rc_yorigin =
+ (rp->height - rc->rc_maxrow * rc->rc_font->height) / 2;
+#if 0
+ /* Raster width used for row copies */
+ rc->rc_raswidth = rc->rc_maxcol * rc->rc_font->width;
+ if (rc->rc_raswidth & ALIGNMASK) {
+ /* Pad to 32 bits */
+ i = (rc->rc_raswidth + ALIGNMASK) & ~ALIGNMASK;
+ /* Make sure width isn't too wide */
+ if (rc->rc_xorigin + i <= rp->width)
+ rc->rc_raswidth = i;
+ }
+#endif
+ rc->rc_bits = 0;
+}
diff --git a/sys/arch/luna68k/dev/sio.c b/sys/arch/luna68k/dev/sio.c
new file mode 100644
index 00000000000..47cccc1e7c8
--- /dev/null
+++ b/sys/arch/luna68k/dev/sio.c
@@ -0,0 +1,131 @@
+/* $NetBSD: sio.c,v 1.1 2000/01/05 08:48:55 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: sio.c,v 1.1 2000/01/05 08:48:55 nisimura Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/cpu.h>
+#include <machine/autoconf.h>
+
+#include <luna68k/luna68k/isr.h>
+#include <luna68k/dev/siovar.h>
+
+static int sio_match __P((struct device *, struct cfdata *, void *));
+static void sio_attach __P((struct device *, struct device *, void *));
+static int sio_print __P((void *, const char *));
+
+const struct cfattach sio_ca = {
+ sizeof(struct sio_softc), sio_match, sio_attach
+};
+extern struct cfdriver sio_cd;
+
+static void nullintr __P((int));
+static int xsiointr __P((void *));
+
+static int
+sio_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct mainbus_attach_args *ma = aux;
+
+ if (strcmp(ma->ma_name, sio_cd.cd_name))
+ return 0;
+ if (badaddr((caddr_t)ma->ma_addr, 4))
+ return 0;
+ return 1;
+}
+
+static void
+sio_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct sio_softc *sc = (void *)self;
+ struct mainbus_attach_args *ma = aux;
+ struct sio_attach_args sio_args;
+ int channel;
+ extern int sysconsole; /* console: 0 for ttya, 1 for desktop */
+
+ printf(": 7201a\n");
+
+ sc->scp_ctl = (caddr_t)ma->ma_addr;
+ sc->scp_intr[0] = sc->scp_intr[1] = nullintr;
+ for (channel = 0; channel < 2; channel++) {
+ sio_args.channel = channel;
+ sio_args.hwflags = (channel == sysconsole);
+ config_found(self, (void *)&sio_args, sio_print);
+ }
+
+ isrlink_autovec(xsiointr, sc, ma->ma_ilvl, ISRPRI_TTYNOBUF);
+}
+
+static int
+sio_print(aux, name)
+ void *aux;
+ const char *name;
+{
+ struct sio_attach_args *args = aux;
+
+ if (name != NULL)
+ printf("%s: ", name);
+
+ if (args->channel != -1)
+ printf(" channel %d", args->channel);
+
+ return UNCONF;
+}
+
+static int
+xsiointr(arg)
+ void *arg;
+{
+ struct sio_softc *sc = arg;
+
+ (*sc->scp_intr[0])(0); /* 0: ttya system serial port */
+ (*sc->scp_intr[1])(1); /* 1: keyboard and mouse */
+ return 1;
+}
+
+static void nullintr(v) int v; { }
diff --git a/sys/arch/luna68k/dev/sioreg.h b/sys/arch/luna68k/dev/sioreg.h
new file mode 100644
index 00000000000..c6116f61a94
--- /dev/null
+++ b/sys/arch/luna68k/dev/sioreg.h
@@ -0,0 +1,136 @@
+/* $NetBSD: sioreg.h,v 1.1 2000/01/05 08:48:55 nisimura Exp $ */
+/*
+ * Copyright (c) 1992 OMRON Corporation.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * OMRON Corporation.
+ *
+ * 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.
+ *
+ * @(#)sioreg.h 8.1 (Berkeley) 6/10/93
+ */
+
+#define WR0 0x00
+#define WR1 0x01
+#define WR2 0x02
+#define WR3 0x03
+#define WR4 0x04
+#define WR5 0x05
+#define WR6 0x06
+#define WR7 0x07
+
+#define WR2A WR2
+#define WR2B (WR2|0x10)
+
+#define RR0 0x08
+#define RR1 0x09
+#define RR2 0x0A
+#define RR3 0x0B
+#define RR4 0x0C
+
+#define RR2A RR2
+#define RR2B (RR2|0x10)
+
+#define WR0_NOP 0x00 /* No Operation */
+#define WR0_SNDABRT 0x08 /* Send Abort (HDLC) */
+#define WR0_RSTINT 0x10 /* Reset External/Status Interrupt */
+#define WR0_CHANRST 0x18 /* Channel Reset */
+#define WR0_INTNXT 0x20 /* Enable Interrupt on Next Receive Character */
+#define WR0_RSTPEND 0x28 /* Reset Transmitter Interrput/DMA Pending */
+#define WR0_ERRRST 0x30 /* Error Reset */
+#define WR0_ENDINTR 0x38 /* End of Interrupt */
+
+#define WR1_ESENBL 0x01 /* External/Status Interrupt Enable */
+#define WR1_TXENBL 0x02 /* Tx Interrupt/DMA Enable */
+#define WR1_STATVEC 0x04 /* Status Affects Vector (Only Chan-B) */
+#define WR1_RXDSEBL 0x00 /* Rx Interrupt/DMA Disable */
+#define WR1_RXFIRST 0x08 /* Interrupt only First Character Received */
+#define WR1_RXALLS 0x10 /* Interrupt Every Characters Received (with Special Char.) */
+#define WR1_RXALL 0x18 /* Interrupt Every Characters Received (without Special Char.) */
+
+#define WR2_INTR_0 0x00 /* Interrupt Priority: RxA TxA RxB TxB E/SA E/SA */
+#define WR2_INTR_1 0x04 /* Interrupt Priority: RxA RxB TxA TxB E/SA E/SA */
+#define WR2_VEC85_1 0x00 /* 8085 Vectored Mode - 1 */
+#define WR2_VEC85_2 0x08 /* 8085 Vectored Mode - 2 */
+#define WR2_VEC86 0x10 /* 8086 Vectored */
+#define WR2_VEC85_3 0x18 /* 8085 Vectored Mode - 3 */
+
+#define WR3_RXENBL 0x01 /* Rx Enable */
+#define WR3_RXCRC 0x08 /* Rx CRC Check */
+#define WR3_AUTOEBL 0x20 /* Auto Enable (flow control for MODEM) */
+#define WR3_RX5BIT 0x00 /* Rx Bits/Character: 5 Bits */
+#define WR3_RX7BIT 0x40 /* Rx Bits/Character: 7 Bits */
+#define WR3_RX6BIT 0x80 /* Rx Bits/Character: 6 Bits */
+#define WR3_RX8BIT 0xc0 /* Rx Bits/Character: 8 Bits */
+
+#define WR4_NPARITY 0x00 /* No Parity */
+#define WR4_PARENAB 0x01 /* Parity Enable */
+#define WR4_OPARITY 0x01 /* Parity Odd */
+#define WR4_EPARITY 0x02 /* Parity Even */
+#define WR4_STOP1 0x04 /* Stop Bits (1bit) */
+#define WR4_STOP15 0x08 /* Stop Bits (1.5bit) */
+#define WR4_STOP2 0x0c /* Stop Bits (2bit) */
+#define WR4_BAUD96 0x40 /* Clock Rate (9600 BAUD) */
+#define WR4_BAUD48 0x80 /* Clock Rate (4800 BAUD) */
+#define WR4_BAUD24 0xc0 /* Clock Rate (2400 BAUD) */
+
+#define WR5_TXCRC 0x01 /* Tx CRC Check */
+#define WR5_RTS 0x02 /* Request To Send [RTS] */
+#define WR5_TXENBL 0x08 /* Transmit Enable */
+#define WR5_BREAK 0x10 /* Send Break [BRK] */
+#define WR5_TX5BIT 0x00 /* Tx Bits/Character: 5 Bits */
+#define WR5_TX7BIT 0x20 /* Tx Bits/Character: 7 Bits */
+#define WR5_TX6BIT 0x40 /* Tx Bits/Character: 6 Bits */
+#define WR5_TX8BIT 0x60 /* Tx Bits/Character: 8 Bits */
+#define WR5_DTR 0x80 /* Data Terminal Ready [DTR] */
+
+#define RR0_RXAVAIL 0x01 /* Rx Character Available */
+#define RR0_INTRPEND 0x02 /* Interrupt Pending (Channel-A Only) */
+#define RR0_TXEMPTY 0x04 /* Tx Buffer Empty */
+#define RR0_DCD 0x08 /* Data Carrier Detect [DCD] */
+#define RR0_SYNC 0x10 /* Synchronization */
+#define RR0_CTS 0x20 /* Clear To Send [CTS] */
+#define RR0_BREAK 0x80 /* Break Detected [BRK] */
+
+#define RR1_PARITY 0x10 /* Parity Error */
+#define RR1_OVERRUN 0x20 /* Data Over Run */
+#define RR1_FRAMING 0x40 /* Framing Error */
+
+#define RR_RXRDY 0x0100 /* Rx Character Available */
+#define RR_INTRPEND 0x0200 /* Interrupt Pending (Channel-A Only) */
+#define RR_TXRDY 0x0400 /* Tx Buffer Empty */
+#define RR_DCD 0x0800 /* Data Carrier Detect [DCD] */
+#define RR_SYNC 0x1000 /* Synchronization */
+#define RR_CTS 0x2000 /* Clear To Send [CTS] */
+#define RR_BREAK 0x8000 /* Break Detected */
+#define RR_PARITY 0x0010 /* Parity Error */
+#define RR_OVERRUN 0x0020 /* Data Over Run */
+#define RR_FRAMING 0x0040 /* Framing Error */
diff --git a/sys/arch/luna68k/dev/siotty.c b/sys/arch/luna68k/dev/siotty.c
new file mode 100644
index 00000000000..ff7bfc3eda3
--- /dev/null
+++ b/sys/arch/luna68k/dev/siotty.c
@@ -0,0 +1,623 @@
+/* $NetBSD: siotty.c,v 1.1 2000/01/05 08:48:55 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: siotty.c,v 1.1 2000/01/05 08:48:55 nisimura Exp $");
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.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/fcntl.h>
+#include <dev/cons.h>
+
+#include <machine/cpu.h>
+
+#include <luna68k/dev/sioreg.h>
+#include <luna68k/dev/siovar.h>
+
+#define TIOCM_BREAK 01000 /* non standard use */
+
+static const u_int8_t ch0_regs[6] = {
+ WR0_RSTINT, /* reset E/S interrupt */
+ WR1_RXALLS | WR1_TXENBL, /* Rx per char, Tx */
+ 0, /* */
+ WR3_RX8BIT | WR3_RXENBL, /* Rx */
+ WR4_BAUD96 | WR4_STOP1, /* Tx/Rx */
+ WR5_TX8BIT | WR5_TXENBL | WR5_DTR | WR5_RTS, /* Tx */
+};
+
+static struct speedtab siospeedtab[] = {
+ { 2400, WR4_BAUD24, },
+ { 4800, WR4_BAUD48, },
+ { 9600, WR4_BAUD96, },
+ { -1, 0, },
+};
+
+struct siotty_softc {
+ struct device sc_dev;
+ struct tty *sc_tty;
+ struct sioreg *sc_ctl;
+ u_int sc_flags;
+ u_int8_t sc_wr[6];
+};
+
+#include "siotty.h"
+cdev_decl(sio);
+static void siostart __P((struct tty *));
+static int sioparam __P((struct tty *, struct termios *));
+static void siottyintr __P((int));
+static int siomctl __P((struct siotty_softc *, int, int));
+
+static int siotty_match __P((struct device *, struct cfdata *, void *));
+static void siotty_attach __P((struct device *, struct device *, void *));
+
+const struct cfattach siotty_ca = {
+ sizeof(struct siotty_softc), siotty_match, siotty_attach
+};
+extern struct cfdriver siotty_cd;
+
+static int
+siotty_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct sio_attach_args *args = aux;
+
+ if (args->channel != 0) /* XXX allow tty on Ch.B XXX */
+ return 0;
+ return 1;
+}
+
+static void
+siotty_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct sio_softc *scp = (void *)parent;
+ struct siotty_softc *sc = (void *)self;
+ struct sio_attach_args *args = aux;
+
+ sc->sc_ctl = (struct sioreg *)scp->scp_ctl + args->channel;
+ bcopy(ch0_regs, sc->sc_wr, sizeof(ch0_regs));
+ scp->scp_intr[args->channel] = siottyintr;
+
+ if (args->hwflags == 1) {
+ printf(" (console)");
+ sc->sc_flags = TIOCFLAG_SOFTCAR;
+ }
+ else {
+ setsioreg(sc->sc_ctl, WR0, WR0_CHANRST);
+ setsioreg(sc->sc_ctl, WR2A, WR2_VEC86 | WR2_INTR_1);
+ setsioreg(sc->sc_ctl, WR2B, 0);
+ setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
+ setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]);
+ setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]);
+ setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]);
+ setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
+ }
+ setsioreg(sc->sc_ctl, WR1, sc->sc_wr[WR1]); /* now interrupt driven */
+
+ printf("\n");
+}
+
+/*-------------------- low level routine --------------------*/
+
+static void
+siottyintr(chan)
+ int chan;
+{
+ struct siotty_softc *sc;
+ struct sioreg *sio;
+ struct tty *tp;
+ unsigned int code;
+ int rr;
+
+ if (chan >= siotty_cd.cd_ndevs)
+ return;
+ sc = siotty_cd.cd_devs[chan];
+ tp = sc->sc_tty;
+ sio = sc->sc_ctl;
+ rr = getsiocsr(sio);
+#if defined(DDB)
+ if ((rr && RR_BREAK) && tp != NULL && tp->t_dev == cn_tab->cn_dev)
+ cpu_Debugger();
+ else
+#endif
+ if (rr & RR_RXRDY) {
+ do {
+ code = sio->sio_data;
+ if (rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) {
+ sio->sio_cmd = WR0_ERRRST;
+ if (sio->sio_stat & RR_FRAMING)
+ code |= TTY_FE;
+ else if (sio->sio_stat & RR_PARITY)
+ code |= TTY_PE;
+ }
+ if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0)
+ continue;
+ (*linesw[tp->t_line].l_rint)(code, tp);
+ } while ((rr = getsiocsr(sio)) & RR_RXRDY);
+ }
+ if (rr & RR_TXRDY) {
+ sio->sio_cmd = WR0_RSTPEND;
+ if (tp != NULL) {
+ tp->t_state &= ~(TS_BUSY|TS_FLUSH);
+ if (tp->t_line)
+ (*linesw[tp->t_line].l_start)(tp);
+ else
+ siostart(tp);
+ }
+ }
+}
+
+static void
+siostart(tp)
+ struct tty *tp;
+{
+ struct siotty_softc *sc = siotty_cd.cd_devs[minor(tp->t_dev)];
+ int s, c;
+
+ s = spltty();
+ if (tp->t_state & (TS_BUSY|TS_TIMEOUT|TS_TTSTOP))
+ goto out;
+ if (tp->t_outq.c_cc <= tp->t_lowat) {
+ if (tp->t_state & TS_ASLEEP) {
+ tp->t_state &= ~TS_ASLEEP;
+ wakeup((caddr_t)&tp->t_outq);
+ }
+ selwakeup(&tp->t_wsel);
+ }
+ if (tp->t_outq.c_cc == 0)
+ goto out;
+
+ tp->t_state |= TS_BUSY;
+ while (getsiocsr(sc->sc_ctl) & RR_TXRDY) {
+ if ((c = getc(&tp->t_outq)) == -1)
+ break;
+ sc->sc_ctl->sio_data = c;
+ }
+out:
+ splx(s);
+}
+
+void
+siostop(tp, flag)
+ struct tty *tp;
+ int flag;
+{
+ int s;
+
+ s = spltty();
+ if (TS_BUSY == (tp->t_state & (TS_BUSY|TS_TTSTOP))) {
+ /*
+ * Device is transmitting; must stop it.
+ */
+ tp->t_state |= TS_FLUSH;
+ }
+ splx(s);
+}
+
+static int
+sioparam(tp, t)
+ struct tty *tp;
+ struct termios *t;
+{
+ struct siotty_softc *sc = siotty_cd.cd_devs[minor(tp->t_dev)];
+ int wr4, s;
+
+ if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
+ return EINVAL;
+ wr4 = ttspeedtab(t->c_ospeed, siospeedtab);
+ if (wr4 < 0)
+ return EINVAL;
+
+ if (sc->sc_flags & TIOCFLAG_SOFTCAR) {
+ t->c_cflag |= CLOCAL;
+ t->c_cflag &= ~HUPCL;
+ }
+ if (sc->sc_flags & TIOCFLAG_CLOCAL)
+ t->c_cflag |= CLOCAL;
+
+ /*
+ * If there were no changes, don't do anything. This avoids dropping
+ * input and improves performance when all we did was frob things like
+ * VMIN and VTIME.
+ */
+ if (tp->t_ospeed == t->c_ospeed && tp->t_cflag == t->c_cflag)
+ return 0;
+
+ tp->t_ispeed = t->c_ispeed;
+ tp->t_ospeed = t->c_ospeed;
+ tp->t_cflag = t->c_cflag;
+
+ sc->sc_wr[WR3] &= 0x3f;
+ sc->sc_wr[WR5] &= 0x9f;
+ switch (tp->t_cflag & CSIZE) {
+ case CS7:
+ sc->sc_wr[WR3] |= WR3_RX7BIT; sc->sc_wr[WR5] |= WR5_TX7BIT;
+ break;
+ case CS8:
+ sc->sc_wr[WR3] |= WR3_RX8BIT; sc->sc_wr[WR5] |= WR5_TX8BIT;
+ break;
+ }
+ if (tp->t_cflag & PARENB) {
+ wr4 |= WR4_PARENAB;
+ if ((tp->t_cflag & PARODD) == 0)
+ wr4 |= WR4_EPARITY;
+ }
+ wr4 |= (tp->t_cflag & CSTOPB) ? WR4_STOP2 : WR4_STOP1;
+ sc->sc_wr[WR4] = wr4;
+
+ s = spltty();
+ setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]);
+ setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]);
+ setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]);
+ splx(s);
+
+ return 0;
+}
+
+static int
+siomctl(sc, control, op)
+ struct siotty_softc *sc;
+ int control, op;
+{
+ int val, s, wr5, rr;
+
+ val = 0;
+ if (control & TIOCM_BREAK)
+ val |= WR5_BREAK;
+ if (control & TIOCM_DTR)
+ val |= WR5_DTR;
+ if (control & TIOCM_RTS)
+ val |= WR5_RTS;
+ s = spltty();
+ wr5 = sc->sc_wr[WR5];
+ switch (op) {
+ case DMSET:
+ wr5 &= ~(WR5_BREAK|WR5_DTR|WR5_RTS);
+ /* FALLTHRU */
+ case DMBIS:
+ wr5 |= val;
+ break;
+ case DMBIC:
+ wr5 &= ~val;
+ break;
+ case DMGET:
+ val = 0;
+ rr = getsiocsr(sc->sc_ctl);
+ if (wr5 & WR5_DTR)
+ val |= TIOCM_DTR;
+ if (wr5 & WR5_RTS)
+ val |= TIOCM_RTS;
+ if (rr & RR_CTS)
+ val |= TIOCM_CTS;
+ if (rr & RR_DCD)
+ val |= TIOCM_CD;
+ goto done;
+ }
+ sc->sc_wr[WR5] = wr5;
+ setsioreg(sc->sc_ctl, WR5, wr5);
+ val = 0;
+ done:
+ splx(s);
+ return val;
+}
+
+/*-------------------- cdevsw[] interface --------------------*/
+
+int
+sioopen(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ struct siotty_softc *sc;
+ struct tty *tp;
+ int error;
+
+ if ((sc = siotty_cd.cd_devs[minor(dev)]) == NULL)
+ return ENXIO;
+ if ((tp = sc->sc_tty) == NULL) {
+ tp = sc->sc_tty = ttymalloc();
+ tty_attach(tp);
+ }
+ else if ((tp->t_state & TS_ISOPEN) && (tp->t_state & TS_XCLUDE)
+ && p->p_ucred->cr_uid != 0)
+ return EBUSY;
+
+ tp->t_oproc = siostart;
+ tp->t_param = sioparam;
+ tp->t_hwiflow = NULL /* XXX siohwiflow XXX */;
+ tp->t_dev = dev;
+ if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) {
+ struct termios t;
+
+ t.c_ispeed = t.c_ospeed = TTYDEF_SPEED;
+ t.c_cflag = TTYDEF_CFLAG;
+ tp->t_ospeed = 0; /* force register update */
+ (void)sioparam(tp, &t);
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_lflag = TTYDEF_LFLAG;
+ ttychars(tp);
+ ttsetwater(tp);
+ /* raise RTS and DTR here; but, DTR lead is not wired */
+ /* then check DCD condition; but, DCD lead is not wired */
+ tp->t_state |= TS_CARR_ON; /* assume detected all the time */
+#if 0
+ if ((sc->sc_flags & TIOCFLAG_SOFTCAR)
+ || (tp->t_cflag & MDMBUF)
+ || (getsiocsr(sc->sc_ctl) & RR_DCD))
+ tp->t_state |= TS_CARR_ON;
+ else
+ tp->t_state &= ~TS_CARR_ON;
+#endif
+ }
+
+ error = ttyopen(tp, 0, (flag & O_NONBLOCK));
+ if (error > 0)
+ return error;
+ return (*linesw[tp->t_line].l_open)(dev, tp);
+}
+
+int
+sioclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
+ struct tty *tp = sc->sc_tty;
+ int s;
+
+ (*linesw[tp->t_line].l_close)(tp, flag);
+
+ s = spltty();
+ siomctl(sc, TIOCM_BREAK, DMBIC);
+#if 0 /* because unable to feed DTR signal */
+ if ((tp->t_cflag & HUPCL)
+ || tp->t_wopen || (tp->t_state & TS_ISOPEN) == 0) {
+ siomctl(sc, TIOCM_DTR, DMBIC);
+ /* Yield CPU time to others for 1 second, then ... */
+ siomctl(sc, TIOCM_DTR, DMBIS);
+ }
+#endif
+ splx(s);
+ return ttyclose(tp);
+}
+
+int
+sioread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
+ struct tty *tp = sc->sc_tty;
+
+ return (*linesw[tp->t_line].l_read)(tp, uio, flag);
+}
+
+int
+siowrite(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
+ struct tty *tp = sc->sc_tty;
+
+ return (*linesw[tp->t_line].l_write)(tp, uio, flag);
+}
+
+int
+sioioctl(dev, cmd, data, flag, p)
+ dev_t dev;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
+ struct tty *tp = sc->sc_tty;
+ int error;
+
+ 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;
+
+ /* the last resort for TIOC ioctl tranversing */
+ switch (cmd) {
+ case TIOCSBRK: /* Set the hardware into BREAK condition */
+ siomctl(sc, TIOCM_BREAK, DMBIS);
+ break;
+ case TIOCCBRK: /* Clear the hardware BREAK condition */
+ siomctl(sc, TIOCM_BREAK, DMBIC);
+ break;
+ case TIOCSDTR: /* Assert DTR signal */
+ siomctl(sc, TIOCM_DTR|TIOCM_RTS, DMBIS);
+ break;
+ case TIOCCDTR: /* Clear DTR signal */
+ siomctl(sc, TIOCM_DTR|TIOCM_RTS, DMBIC);
+ break;
+ case TIOCMSET: /* Set modem state replacing current one */
+ siomctl(sc, *(int *)data, DMSET);
+ break;
+ case TIOCMGET: /* Return current modem state */
+ *(int *)data = siomctl(sc, 0, DMGET);
+ break;
+ case TIOCMBIS: /* Set individual bits of modem state */
+ siomctl(sc, *(int *)data, DMBIS);
+ break;
+ case TIOCMBIC: /* Clear individual bits of modem state */
+ siomctl(sc, *(int *)data, DMBIC);
+ break;
+ case TIOCSFLAGS: /* Instruct how serial port behaves */
+ sc->sc_flags = *(int *)data;
+ break;
+ case TIOCGFLAGS: /* Return current serial port state */
+ *(int *)data = sc->sc_flags;
+ break;
+ default:
+ return ENOTTY;
+ }
+ return 0;
+}
+
+/* ARSGUSED */
+struct tty *
+siotty(dev)
+ dev_t dev;
+{
+ struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
+
+ return sc->sc_tty;
+}
+
+/*-------------------- miscelleneous routine --------------------*/
+
+/* EXPORT */ void
+setsioreg(sio, regno, val)
+ struct sioreg *sio;
+ int regno, val;
+{
+ if (regno != 0)
+ sio->sio_cmd = regno; /* DELAY(); */
+ sio->sio_cmd = val; /* DELAY(); */
+}
+
+/* EXPORT */ int
+getsiocsr(sio)
+ struct sioreg *sio;
+{
+ int val;
+
+ val = sio->sio_stat << 8; /* DELAY(); */
+ sio->sio_cmd = 1; /* DELAY(); */
+ val |= sio->sio_stat; /* DELAY(); */
+ return val;
+}
+
+/*--------------------- console interface ----------------------*/
+
+void syscnattach __P((int));
+int syscngetc __P((dev_t));
+void syscnputc __P((dev_t, int));
+
+struct consdev syscons = {
+ NULL,
+ NULL,
+ syscngetc,
+ syscnputc,
+ nullcnpollc,
+ NODEV,
+ CN_REMOTE,
+};
+
+/* EXPORT */ void
+syscnattach(channel)
+ int channel;
+{
+/*
+ * Channel A is immediately initialized with 9600N1 right after cold
+ * boot/reset/poweron. ROM monitor emits one line message on CH.A.
+ */
+ struct sioreg *sio;
+ sio = (struct sioreg *)0x51000000 + channel;
+
+ syscons.cn_dev = makedev(7, channel);
+ cn_tab = &syscons;
+
+ setsioreg(sio, WR0, WR0_CHANRST);
+ setsioreg(sio, WR2A, WR2_VEC86 | WR2_INTR_1);
+ setsioreg(sio, WR2B, 0);
+ setsioreg(sio, WR0, ch0_regs[WR0]);
+ setsioreg(sio, WR4, ch0_regs[WR4]);
+ setsioreg(sio, WR3, ch0_regs[WR3]);
+ setsioreg(sio, WR5, ch0_regs[WR5]);
+ setsioreg(sio, WR0, ch0_regs[WR0]);
+}
+
+/* EXPORT */ int
+syscngetc(dev)
+ dev_t dev;
+{
+ struct sioreg *sio;
+ int s, c;
+
+ sio = (struct sioreg *)0x51000000 + ((int)dev & 0x1);
+ s = splhigh();
+ while ((getsiocsr(sio) & RR_RXRDY) == 0)
+ ;
+ c = sio->sio_data;
+ splx(s);
+
+ return c;
+}
+
+/* EXPORT */ void
+syscnputc(dev, c)
+ dev_t dev;
+ int c;
+{
+ struct sioreg *sio;
+ int s;
+
+ sio = (struct sioreg *)0x51000000 + ((int)dev & 0x1);
+ s = splhigh();
+ while ((getsiocsr(sio) & RR_TXRDY) == 0)
+ ;
+ sio->sio_cmd = WR0_RSTPEND;
+ sio->sio_data = c;
+ splx(s);
+}
diff --git a/sys/arch/luna68k/dev/siovar.h b/sys/arch/luna68k/dev/siovar.h
new file mode 100644
index 00000000000..b7e94598423
--- /dev/null
+++ b/sys/arch/luna68k/dev/siovar.h
@@ -0,0 +1,59 @@
+/* $NetBSD: siovar.h,v 1.1 2000/01/05 08:48:55 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+struct sio_softc {
+ struct device scp_dev;
+ caddr_t scp_ctl;
+ void (*scp_intr[2]) __P((int));
+};
+
+struct sio_attach_args {
+ int channel;
+ int hwflags;
+};
+
+struct sioreg {
+ volatile u_int8_t sio_data;
+ unsigned : 8;
+ volatile u_int8_t sio_cmd;
+ unsigned : 8;
+#define sio_stat sio_cmd
+};
+
+int getsiocsr __P((struct sioreg *));
+void setsioreg __P((struct sioreg *, int, int));
diff --git a/sys/arch/luna68k/dev/spc.c b/sys/arch/luna68k/dev/spc.c
new file mode 100644
index 00000000000..92fff867ee0
--- /dev/null
+++ b/sys/arch/luna68k/dev/spc.c
@@ -0,0 +1,104 @@
+/* $NetBSD: spc.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: spc.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/autoconf.h>
+
+#include <dev/scsipi/scsi_all.h>
+#include <dev/scsipi/scsipi_all.h>
+#include <dev/scsipi/scsi_message.h>
+#include <dev/scsipi/scsiconf.h>
+
+#include <dev/ic/mb89352reg.h>
+#include <dev/ic/mb89352var.h>
+
+#include <luna68k/luna68k/isr.h>
+
+static int spc_match __P((struct device *, struct cfdata *, void *));
+static void spc_attach __P((struct device *, struct device *, void *));
+
+const struct cfattach spc_ca = {
+ sizeof(struct spc_softc), spc_match, spc_attach
+};
+extern struct cfdriver spc_cd;
+
+static int
+spc_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct mainbus_attach_args *ma = aux;
+
+ if (strcmp(ma->ma_name, spc_cd.cd_name))
+ return 0;
+#if 0
+ if (badaddr((caddr_t)ma->ma_addr, 4))
+ return 0;
+ /* Experiments proved 2nd SPC address does NOT make a buserror. */
+#endif
+ return 1;
+}
+
+static void
+spc_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct spc_softc *sc = (void *)self;
+ struct mainbus_attach_args *ma = aux;
+
+ printf ("\n");
+
+ sc->sc_iot = /* XXX */ 0;
+ sc->sc_ioh = ma->ma_addr;
+ sc->sc_initiator = 7;
+
+ isrlink_autovec(spcintr, (void *)sc, ma->ma_ilvl, ISRPRI_BIO);
+
+ spcattach(sc);
+}
diff --git a/sys/arch/luna68k/dev/timekeeper.c b/sys/arch/luna68k/dev/timekeeper.c
new file mode 100644
index 00000000000..735ee347152
--- /dev/null
+++ b/sys/arch/luna68k/dev/timekeeper.c
@@ -0,0 +1,248 @@
+/* $NetBSD: timekeeper.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: timekeeper.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+
+#include <machine/cpu.h>
+
+#include <dev/clock_subr.h>
+#include <luna68k/luna68k/clockvar.h>
+#include <luna68k/dev/timekeeper.h>
+#include <machine/autoconf.h>
+
+#define YEAR0 1970 /* year offset */
+
+struct timekeeper_softc {
+ struct device sc_dev;
+ void *sc_clock, *sc_nvram;
+ int sc_nvramsize;
+ u_int8_t sc_image[2040];
+};
+
+/*
+ * BCD to decimal and decimal to BCD.
+ */
+#define FROMBCD(x) (((x) >> 4) * 10 + ((x) & 0xf))
+#define TOBCD(x) (((x) / 10 * 16) + ((x) % 10))
+
+static int clock_match __P((struct device *, struct cfdata *, void *));
+static void clock_attach __P((struct device *, struct device *, void *));
+
+const struct cfattach clock_ca = {
+ sizeof (struct timekeeper_softc), clock_match, clock_attach
+};
+extern struct cfdriver clock_cd;
+
+static void mkclock_get __P((struct device *, time_t, struct clock_ymdhms *));
+static void mkclock_set __P((struct device *, struct clock_ymdhms *));
+static void dsclock_get __P((struct device *, time_t, struct clock_ymdhms *));
+static void dsclock_set __P((struct device *, struct clock_ymdhms *));
+
+static struct clockfns mkclock_clockfns = {
+ NULL /* never used */, mkclock_get, mkclock_set,
+};
+
+static struct clockfns dsclock_clockfns = {
+ NULL /* never used */, dsclock_get, dsclock_set,
+};
+
+static int
+clock_match(parent, match, aux)
+ struct device *parent;
+ struct cfdata *match;
+ void *aux;
+{
+ struct mainbus_attach_args *ma = aux;
+
+ if (strcmp(ma->ma_name, clock_cd.cd_name))
+ return 0;
+ return 1;
+}
+
+static void
+clock_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct timekeeper_softc *sc = (void *)self;
+ struct mainbus_attach_args *ma = aux;
+ struct clockfns *clockwork;
+
+ switch (machtype) {
+ default:
+ case LUNA_I: /* Mostek MK48T02 */
+ sc->sc_clock = (void *)(ma->ma_addr + 2040);
+ sc->sc_nvram = (void *)ma->ma_addr;
+ sc->sc_nvramsize = 2040;
+ clockwork = &mkclock_clockfns;
+ printf(": mk48t02\n");
+ break;
+ case LUNA_II: /* Dallas DS1287A */
+ sc->sc_clock = (void *)ma->ma_addr;
+ sc->sc_nvram = (void *)(ma->ma_addr + 50);
+ sc->sc_nvramsize = 50;
+ clockwork = &dsclock_clockfns;
+ printf(": ds1287a\n");
+ break;
+ }
+ clockattach(&sc->sc_dev, clockwork);
+ memcpy(sc->sc_image, sc->sc_nvram, sc->sc_nvramsize);
+}
+
+/*
+ * Get the time of day, based on the clock's value and/or the base value.
+ */
+static void
+mkclock_get(dev, base, dt)
+ struct device *dev;
+ time_t base;
+ struct clock_ymdhms *dt;
+{
+ struct timekeeper_softc *sc = (void *)dev;
+ volatile u_int8_t *chiptime = (void *)sc->sc_clock;
+ int s;
+
+ s = splclock();
+ chiptime[MK_CSR] |= MK_CSR_READ; /* enable read (stop time) */
+ dt->dt_sec = FROMBCD(chiptime[MK_SEC]);
+ dt->dt_min = FROMBCD(chiptime[MK_MIN]);
+ dt->dt_hour = FROMBCD(chiptime[MK_HOUR]);
+ dt->dt_wday = FROMBCD(chiptime[MK_DOW]);
+ dt->dt_day = FROMBCD(chiptime[MK_DOM]);
+ dt->dt_mon = FROMBCD(chiptime[MK_MONTH]);
+ dt->dt_year = FROMBCD(chiptime[MK_YEAR]) + YEAR0;
+ chiptime[MK_CSR] &= ~MK_CSR_READ; /* time wears on */
+ splx(s);
+#ifdef TIMEKEEPER_DEBUG
+ printf("get %d/%d/%d %d:%d:%d\n",
+ dt->dt_year, dt->dt_mon, dt->dt_day,
+ dt->dt_hour, dt->dt_min, dt->dt_sec);
+#endif
+}
+
+/*
+ * Reset the TODR based on the time value.
+ */
+static void
+mkclock_set(dev, dt)
+ struct device *dev;
+ struct clock_ymdhms *dt;
+{
+ struct timekeeper_softc *sc = (void *)dev;
+ volatile u_int8_t *chiptime = (void *)sc->sc_clock;
+ volatile u_int8_t *stamp = (u_int8_t *)sc->sc_nvram + 0x10;
+ int s;
+
+ s = splclock();
+ chiptime[MK_CSR] |= MK_CSR_WRITE; /* enable write */
+ chiptime[MK_SEC] = TOBCD(dt->dt_sec);
+ chiptime[MK_MIN] = TOBCD(dt->dt_min);
+ chiptime[MK_HOUR] = TOBCD(dt->dt_hour);
+ chiptime[MK_DOW] = TOBCD(dt->dt_wday);
+ chiptime[MK_DOM] = TOBCD(dt->dt_day);
+ chiptime[MK_MONTH] = TOBCD(dt->dt_mon);
+ chiptime[MK_YEAR] = TOBCD(dt->dt_year - YEAR0);
+ chiptime[MK_CSR] &= ~MK_CSR_WRITE; /* load them up */
+ splx(s);
+#ifdef TIMEKEEPER_DEBUG
+ printf("set %d/%d/%d %d:%d:%d\n",
+ dt->dt_year, dt->dt_mon, dt->dt_day,
+ dt->dt_hour, dt->dt_min, dt->dt_sec);
+#endif
+
+ stamp[0] = 'R'; stamp[1] = 'T'; stamp[2] = 'C'; stamp[3] = '\0';
+}
+
+/*
+ * Get the time of day, based on the clock's value and/or the base value.
+ */
+static void
+dsclock_get(dev, base, dt)
+ struct device *dev;
+ time_t base;
+ struct clock_ymdhms *dt;
+{
+ struct timekeeper_softc *sc = (void *)dev;
+ volatile u_int8_t *chiptime = (void *)sc->sc_clock;
+ int s;
+
+ s = splclock();
+ /* update in progress; spin loop */
+ while (chiptime[MC_REGA] & MC_REGA_UIP)
+ ;
+ dt->dt_sec = chiptime[MC_SEC];
+ dt->dt_min = chiptime[MC_MIN];
+ dt->dt_hour = chiptime[MC_HOUR];
+ dt->dt_wday = chiptime[MC_DOW];
+ dt->dt_day = chiptime[MC_DOM];
+ dt->dt_mon = chiptime[MC_MONTH];
+ dt->dt_year = chiptime[MC_YEAR] + YEAR0;
+ splx(s);
+}
+
+/*
+ * Reset the TODR based on the time value.
+ */
+static void
+dsclock_set(dev, dt)
+ struct device *dev;
+ struct clock_ymdhms *dt;
+{
+ struct timekeeper_softc *sc = (void *)dev;
+ volatile u_int8_t *chiptime = (void *)sc->sc_clock;
+ int s;
+
+ s = splclock();
+ chiptime[MC_REGB] |= MC_REGB_SET; /* enable write */
+ chiptime[MC_SEC] = dt->dt_sec;
+ chiptime[MC_MIN] = dt->dt_min;
+ chiptime[MC_HOUR] = dt->dt_hour;
+ chiptime[MC_DOW] = dt->dt_wday;
+ chiptime[MC_DOM] = dt->dt_day;
+ chiptime[MC_MONTH] = dt->dt_mon;
+ chiptime[MC_YEAR] = dt->dt_year - YEAR0;
+ chiptime[MC_REGB] &= ~MC_REGB_SET; /* load them up */
+ splx(s);
+}
diff --git a/sys/arch/luna68k/dev/timekeeper.h b/sys/arch/luna68k/dev/timekeeper.h
new file mode 100644
index 00000000000..7c4f92ea55d
--- /dev/null
+++ b/sys/arch/luna68k/dev/timekeeper.h
@@ -0,0 +1,95 @@
+/* $NetBSD: timekeeper.h,v 1.1 2000/01/05 08:48:56 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Mostek MK48T02 for LUNA-1
+ */
+#define MK_CSR 0 /* control register */
+#define MK_SEC 1 /* seconds (0..59; BCD) */
+#define MK_MIN 2 /* minutes (0..59; BCD) */
+#define MK_HOUR 3 /* hour (0..23; BCD) */
+#define MK_DOW 4 /* weekday (1..7) */
+#define MK_DOM 5 /* day in month (1..31; BCD) */
+#define MK_MONTH 6 /* month (1..12; BCD) */
+#define MK_YEAR 7 /* year (0..99; BCD) */
+/* bits in cl_csr */
+#define MK_CSR_WRITE 0x80 /* want to write */
+#define MK_CSR_READ 0x40 /* want to read (freeze clock) */
+
+/*
+ * Dallas Semiconductor DS1287 -- mc146818 compatible, for LUNA-2
+ */
+#define MC_SEC 0x0 /* Time of year: seconds (0-59) */
+#define MC_ASEC 0x1 /* Alarm: seconds */
+#define MC_MIN 0x2 /* Time of year: minutes (0-59) */
+#define MC_AMIN 0x3 /* Alarm: minutes */
+#define MC_HOUR 0x4 /* Time of year: hour (see above) */
+#define MC_AHOUR 0x5 /* Alarm: hour */
+#define MC_DOW 0x6 /* Time of year: day of week (1-7) */
+#define MC_DOM 0x7 /* Time of year: day of month (1-31) */
+#define MC_MONTH 0x8 /* Time of year: month (1-12) */
+#define MC_YEAR 0x9 /* Time of year: year in century (0-99) */
+
+#define MC_REGA 0xa /* Control register A */
+#define MC_REGA_RSMASK 0x0f /* Interrupt rate select mask (see below) */
+#define MC_REGA_DVMASK 0x70 /* Divisor select mask (see below) */
+#define MC_REGA_UIP 0x80 /* Update in progress; read only. */
+
+#define MC_REGB 0xb /* Control register B */
+#define MC_REGB_DSE 0x01 /* Daylight Savings Enable */
+#define MC_REGB_24HR 0x02 /* 24-hour mode (AM/PM mode when clear) */
+#define MC_REGB_BINARY 0x04 /* Binary mode (BCD mode when clear) */
+#define MC_REGB_SQWE 0x08 /* Square Wave Enable */
+#define MC_REGB_UIE 0x10 /* Update End interrupt enable */
+#define MC_REGB_AIE 0x20 /* Alarm interrupt enable */
+#define MC_REGB_PIE 0x40 /* Periodic interrupt enable */
+#define MC_REGB_SET 0x80 /* Allow time to be set; stops updates */
+
+#define MC_REGC 0xc /* Control register C */
+/* MC_REGC_UNUSED 0x0f UNUSED */
+#define MC_REGC_UF 0x10 /* Update End interrupt flag */
+#define MC_REGC_AF 0x20 /* Alarm interrupt flag */
+#define MC_REGC_PF 0x40 /* Periodic interrupt flag */
+#define MC_REGC_IRQF 0x80 /* Interrupt request pending flag */
+
+#define MC_REGD 0xd /* Control register D */
+/* MC_REGD_UNUSED 0x7f UNUSED */
+#define MC_REGD_VRT 0x80 /* Valid RAM and Time bit */
+
+#define MC_NREGS 0xe /* 14 registers; CMOS follows */
+#define MC_NTODREGS 0xa /* 10 of those regs are for TOD and alarm */
diff --git a/sys/arch/luna68k/include/Makefile b/sys/arch/luna68k/include/Makefile
new file mode 100644
index 00000000000..0e4791a5f68
--- /dev/null
+++ b/sys/arch/luna68k/include/Makefile
@@ -0,0 +1,12 @@
+# $NetBSD: Makefile,v 1.1 2000/01/05 08:49:01 nisimura Exp $
+
+KDIR= /sys/arch/luna68k/include
+INCSDIR= /usr/include/luna68k
+
+INCS= ansi.h aout_machdep.h asm.h autoconf.h bswap.h bus.h cdefs.h \
+ cpu.h db_machdep.h disklabel.h endian.h float.h frame.h ieee.h \
+ ieeefp.h intr.h kcore.h limits.h math.h param.h pcb.h pmap.h \
+ proc.h profile.h psl.h pte.h ptrace.h reg.h setjmp.h signal.h \
+ stdarg.h trap.h types.h varargs.h vmparam.h
+
+.include <bsd.kinc.mk>
diff --git a/sys/arch/luna68k/include/ansi.h b/sys/arch/luna68k/include/ansi.h
new file mode 100644
index 00000000000..c162fe306b9
--- /dev/null
+++ b/sys/arch/luna68k/include/ansi.h
@@ -0,0 +1,4 @@
+/* $NetBSD: ansi.h,v 1.1 2000/01/05 08:48:56 nisimura Exp $ */
+
+/* Just use the common m68k definition */
+#include <m68k/ansi.h>
diff --git a/sys/arch/luna68k/include/aout_machdep.h b/sys/arch/luna68k/include/aout_machdep.h
new file mode 100644
index 00000000000..bb3732de756
--- /dev/null
+++ b/sys/arch/luna68k/include/aout_machdep.h
@@ -0,0 +1,8 @@
+/* $NetBSD: aout_machdep.h,v 1.1 2000/01/05 08:49:00 nisimura Exp $ */
+
+#ifndef _MACHINE_EXEC_H_
+#define _MACHINE_EXEC_H_
+
+#include <m68k/aout_machdep.h>
+
+#endif /* _MACHINE_EXEC_H_ */
diff --git a/sys/arch/luna68k/include/asm.h b/sys/arch/luna68k/include/asm.h
new file mode 100644
index 00000000000..054bd72b381
--- /dev/null
+++ b/sys/arch/luna68k/include/asm.h
@@ -0,0 +1,3 @@
+/* $NetBSD: asm.h,v 1.1 2000/01/05 08:48:57 nisimura Exp $ */
+
+#include <m68k/asm.h>
diff --git a/sys/arch/luna68k/include/autoconf.h b/sys/arch/luna68k/include/autoconf.h
new file mode 100644
index 00000000000..98847fe8ab6
--- /dev/null
+++ b/sys/arch/luna68k/include/autoconf.h
@@ -0,0 +1,43 @@
+/* $Id: autoconf.h,v 1.1 2000/01/05 08:49:01 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+struct mainbus_attach_args {
+ const char *ma_name;
+ paddr_t ma_addr;
+ int ma_ilvl;
+};
diff --git a/sys/arch/luna68k/include/bswap.h b/sys/arch/luna68k/include/bswap.h
new file mode 100644
index 00000000000..badc9b5d265
--- /dev/null
+++ b/sys/arch/luna68k/include/bswap.h
@@ -0,0 +1,3 @@
+/* $NetBSD: bswap.h,v 1.1 2000/01/05 08:49:00 nisimura Exp $ */
+
+#include <m68k/bswap.h>
diff --git a/sys/arch/luna68k/include/bus.h b/sys/arch/luna68k/include/bus.h
new file mode 100644
index 00000000000..522353fa249
--- /dev/null
+++ b/sys/arch/luna68k/include/bus.h
@@ -0,0 +1,604 @@
+/* $NetBSD: bus.h,v 1.1 2000/01/05 08:49:01 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (C) 1997 Scott Reynolds. 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
+ *
+ * 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_BUS_H_
+#define _MACHINE_BUS_H_
+
+/*
+ * Value for the luna68k bus space tag, not to be used directly by MI code.
+ */
+#define MACHINE_BUS_SPACE_MEM 0 /* space is mem space */
+
+/*
+ * Bus address and size types
+ */
+typedef u_long bus_addr_t;
+typedef u_long bus_size_t;
+
+/*
+ * Access methods for bus resources and address space.
+ */
+typedef int bus_space_tag_t;
+typedef u_long bus_space_handle_t;
+
+/*
+ * int bus_space_map __P((bus_space_tag_t t, bus_addr_t addr,
+ * bus_size_t size, int flags, bus_space_handle_t *bshp));
+ *
+ * Map a region of bus space.
+ */
+
+#define BUS_SPACE_MAP_CACHEABLE 0x01
+#define BUS_SPACE_MAP_LINEAR 0x02
+
+int bus_space_map __P((bus_space_tag_t, bus_addr_t, bus_size_t,
+ int, bus_space_handle_t *));
+
+/*
+ * void bus_space_unmap __P((bus_space_tag_t t,
+ * bus_space_handle_t bsh, bus_size_t size));
+ *
+ * Unmap a region of bus space.
+ */
+
+void bus_space_unmap __P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
+
+/*
+ * int bus_space_subregion __P((bus_space_tag_t t,
+ * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
+ * bus_space_handle_t *nbshp));
+ *
+ * Get a new handle for a subregion of an already-mapped area of bus space.
+ */
+
+int bus_space_subregion __P((bus_space_tag_t t, bus_space_handle_t bsh,
+ bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp));
+
+/*
+ * int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t, rstart,
+ * bus_addr_t rend, bus_size_t size, bus_size_t align,
+ * bus_size_t boundary, int flags, bus_addr_t *addrp,
+ * bus_space_handle_t *bshp));
+ *
+ * Allocate a region of bus space.
+ */
+
+int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart,
+ bus_addr_t rend, bus_size_t size, bus_size_t align,
+ bus_size_t boundary, int cacheable, bus_addr_t *addrp,
+ bus_space_handle_t *bshp));
+
+/*
+ * int bus_space_free __P((bus_space_tag_t t,
+ * bus_space_handle_t bsh, bus_size_t size));
+ *
+ * Free a region of bus space.
+ */
+
+void bus_space_free __P((bus_space_tag_t t, bus_space_handle_t bsh,
+ bus_size_t size));
+
+/*
+ * int mac68k_bus_space_probe __P((bus_space_tag_t t,
+ * bus_space_handle_t bsh, bus_size_t offset, int sz));
+ *
+ * Probe the bus at t/bsh/offset, using sz as the size of the load.
+ *
+ * This is a machine-dependent extension, and is not to be used by
+ * machine-independent code.
+ */
+
+int mac68k_bus_space_probe __P((bus_space_tag_t t,
+ bus_space_handle_t bsh, bus_size_t offset, int sz));
+
+/*
+ * u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset));
+ *
+ * Read a 1, 2, 4, or 8 byte quantity from bus space
+ * described by tag/handle/offset.
+ */
+
+#define bus_space_read_1(t, h, o) \
+ ((void) t, (*(volatile u_int8_t *)((h) + (o))))
+
+#define bus_space_read_2(t, h, o) \
+ ((void) t, (*(volatile u_int16_t *)((h) + (o))))
+
+#define bus_space_read_4(t, h, o) \
+ ((void) t, (*(volatile u_int32_t *)((h) + (o))))
+
+#if 0 /* Cause a link error for bus_space_read_8 */
+#define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!!
+#endif
+
+/*
+ * void bus_space_read_multi_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset,
+ * u_intN_t *addr, size_t count));
+ *
+ * Read `count' 1, 2, 4, or 8 byte quantities from bus space
+ * described by tag/handle/offset and copy into buffer provided.
+ */
+
+#define bus_space_read_multi_1(t, h, o, a, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,a1 ; \
+ movl %2,d0 ; \
+ 1: movb a0@,a1@+ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
+ "a0","a1","d0"); \
+} while (0)
+
+#define bus_space_read_multi_2(t, h, o, a, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,a1 ; \
+ movl %2,d0 ; \
+ 1: movw a0@,a1@+ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
+ "a0","a1","d0"); \
+} while (0)
+
+#define bus_space_read_multi_4(t, h, o, a, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,a1 ; \
+ movl %2,d0 ; \
+ 1: movl a0@,a1@+ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
+ "a0","a1","d0"); \
+} while (0)
+
+#if 0 /* Cause a link error for bus_space_read_multi_8 */
+#define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!!
+#endif
+
+/*
+ * void bus_space_read_region_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset,
+ * u_intN_t *addr, size_t count));
+ *
+ * Read `count' 1, 2, 4, or 8 byte quantities from bus space
+ * described by tag/handle and starting at `offset' and copy into
+ * buffer provided.
+ */
+
+#define bus_space_read_region_1(t, h, o, a, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,a1 ; \
+ movl %2,d0 ; \
+ 1: movb a0@+,a1@+ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
+ "a0","a1","d0"); \
+} while (0)
+
+#define bus_space_read_region_2(t, h, o, a, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,a1 ; \
+ movl %2,d0 ; \
+ 1: movw a0@+,a1@+ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
+ "a0","a1","d0"); \
+} while (0)
+
+#define bus_space_read_region_4(t, h, o, a, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,a1 ; \
+ movl %2,d0 ; \
+ 1: movl a0@+,a1@+ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
+ "a0","a1","d0"); \
+} while (0)
+
+#if 0 /* Cause a link error for bus_space_read_region_8 */
+#define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
+#endif
+
+/*
+ * void bus_space_write_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset,
+ * u_intN_t value));
+ *
+ * Write the 1, 2, 4, or 8 byte value `value' to bus space
+ * described by tag/handle/offset.
+ */
+
+#define bus_space_write_1(t, h, o, v) \
+ ((void) t, ((void)(*(volatile u_int8_t *)((h) + (o)) = (v))))
+
+#define bus_space_write_2(t, h, o, v) \
+ ((void) t, ((void)(*(volatile u_int16_t *)((h) + (o)) = (v))))
+
+#define bus_space_write_4(t, h, o, v) \
+ ((void) t, ((void)(*(volatile u_int32_t *)((h) + (o)) = (v))))
+
+#if 0 /* Cause a link error for bus_space_write_8 */
+#define bus_space_write_8 !!! bus_space_write_8 not implemented !!!
+#endif
+
+/*
+ * void bus_space_write_multi_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset,
+ * const u_intN_t *addr, size_t count));
+ *
+ * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
+ * provided to bus space described by tag/handle/offset.
+ */
+
+#define bus_space_write_multi_1(t, h, o, a, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,a1 ; \
+ movl %2,d0 ; \
+ 1: movb a1@+,a0@ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
+ "a0","a1","d0"); \
+} while (0)
+
+#define bus_space_write_multi_2(t, h, o, a, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,a1 ; \
+ movl %2,d0 ; \
+ 1: movw a1@+,a0@ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
+ "a0","a1","d0"); \
+} while (0)
+
+#define bus_space_write_multi_4(t, h, o, a, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,a1 ; \
+ movl %2,d0 ; \
+ 1: movl a1@+,a0@ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
+ "a0","a1","d0"); \
+} while (0)
+
+#if 0 /* Cause a link error for bus_space_write_8 */
+#define bus_space_write_multi_8(t, h, o, a, c) \
+ !!! bus_space_write_multi_8 unimplimented !!!
+#endif
+
+/*
+ * void bus_space_write_region_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset,
+ * const u_intN_t *addr, size_t count));
+ *
+ * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
+ * to bus space described by tag/handle starting at `offset'.
+ */
+
+#define bus_space_write_region_1(t, h, o, a, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,a1 ; \
+ movl %2,d0 ; \
+ 1: movb a1@+,a0@+ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
+ "a0","a1","d0"); \
+} while (0)
+
+#define bus_space_write_region_2(t, h, o, a, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,a1 ; \
+ movl %2,d0 ; \
+ 1: movw a1@+,a0@+ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
+ "a0","a1","d0"); \
+} while (0)
+
+#define bus_space_write_region_4(t, h, o, a, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,a1 ; \
+ movl %2,d0 ; \
+ 1: movl a1@+,a0@+ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
+ "a0","a1","d0"); \
+} while (0)
+
+#if 0 /* Cause a link error for bus_space_write_region_8 */
+#define bus_space_write_region_8 \
+ !!! bus_space_write_region_8 unimplemented !!!
+#endif
+
+/*
+ * void bus_space_set_multi_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
+ * size_t count));
+ *
+ * Write the 1, 2, 4, or 8 byte value `val' to bus space described
+ * by tag/handle/offset `count' times.
+ */
+
+#define bus_space_set_multi_1(t, h, o, val, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,d1 ; \
+ movl %2,d0 ; \
+ 1: movb d1,a0@ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h)+(o)), "g" ((u_long)val), \
+ "g" ((size_t)(c)) : \
+ "a0","d0","d1"); \
+} while (0)
+
+#define bus_space_set_multi_2(t, h, o, val, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,d1 ; \
+ movl %2,d0 ; \
+ 1: movw d1,a0@ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h)+(o)), "g" ((u_long)val), \
+ "g" ((size_t)(c)) : \
+ "a0","d0","d1"); \
+} while (0)
+
+#define bus_space_set_multi_4(t, h, o, val, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,d1 ; \
+ movl %2,d0 ; \
+ 1: movl d1,a0@ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h)+(o)), "g" ((u_long)val), \
+ "g" ((size_t)(c)) : \
+ "a0","d0","d1"); \
+} while (0)
+
+#if 0 /* Cause a link error for bus_space_set_multi_8 */
+#define bus_space_set_multi_8 \
+ !!! bus_space_set_multi_8 unimplemented !!!
+#endif
+
+/*
+ * void bus_space_set_region_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
+ * size_t count));
+ *
+ * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
+ * by tag/handle starting at `offset'.
+ */
+
+#define bus_space_set_region_1(t, h, o, val, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,d1 ; \
+ movl %2,d0 ; \
+ 1: movb d1,a0@+ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h)+(o)), "g" ((u_long)val), \
+ "g" ((size_t)(c)) : \
+ "a0","d0","d1"); \
+} while (0)
+
+#define bus_space_set_region_2(t, h, o, val, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,d1 ; \
+ movl %2,d0 ; \
+ 1: movw d1,a0@+ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h)+(o)), "g" ((u_long)val), \
+ "g" ((size_t)(c)) : \
+ "a0","d0","d1"); \
+} while (0)
+
+#define bus_space_set_region_4(t, h, o, val, c) do { \
+ (void) t; \
+ __asm __volatile (" \
+ movl %0,a0 ; \
+ movl %1,d1 ; \
+ movl %2,d0 ; \
+ 1: movl d1,a0@+ ; \
+ subql #1,d0 ; \
+ jne 1b" : \
+ : \
+ "r" ((h)+(o)), "g" ((u_long)val), \
+ "g" ((size_t)(c)) : \
+ "a0","d0","d1"); \
+} while (0)
+
+#if 0 /* Cause a link error for bus_space_set_region_8 */
+#define bus_space_set_region_8 \
+ !!! bus_space_set_region_8 unimplemented !!!
+#endif
+
+/*
+ * void bus_space_copy_N __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh1, bus_size_t off1,
+ * bus_space_handle_t bsh2, bus_size_t off2,
+ * size_t count));
+ *
+ * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
+ * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
+ */
+
+#define __MACHINE_copy_region_N(BYTES) \
+static __inline void __CONCAT(bus_space_copy_region_,BYTES) \
+ __P((bus_space_tag_t, \
+ bus_space_handle_t bsh1, bus_size_t off1, \
+ bus_space_handle_t bsh2, bus_size_t off2, \
+ bus_size_t count)); \
+ \
+static __inline void \
+__CONCAT(bus_space_copy_region_,BYTES)(t, h1, o1, h2, o2, c) \
+ bus_space_tag_t t; \
+ bus_space_handle_t h1, h2; \
+ bus_size_t o1, o2, c; \
+{ \
+ bus_size_t o; \
+ \
+ if ((h1 + o1) >= (h2 + o2)) { \
+ /* src after dest: copy forward */ \
+ for (o = 0; c != 0; c--, o += BYTES) \
+ __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
+ __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
+ } else { \
+ /* dest after src: copy backwards */ \
+ for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \
+ __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
+ __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
+ } \
+}
+__MACHINE_copy_region_N(1)
+__MACHINE_copy_region_N(2)
+__MACHINE_copy_region_N(4)
+#if 0 /* Cause a link error for bus_space_copy_8 */
+#define bus_space_copy_8 \
+ !!! bus_space_copy_8 unimplemented !!!
+#endif
+
+#undef __MACHINE_copy_region_N
+
+/*
+ * Bus read/write barrier methods.
+ *
+ * void bus_space_barrier __P((bus_space_tag_t tag,
+ * bus_space_handle_t bsh, bus_size_t offset,
+ * bus_size_t len, int flags));
+ *
+ * Note: the 680x0 does not currently require barriers, but we must
+ * provide the flags to MI code.
+ */
+#define bus_space_barrier(t, h, o, l, f) \
+ ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
+#define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
+#define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
+
+#define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
+
+#endif /* _MACHINE_BUS_H_ */
diff --git a/sys/arch/luna68k/include/cdefs.h b/sys/arch/luna68k/include/cdefs.h
new file mode 100644
index 00000000000..abca7f9dc14
--- /dev/null
+++ b/sys/arch/luna68k/include/cdefs.h
@@ -0,0 +1,8 @@
+/* $NetBSD: cdefs.h,v 1.1 2000/01/05 08:48:59 nisimura Exp $ */
+
+#ifndef _MACHINE_CDEFS_H_
+#define _MACHINE_CDEFS_H_
+
+#include <m68k/cdefs.h>
+
+#endif
diff --git a/sys/arch/luna68k/include/cpu.h b/sys/arch/luna68k/include/cpu.h
new file mode 100644
index 00000000000..f961418fd4e
--- /dev/null
+++ b/sys/arch/luna68k/include/cpu.h
@@ -0,0 +1,179 @@
+/* $Id: cpu.h,v 1.1 2000/01/05 08:48:57 nisimura Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 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.
+ *
+ * from: Utah $Hdr: cpu.h 1.16 91/03/25$
+ *
+ * @(#)cpu.h 8.4 (Berkeley) 1/5/94
+ */
+
+#ifndef _MACHINE_CPU_H
+#define _MACHINE_CPU_H
+
+/*
+ * Get common m68k CPU definitions.
+ */
+#include <m68k/cpu.h>
+#define M68K_MMU_MOTOROLA
+
+/*
+ * definitions of cpu-dependent requirements
+ * referenced in generic code
+ */
+#define cpu_swapin(p) /* nothing */
+#define cpu_wait(p) /* nothing */
+#define cpu_swapout(p) /* nothing */
+#define cpu_number() 0
+
+/*
+ * Arguments to hardclock and gatherstats encapsulate the previous
+ * machine state in an opaque clockframe. One the luna68k, we use
+ * what the hardware pushes on an interrupt (frame format 0).
+ */
+struct clockframe {
+ u_short sr; /* sr at time of interrupt */
+ u_long pc; /* pc at time of interrupt */
+ u_short vo; /* vector offset (4-word frame) */
+};
+
+#define CLKF_USERMODE(framep) (((framep)->sr & PSL_S) == 0)
+#define CLKF_BASEPRI(framep) (((framep)->sr & PSL_IPL) == 0)
+#define CLKF_PC(framep) ((framep)->pc)
+#if 0
+/* We would like to do it this way... */
+#define CLKF_INTR(framep) (((framep)->sr & PSL_M) == 0)
+#else
+/* but until we start using PSL_M, we have to do this instead */
+#define CLKF_INTR(framep) (0) /* XXX */
+#endif
+
+
+/*
+ * Preempt the current process if in interrupt from user mode,
+ * or after the current trap/syscall if in system mode.
+ */
+#define need_resched() { want_resched = 1; aston(); }
+
+/*
+ * Give a profiling tick to the current process when the user profiling
+ * buffer pages are invalid. On the hp300, 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; aston(); }
+
+/*
+ * Notify the current process (p) that it has a signal pending,
+ * process as soon as possible.
+ */
+#define signotify(p) aston()
+
+#define aston() (astpending = 1)
+
+extern int astpending; /* need to trap before returning to user mode */
+extern int want_resched; /* resched() was called */
+
+/*
+ * simulated software interrupt register
+ */
+extern unsigned char ssir;
+
+#define SIR_NET 0x1
+#define SIR_CLOCK 0x2
+
+#define siron(x) \
+ __asm __volatile ("orb %0,%1" : : "di" ((u_char)(x)), "g" (ssir))
+#define siroff(x) \
+ __asm __volatile ("andb %0,%1" : : "di" ((u_char)~(x)), "g" (ssir))
+
+#define setsoftnet() siron(SIR_NET)
+#define setsoftclock() siron(SIR_CLOCK)
+
+/*
+ * CTL_MACHDEP definitions.
+ */
+#define CPU_CONSDEV 1 /* dev_t: console terminal device */
+#define CPU_MAXID 2 /* number of valid machdep ids */
+
+#define CTL_MACHDEP_NAMES { \
+ { 0, 0 }, \
+ { "console_device", CTLTYPE_STRUCT }, \
+}
+
+/*
+ * Values for machtype
+ */
+#define LUNA_I 1
+#define LUNA_II 2
+
+#ifdef _KERNEL
+extern int machtype;
+extern char *intiobase, *intiolimit; /* XXX */
+extern u_int intiobase_phys, intiotop_phys; /* XXX */
+
+/* machdep.c functions */
+void dumpconf __P((void));
+void dumpsys __P((void));
+
+/* locore.s functions */
+struct pcb;
+struct fpframe;
+int suline __P((caddr_t, caddr_t));
+void savectx __P((struct pcb *));
+void switch_exit __P((struct proc *));
+void proc_trampoline __P((void));
+void loadustp __P((int));
+void m68881_save __P((struct fpframe *));
+void m68881_restore __P((struct fpframe *));
+
+/* machdep.c functions */
+int badaddr __P((caddr_t, int));
+
+/* sys_machdep.c functions */
+int cachectl1 __P((unsigned long, vaddr_t, size_t, struct proc *));
+int dma_cachectl __P((caddr_t, int));
+
+/* vm_machdep.c functions */
+void physaccess __P((caddr_t, caddr_t, int, int));
+void physunaccess __P((caddr_t, int));
+int kvtop __P((caddr_t));
+
+/* trap.c functions */
+void child_return __P((void *));
+#endif
+
+#endif /* _MACHINE_CPU_H */
diff --git a/sys/arch/luna68k/include/db_machdep.h b/sys/arch/luna68k/include/db_machdep.h
new file mode 100644
index 00000000000..111d79f8e05
--- /dev/null
+++ b/sys/arch/luna68k/include/db_machdep.h
@@ -0,0 +1,4 @@
+/* $NetBSD: db_machdep.h,v 1.1 2000/01/05 08:48:57 nisimura Exp $ */
+
+/* Just use the common m68k definition */
+#include <m68k/db_machdep.h>
diff --git a/sys/arch/luna68k/include/disklabel.h b/sys/arch/luna68k/include/disklabel.h
new file mode 100644
index 00000000000..3698badea8c
--- /dev/null
+++ b/sys/arch/luna68k/include/disklabel.h
@@ -0,0 +1,57 @@
+/* $NetBSD: disklabel.h,v 1.1 2000/01/05 08:48:57 nisimura Exp $ */
+
+/*
+ * Copyright (c) 1994 Christopher G. Demetriou
+ * 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 Christopher G. Demetriou.
+ * 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_
+
+#define LABELSECTOR 0 /* sector containing label */
+#define LABELOFFSET 64 /* offset of label in sector */
+#define MAXPARTITIONS 8 /* number of partitions */
+#define RAW_PART 2 /* raw partition: xx?c */
+
+/*
+ * This holds a copy of the whole label block, saved in here by
+ * readdisklabel() so that writedisklabel() can preserve the
+ * parts of the label block outside of the actual label.
+ * (i.e. Sun label info, bad block table, etc.)
+ */
+struct cpu_disklabel {
+ char cd_block[512];
+};
+
+#ifdef _KERNEL
+
+struct dkbad;
+int isbad __P((struct dkbad *bt, int, int, int));
+
+#endif /* _KERNEL */
+#endif /* _MACHINE_DISKLABEL_H_ */
diff --git a/sys/arch/luna68k/include/endian.h b/sys/arch/luna68k/include/endian.h
new file mode 100644
index 00000000000..cfa03d3ece8
--- /dev/null
+++ b/sys/arch/luna68k/include/endian.h
@@ -0,0 +1,4 @@
+/* $NetBSD: endian.h,v 1.1 2000/01/05 08:48:57 nisimura Exp $ */
+
+/* Just use the common m68k definition */
+#include <m68k/endian.h>
diff --git a/sys/arch/luna68k/include/float.h b/sys/arch/luna68k/include/float.h
new file mode 100644
index 00000000000..c6df94eb97c
--- /dev/null
+++ b/sys/arch/luna68k/include/float.h
@@ -0,0 +1,8 @@
+/* $NetBSD: float.h,v 1.1 2000/01/05 08:48:58 nisimura Exp $ */
+
+#ifndef _MACHINE_FLOAT_H_
+#define _MACHINE_FLOAT_H_
+
+#include <m68k/float.h>
+
+#endif
diff --git a/sys/arch/luna68k/include/frame.h b/sys/arch/luna68k/include/frame.h
new file mode 100644
index 00000000000..35d9fc3d028
--- /dev/null
+++ b/sys/arch/luna68k/include/frame.h
@@ -0,0 +1,3 @@
+/* $NetBSD: frame.h,v 1.1 2000/01/05 08:48:58 nisimura Exp $ */
+
+#include <m68k/frame.h>
diff --git a/sys/arch/luna68k/include/ieee.h b/sys/arch/luna68k/include/ieee.h
new file mode 100644
index 00000000000..36ded585747
--- /dev/null
+++ b/sys/arch/luna68k/include/ieee.h
@@ -0,0 +1,3 @@
+/* $NetBSD: ieee.h,v 1.1 2000/01/05 08:49:01 nisimura Exp $ */
+
+#include <m68k/ieee.h>
diff --git a/sys/arch/luna68k/include/ieeefp.h b/sys/arch/luna68k/include/ieeefp.h
new file mode 100644
index 00000000000..e29843eebbb
--- /dev/null
+++ b/sys/arch/luna68k/include/ieeefp.h
@@ -0,0 +1,4 @@
+/* $NetBSD: ieeefp.h,v 1.1 2000/01/05 08:49:00 nisimura Exp $ */
+
+/* Just use the common m68k definition */
+#include <m68k/ieeefp.h>
diff --git a/sys/arch/luna68k/include/intr.h b/sys/arch/luna68k/include/intr.h
new file mode 100644
index 00000000000..ed145ad8894
--- /dev/null
+++ b/sys/arch/luna68k/include/intr.h
@@ -0,0 +1,68 @@
+/* $NetBSD: intr.h,v 1.1 2000/01/05 08:49:01 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_INTR_H
+#define _MACHINE_INTR_H
+
+/*
+ * spl functions; all but spl0 are done in-line
+ */
+#include <machine/psl.h>
+
+#define splnone() spl0()
+#define spllowersoftclock() spl1()
+#define splsoftclock() splraise1()
+#define splsoftnet() splraise1()
+#define splbio() spl2()
+#define splnet() spl3()
+#define spltty() spl6()
+#define splimp() spl7()
+#define splclock() spl5()
+#define splstatclock() spl5()
+#define splvm() spl7()
+#define splhigh() spl7()
+#define splsched() spl7()
+
+/* watch out for side effects */
+#define splx(s) ((s) & PSL_IPL ? _spl(s) : spl0())
+
+#ifdef _KERNEL
+int spl0 __P((void));
+#endif /* _KERNEL */
+
+#endif /* _MACHINE_INTR_H */
diff --git a/sys/arch/luna68k/include/kcore.h b/sys/arch/luna68k/include/kcore.h
new file mode 100644
index 00000000000..614620c075b
--- /dev/null
+++ b/sys/arch/luna68k/include/kcore.h
@@ -0,0 +1,8 @@
+/* $NetBSD: kcore.h,v 1.1 2000/01/05 08:48:58 nisimura Exp $ */
+
+#ifndef _MACHINE_KCORE_H_
+#define _MACHINE_KCORE_H_
+
+#include <m68k/kcore.h>
+
+#endif
diff --git a/sys/arch/luna68k/include/limits.h b/sys/arch/luna68k/include/limits.h
new file mode 100644
index 00000000000..745d12c82f0
--- /dev/null
+++ b/sys/arch/luna68k/include/limits.h
@@ -0,0 +1,9 @@
+/* $NetBSD: limits.h,v 1.1 2000/01/05 08:48:58 nisimura Exp $ */
+
+#ifndef _MACHINE_LIMITS_H_
+#define _MACHINE_LIMITS_H_
+
+/* Just use the common m68k definition */
+#include <m68k/limits.h>
+
+#endif /* _MACHINE_LIMITS_H_ */
diff --git a/sys/arch/luna68k/include/math.h b/sys/arch/luna68k/include/math.h
new file mode 100644
index 00000000000..9266b1f4c12
--- /dev/null
+++ b/sys/arch/luna68k/include/math.h
@@ -0,0 +1,3 @@
+/* $NetBSD: math.h,v 1.1 2000/01/05 08:49:02 nisimura Exp $ */
+
+#include <m68k/math.h>
diff --git a/sys/arch/luna68k/include/param.h b/sys/arch/luna68k/include/param.h
new file mode 100644
index 00000000000..2d99d49932e
--- /dev/null
+++ b/sys/arch/luna68k/include/param.h
@@ -0,0 +1,81 @@
+/* $Id: param.h,v 1.1 2000/01/05 08:49:01 nisimura 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.
+ *
+ * from: Utah $Hdr: machparam.h 1.16 92/12/20$
+ *
+ * @(#)param.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _MACHINE_PARAM_H_
+#define _MACHINE_PARAM_H_
+
+#define _MACHINE luna68k
+#define MACHINE "luna68k"
+
+#define PGSHIFT 12 /* LOG2(NBPG) */
+#define KERNBASE 0x00000000 /* start of kernel virtual */
+
+#define SEGSHIFT 22 /* LOG2(NBSEG) */
+#define NBSEG (1 << SEGSHIFT) /* bytes/segment */
+#define SEGOFSET (NBSEG-1) /* byte offset into segment */
+
+#define UPAGES 3 /* pages of u-area */
+
+#include <m68k/param.h>
+
+#define NPTEPG (NBPG/(sizeof (pt_entry_t)))
+
+#ifndef MSGBUFSIZE
+#define MSGBUFSIZE NBPG /* default message buffer size */
+#endif
+
+#ifndef NKMEMCLUSTERS
+# define NKMEMCLUSTERS (2048 * 1024 / NBPG)
+#endif
+
+#include <machine/intr.h>
+
+#if defined(_KERNEL) && !defined(_LOCORE)
+#define delay(us) _delay((us)<<8)
+#define DELAY(n) delay(n)
+
+void _delay __P((unsigned));
+#endif /* _KERNEL && !_LOCORE */
+
+#endif /* !_MACHINE_PARAM_H_ */
diff --git a/sys/arch/luna68k/include/pcb.h b/sys/arch/luna68k/include/pcb.h
new file mode 100644
index 00000000000..2044ddcba80
--- /dev/null
+++ b/sys/arch/luna68k/include/pcb.h
@@ -0,0 +1,3 @@
+/* $NetBSD: pcb.h,v 1.1 2000/01/05 08:48:58 nisimura Exp $ */
+
+#include <m68k/pcb.h>
diff --git a/sys/arch/luna68k/include/pmap.h b/sys/arch/luna68k/include/pmap.h
new file mode 100644
index 00000000000..fba6454e3f4
--- /dev/null
+++ b/sys/arch/luna68k/include/pmap.h
@@ -0,0 +1,150 @@
+/* $NetBSD: pmap.h,v 1.1 2000/01/05 08:48:58 nisimura Exp $ */
+
+/*
+ * Copyright (c) 1987 Carnegie-Mellon University
+ * Copyright (c) 1991, 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.
+ *
+ * @(#)pmap.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _MACHINE_PMAP_H_
+#define _MACHINE_PMAP_H_
+
+#include <machine/pte.h>
+
+/*
+ * Pmap stuff
+ */
+struct pmap {
+ pt_entry_t *pm_ptab; /* KVA of page table */
+ st_entry_t *pm_stab; /* KVA of segment table */
+ int pm_stfree; /* 040: free lev2 blocks */
+ st_entry_t *pm_stpa; /* 040: ST phys addr */
+ short pm_sref; /* segment table ref count */
+ short pm_count; /* pmap reference count */
+ simple_lock_data_t pm_lock; /* lock on pmap */
+ struct pmap_statistics pm_stats; /* pmap statistics */
+ long pm_ptpages; /* more stats: PT pages */
+};
+
+typedef struct pmap *pmap_t;
+
+/*
+ * On the 040 we keep track of which level 2 blocks are already in use
+ * with the pm_stfree mask. Bits are arranged from LSB (block 0) to MSB
+ * (block 31). For convenience, the level 1 table is considered to be
+ * block 0.
+ *
+ * MAX[KU]L2SIZE control how many pages of level 2 descriptors are allowed.
+ * for the kernel and users. 8 implies only the initial "segment table"
+ * page is used. WARNING: don't change MAXUL2SIZE unless you can allocate
+ * physically contiguous pages for the ST in pmap.c!
+ */
+#define MAXKL2SIZE 32
+#define MAXUL2SIZE 8
+#define l2tobm(n) (1 << (n))
+#define bmtol2(n) (ffs(n) - 1)
+
+/*
+ * Macros for speed
+ */
+#define PMAP_ACTIVATE(pmap, loadhw) \
+{ \
+ if ((loadhw)) \
+ loadustp(m68k_btop((paddr_t)(pmap)->pm_stpa)); \
+}
+
+/*
+ * For each vm_page_t, there is a list of all currently valid virtual
+ * mappings of that page. An entry is a pv_entry, the list is pv_table.
+ */
+struct pv_entry {
+ struct pv_entry *pv_next; /* next pv_entry */
+ struct pmap *pv_pmap; /* pmap where mapping lies */
+ vaddr_t pv_va; /* virtual address for mapping */
+ st_entry_t *pv_ptste; /* non-zero if VA maps a PT page */
+ struct pmap *pv_ptpmap; /* if pv_ptste, pmap for PT page */
+ int pv_flags; /* flags */
+};
+
+#define PV_CI 0x01 /* header: all entries are cache inhibited */
+#define PV_PTPAGE 0x02 /* header: entry maps a page table page */
+
+struct pv_page;
+
+struct pv_page_info {
+ TAILQ_ENTRY(pv_page) pgi_list;
+ struct pv_entry *pgi_freelist;
+ int pgi_nfree;
+};
+
+/*
+ * This is basically:
+ * ((NBPG - sizeof(struct pv_page_info)) / sizeof(struct pv_entry))
+ */
+#define NPVPPG 170
+
+struct pv_page {
+ struct pv_page_info pvp_pgi;
+ struct pv_entry pvp_pv[NPVPPG];
+};
+
+#ifdef _KERNEL
+
+extern struct pmap kernel_pmap_store;
+
+#define pmap_kernel() (&kernel_pmap_store)
+#define active_pmap(pm) \
+ ((pm) == pmap_kernel() || (pm) == curproc->p_vmspace->vm_map.pmap)
+#define active_user_pmap(pm) \
+ (curproc && \
+ (pm) != pmap_kernel() && (pm) == curproc->p_vmspace->vm_map.pmap)
+
+extern struct pv_entry *pv_table; /* array of entries, one per page */
+
+#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
+#define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count)
+
+extern pt_entry_t *Sysmap;
+extern char *vmmap; /* map for mem, dumps, etc. */
+
+vaddr_t pmap_map __P((vaddr_t, paddr_t, paddr_t, int));
+void pmap_procwr __P((struct proc *, vaddr_t, size_t));
+#define PMAP_NEED_PROCWR
+
+#endif /* _KERNEL */
+
+#endif /* !_MACHINE_PMAP_H_ */
diff --git a/sys/arch/luna68k/include/proc.h b/sys/arch/luna68k/include/proc.h
new file mode 100644
index 00000000000..c237dbb9de9
--- /dev/null
+++ b/sys/arch/luna68k/include/proc.h
@@ -0,0 +1,53 @@
+/* $NetBSD: proc.h,v 1.1 2000/01/05 08:48:58 nisimura Exp $ */
+
+/*
+ * Copyright (c) 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.
+ *
+ * @(#)proc.h 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * Machine-dependent part of the proc structure for luna68k.
+ */
+struct mdproc {
+ int *md_regs; /* registers on current frame */
+ int md_flags; /* machine-dependent flags */
+};
+
+/* md_flags */
+#define MDP_STACKADJ 0x0002 /* frame SP adjusted, might have to
+ undo when system call returns
+ ERESTART. */
+#define MDP_HPUXTRACE 0x0004 /* being traced by HP-UX process */
+#define MDP_HPUXMMAP 0x0008 /* VA space is multiply mapped */
+#define MDP_CCBDATA 0x0010 /* copyback caching of data (68040) */
+#define MDP_CCBSTACK 0x0020 /* copyback caching of stack (68040) */
diff --git a/sys/arch/luna68k/include/profile.h b/sys/arch/luna68k/include/profile.h
new file mode 100644
index 00000000000..f3c16720929
--- /dev/null
+++ b/sys/arch/luna68k/include/profile.h
@@ -0,0 +1,3 @@
+/* $NetBSD: profile.h,v 1.1 2000/01/05 08:48:58 nisimura Exp $ */
+
+#include <m68k/profile.h>
diff --git a/sys/arch/luna68k/include/psl.h b/sys/arch/luna68k/include/psl.h
new file mode 100644
index 00000000000..a8136b7ee2a
--- /dev/null
+++ b/sys/arch/luna68k/include/psl.h
@@ -0,0 +1,3 @@
+/* $NetBSD: psl.h,v 1.1 2000/01/05 08:48:58 nisimura Exp $ */
+
+#include <m68k/psl.h>
diff --git a/sys/arch/luna68k/include/pte.h b/sys/arch/luna68k/include/pte.h
new file mode 100644
index 00000000000..2cf3139281c
--- /dev/null
+++ b/sys/arch/luna68k/include/pte.h
@@ -0,0 +1,152 @@
+/* $NetBSD: pte.h,v 1.1 2000/01/05 08:48:59 nisimura 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.
+ *
+ * from: Utah $Hdr: pte.h 1.13 92/01/20$
+ *
+ * @(#)pte.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _MACHINE_PTE_H_
+#define _MACHINE_PTE_H_
+
+/*
+ * m68k hardware segment/page table entries
+ */
+
+#if 0
+struct ste {
+ unsigned int sg_pfnum:20; /* page table frame number */
+ unsigned int :8; /* reserved at 0 */
+ unsigned int :1; /* reserved at 1 */
+ unsigned int sg_prot:1; /* write protect bit */
+ unsigned int sg_v:2; /* valid bits */
+};
+
+struct ste40 {
+ unsigned int sg_ptaddr:24; /* page table page addr */
+ unsigned int :4; /* reserved at 0 */
+ unsigned int sg_u; /* hardware modified (dirty) bit */
+ unsigned int sg_prot:1; /* write protect bit */
+ unsigned int sg_v:2; /* valid bits */
+};
+
+struct pte {
+ unsigned int pg_pfnum:20; /* page frame number or 0 */
+ unsigned int :3;
+ unsigned int pg_w:1; /* is wired */
+ unsigned int :1; /* reserved at zero */
+ unsigned int pg_ci:1; /* cache inhibit bit */
+ unsigned int :1; /* reserved at zero */
+ unsigned int pg_m:1; /* hardware modified (dirty) bit */
+ unsigned int pg_u:1; /* hardware used (reference) bit */
+ unsigned int pg_prot:1; /* write protect bit */
+ unsigned int pg_v:2; /* valid bit */
+};
+#endif
+
+typedef int st_entry_t; /* segment table entry */
+typedef int pt_entry_t; /* Mach page table entry */
+
+#define PT_ENTRY_NULL ((pt_entry_t *) 0)
+#define ST_ENTRY_NULL ((st_entry_t *) 0)
+
+#define SG_V 0x00000002 /* segment is valid */
+#define SG_NV 0x00000000
+#define SG_PROT 0x00000004 /* access protection mask */
+#define SG_RO 0x00000004
+#define SG_RW 0x00000000
+#define SG_U 0x00000008 /* modified bit (68040) */
+#define SG_FRAME 0xfffff000
+#define SG_IMASK 0xffc00000
+#define SG_ISHIFT 22
+#define SG_PMASK 0x003ff000
+#define SG_PSHIFT 12
+
+/* 68040 additions */
+#define SG4_MASK1 0xfe000000
+#define SG4_SHIFT1 25
+#define SG4_MASK2 0x01fc0000
+#define SG4_SHIFT2 18
+#define SG4_MASK3 0x0003f000
+#define SG4_SHIFT3 12
+#define SG4_ADDR1 0xfffffe00
+#define SG4_ADDR2 0xffffff00
+#define SG4_LEV1SIZE 128
+#define SG4_LEV2SIZE 128
+#define SG4_LEV3SIZE 64
+
+#define PG_V 0x00000001
+#define PG_NV 0x00000000
+#define PG_PROT 0x00000004
+#define PG_U 0x00000008
+#define PG_M 0x00000010
+#define PG_W 0x00000100
+#define PG_RO 0x00000004
+#define PG_RW 0x00000000
+#define PG_FRAME 0xfffff000
+#define PG_CI 0x00000040
+#define PG_SHIFT 12
+#define PG_PFNUM(x) (((x) & PG_FRAME) >> PG_SHIFT)
+
+/* 68040 additions */
+#define PG_CMASK 0x00000060 /* cache mode mask */
+#define PG_CWT 0x00000000 /* writethrough caching */
+#define PG_CCB 0x00000020 /* copyback caching */
+#define PG_CIS 0x00000040 /* cache inhibited serialized */
+#define PG_CIN 0x00000060 /* cache inhibited nonserialized */
+#define PG_SO 0x00000080 /* supervisor only */
+
+#define STSIZE (MAXUL2SIZE*SG4_LEV2SIZE*sizeof(st_entry_t))
+ /* user process segment table size */
+#define MAX_PTSIZE 0x400000 /* max size of UPT */
+#define MAX_KPTSIZE 0x100000 /* max memory to allocate to KPT */
+#define PTBASE 0x10000000 /* UPT map base address */
+#define PTMAXSIZE 0x70000000 /* UPT map maximum size */
+
+/*
+ * Kernel virtual address to page table entry and to physical address.
+ */
+#define kvtopte(va) \
+ (&Sysmap[((unsigned)(va) - VM_MIN_KERNEL_ADDRESS) >> PGSHIFT])
+#define ptetokv(pt) \
+ ((((pt_entry_t *)(pt) - Sysmap) << PGSHIFT) + VM_MIN_KERNEL_ADDRESS)
+#define kvtophys(va) \
+ ((kvtopte(va)->pg_pfnum << PGSHIFT) | ((int)(va) & PGOFSET))
+
+#endif /* !_MACHINE_PTE_H_ */
diff --git a/sys/arch/luna68k/include/ptrace.h b/sys/arch/luna68k/include/ptrace.h
new file mode 100644
index 00000000000..9b1c615ebe2
--- /dev/null
+++ b/sys/arch/luna68k/include/ptrace.h
@@ -0,0 +1,4 @@
+/* $NetBSD: ptrace.h,v 1.1 2000/01/05 08:48:59 nisimura Exp $ */
+
+/* Just use the common m68k definition */
+#include <m68k/ptrace.h>
diff --git a/sys/arch/luna68k/include/reg.h b/sys/arch/luna68k/include/reg.h
new file mode 100644
index 00000000000..d3ddf233958
--- /dev/null
+++ b/sys/arch/luna68k/include/reg.h
@@ -0,0 +1,8 @@
+/* $NetBSD: reg.h,v 1.1 2000/01/05 08:49:01 nisimura Exp $ */
+
+#ifndef _MACHINE_REG_H_
+#define _MACHINE_REG_H_
+
+#include <m68k/reg.h>
+
+#endif /* _MACHINE_REG_H_ */
diff --git a/sys/arch/luna68k/include/setjmp.h b/sys/arch/luna68k/include/setjmp.h
new file mode 100644
index 00000000000..deb4c0d04e0
--- /dev/null
+++ b/sys/arch/luna68k/include/setjmp.h
@@ -0,0 +1,3 @@
+/* $NetBSD: setjmp.h,v 1.1 2000/01/05 08:48:59 nisimura Exp $ */
+
+#include <m68k/setjmp.h>
diff --git a/sys/arch/luna68k/include/signal.h b/sys/arch/luna68k/include/signal.h
new file mode 100644
index 00000000000..ecf4f256b1d
--- /dev/null
+++ b/sys/arch/luna68k/include/signal.h
@@ -0,0 +1,4 @@
+/* $NetBSD: signal.h,v 1.1 2000/01/05 08:48:59 nisimura Exp $ */
+
+/* Just use the common m68k definition */
+#include <m68k/signal.h>
diff --git a/sys/arch/luna68k/include/stdarg.h b/sys/arch/luna68k/include/stdarg.h
new file mode 100644
index 00000000000..f5407abca7d
--- /dev/null
+++ b/sys/arch/luna68k/include/stdarg.h
@@ -0,0 +1,4 @@
+/* $NetBSD: stdarg.h,v 1.1 2000/01/05 08:48:59 nisimura Exp $ */
+
+/* Just use the common m68k definition */
+#include <m68k/stdarg.h>
diff --git a/sys/arch/luna68k/include/trap.h b/sys/arch/luna68k/include/trap.h
new file mode 100644
index 00000000000..4a60aeae33f
--- /dev/null
+++ b/sys/arch/luna68k/include/trap.h
@@ -0,0 +1,3 @@
+/* $NetBSD: trap.h,v 1.1 2000/01/05 08:48:59 nisimura Exp $ */
+
+#include <m68k/trap.h>
diff --git a/sys/arch/luna68k/include/types.h b/sys/arch/luna68k/include/types.h
new file mode 100644
index 00000000000..d610dde29b2
--- /dev/null
+++ b/sys/arch/luna68k/include/types.h
@@ -0,0 +1,8 @@
+/* $NetBSD: types.h,v 1.1 2000/01/05 08:48:59 nisimura Exp $ */
+
+#ifndef _MACHINE_TYPES_H_
+#define _MACHINE_TYPES_H_
+
+#include <m68k/types.h>
+
+#endif
diff --git a/sys/arch/luna68k/include/varargs.h b/sys/arch/luna68k/include/varargs.h
new file mode 100644
index 00000000000..9a199e76250
--- /dev/null
+++ b/sys/arch/luna68k/include/varargs.h
@@ -0,0 +1,4 @@
+/* $NetBSD: varargs.h,v 1.1 2000/01/05 08:49:00 nisimura Exp $ */
+
+/* Just use the common m68k definition */
+#include <m68k/varargs.h>
diff --git a/sys/arch/luna68k/include/vmparam.h b/sys/arch/luna68k/include/vmparam.h
new file mode 100644
index 00000000000..86f229a5582
--- /dev/null
+++ b/sys/arch/luna68k/include/vmparam.h
@@ -0,0 +1,142 @@
+/* $NetBSD: vmparam.h,v 1.1 2000/01/05 08:49:01 nisimura 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.
+ *
+ * from: Utah $Hdr: vmparam.h 1.16 91/01/18$
+ *
+ * @(#)vmparam.h 8.2 (Berkeley) 4/19/94
+ */
+
+#ifndef _MACHINE_VMPARAM_H_
+#define _MACHINE_VMPARAM_H_
+
+/*
+ * USRTEXT is the start of the user text/data space, while USRSTACK
+ * is the top (end) of the user stack.
+ */
+#define USRTEXT 8192
+#define USRSTACK VM_MAXUSER_ADDRESS
+
+/*
+ * 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
+
+/*
+ * Sizes of the system and user portions of the system page table.
+ */
+/* SYSPTSIZE IS SILLY; IT SHOULD BE COMPUTED AT BOOT TIME */
+#define SYSPTSIZE (2 * NPTEPG) /* 8mb */
+#define USRPTSIZE (1 * NPTEPG) /* 4mb */
+
+/*
+ * PTEs for mapping user space into the kernel for phyio operations.
+ * One page is enough to handle 4Mb of simultaneous raw IO operations.
+ */
+#ifndef USRIOSIZE
+#define USRIOSIZE (1 * NPTEPG) /* 4mb */
+#endif
+
+/*
+ * PTEs for system V style shared memory.
+ * This is basically slop for kmempt which we actually allocate (malloc) from.
+ */
+#ifndef SHMMAXPGS
+#define SHMMAXPGS 1024 /* 8mb */
+#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
+
+/* user/kernel map constants */
+#define VM_MIN_ADDRESS ((vaddr_t)0)
+#define VM_MAXUSER_ADDRESS ((vaddr_t)0xFFFC0000)
+#define VM_MAX_ADDRESS ((vaddr_t)0xFFFC0000)
+#define VM_MIN_KERNEL_ADDRESS ((vaddr_t)0)
+#define VM_MAX_KERNEL_ADDRESS ((vaddr_t)(0-NBPG))
+
+/* virtual sizes (bytes) for various kernel submaps */
+#define VM_MBUF_SIZE (NMBCLUSTERS*MCLBYTES)
+#define VM_KMEM_SIZE (NKMEMCLUSTERS*NBPG)
+#define VM_PHYS_SIZE (USRIOSIZE*NBPG)
+
+/* # of kernel PT pages (initial only, can grow dynamically) */
+#define VM_KERNEL_PT_PAGES ((vsize_t)2) /* XXX: SYSPTSIZE */
+
+/*
+ * Constants which control the way the VM system deals with memory segments.
+ * Only one physical contigous memory segment.
+ */
+#define VM_PHYSSEG_MAX 1
+#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH
+#define VM_PHYSSEG_NOADD
+
+#define VM_NFREELIST 1
+#define VM_FREELIST_DEFAULT 0
+
+/*
+ * pmap-specific data stored in the vm_physmem[] array.
+ */
+struct pmap_physseg {
+ struct pv_entry *pvent; /* pv table for this seg */
+ char *attrs; /* page attributes for this seg */
+};
+
+#endif /* _MACHINE_VMPARAM_H_ */
diff --git a/sys/arch/luna68k/luna68k/autoconf.c b/sys/arch/luna68k/luna68k/autoconf.c
new file mode 100644
index 00000000000..618aa401b9f
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/autoconf.c
@@ -0,0 +1,116 @@
+/* $NetBSD: autoconf.c,v 1.1 2000/01/05 08:49:02 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 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> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.1 2000/01/05 08:49:02 nisimura Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/map.h>
+#include <sys/buf.h>
+#include <sys/conf.h>
+#include <sys/reboot.h>
+#include <sys/device.h>
+
+#include <machine/disklabel.h>
+#include <machine/cpu.h>
+
+#include <luna68k/luna68k/isr.h>
+
+/*
+ * The following several variables are related to
+ * the configuration process, and are used in initializing
+ * the machine.
+ */
+struct device *booted_device; /* set by device drivers (if found) */
+
+/*
+ * Determine mass storage and memory configuration for a machine.
+ */
+void
+cpu_configure()
+{
+ booted_device = NULL; /* set by device drivers (if found) */
+
+ (void)splhigh();
+ isrinit();
+ if (config_rootfound("mainbus", NULL) == NULL)
+ panic("autoconfig failed, no root");
+
+ spl0();
+}
+
+void
+cpu_rootconf()
+{
+ printf("boot device: %s\n",
+ (booted_device) ? booted_device->dv_xname : "<unknown>");
+
+ setroot(booted_device, 0);
+}
+
+#if 0 /* What is this for !? */
+/*
+ * find a device matching "name" and unit number
+ */
+struct device *
+getdevunit(name, unit)
+ char *name;
+ int unit;
+{
+ struct device *dev = alldevs.tqh_first;
+ char num[10], fullname[16];
+ int lunit;
+
+ /* compute length of name and decimal expansion of unit number */
+ sprintf(num, "%d", unit);
+ lunit = strlen(num);
+ if (strlen(name) + lunit >= sizeof(fullname) - 1)
+ panic("config_attach: device name too long");
+
+ strcpy(fullname, name);
+ strcat(fullname, num);
+
+ while (strcmp(dev->dv_xname, fullname) != 0) {
+ if ((dev = dev->dv_list.tqe_next) == NULL)
+ return NULL;
+ }
+ return dev;
+}
+#endif
diff --git a/sys/arch/luna68k/luna68k/clock.c b/sys/arch/luna68k/luna68k/clock.c
new file mode 100644
index 00000000000..efe20469277
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/clock.c
@@ -0,0 +1,222 @@
+/* $NetBSD: clock.c,v 1.1 2000/01/05 08:49:02 nisimura Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1992, 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 and Ralph Campbell.
+ *
+ * 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: clock.c 1.18 91/01/21
+ *
+ * @(#)clock.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.1 2000/01/05 08:49:02 nisimura Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+
+#include <machine/cpu.h>
+
+#include <dev/clock_subr.h>
+#include <luna68k/luna68k/clockvar.h>
+
+#define CLOCK_LEVEL 5
+#include <luna68k/luna68k/isr.h>
+
+extern int machtype;
+
+static struct device *clockdev;
+static struct clockfns *clockfns;
+static int clockinitted;
+
+void
+clockattach(dev, fns)
+ struct device *dev;
+ struct clockfns *fns;
+{
+ /*
+ * Just bookkeeping.
+ */
+ if (clockfns != NULL)
+ panic("clockattach: multiple clocks");
+ clockdev = dev;
+ clockfns = fns;
+}
+
+/*
+ * Machine-dependent clock routines.
+ *
+ * Startrtclock restarts the real-time clock, which provides
+ * hardclock interrupts to kern_clock.c.
+ *
+ * Inittodr initializes the time of day hardware which provides
+ * date functions. Its primary function is to use some file
+ * system information in case the hardare clock lost state.
+ *
+ * Resettodr restores the time of day hardware after a time change.
+ */
+
+int clock_enable; /* XXX to be removed XXX */
+
+/*
+ * Start the real-time and statistics clocks. Leave stathz 0 since there
+ * are no other timers available.
+ */
+void
+cpu_initclocks()
+{
+ int s;
+
+ if (clockfns == NULL)
+ panic("cpu_initclocks: no clock attached");
+
+ if (machtype == LUNA_I)
+ hz = 60; /* LUNA-I is clocked at 60Hz, not 100Hz */
+
+ tick = 1000000 / hz; /* number of microseconds between interrupts */
+ tickfix = 1000000 - (hz * tick);
+ if (tickfix) {
+ int ftp;
+
+ ftp = min(ffs(tickfix), ffs(hz));
+ tickfix >>= (ftp - 1);
+ tickfixinterval = hz >> (ftp - 1);
+ }
+ /*
+ * Get the clock started.
+ */
+ s = splhigh();
+ /*
+ * XXX
+ * I guess it's necessary to program clock source with
+ * approprivate mode/value.
+ * XXX
+ */
+ clock_enable = 1;
+ splx(s);
+}
+
+/*
+ * We assume newhz is either stathz or profhz, and that neither will
+ * change after being set up above. Could recalculate intervals here
+ * but that would be a drag.
+ */
+void
+setstatclockrate(newhz)
+ int newhz;
+{
+ /* nothing we can do */
+}
+
+/*
+ * Initialze the time of day register, based on the time base which is, e.g.
+ * from a filesystem. Base provides the time to within six months,
+ * and the time of year clock (if any) provides the rest.
+ */
+void
+inittodr(base)
+ time_t base;
+{
+ struct clock_ymdhms dt;
+ time_t deltat;
+ int badbase;
+
+ if (base < 5*SECYR) {
+ printf("WARNING: preposterous time in file system");
+ /* read the system clock anyway */
+ base = 6*SECYR + 186*SECDAY + SECDAY/2;
+ badbase = 1;
+ } else
+ badbase = 0;
+
+ (*clockfns->cf_get)(clockdev, base, &dt);
+ clockinitted = 1;
+ /* simple sanity checks */
+ if (dt.dt_year < 1970 || dt.dt_mon < 1 || dt.dt_mon > 12
+ || dt.dt_day < 1 || dt.dt_day > 31
+ || dt.dt_hour > 23 || dt.dt_min > 59 || dt.dt_sec > 59) {
+ /*
+ * Believe the time in the file system for lack of
+ * anything better, resetting the TODR.
+ */
+ time.tv_sec = base;
+ if (!badbase) {
+ printf("WARNING: preposterous clock chip time");
+ resettodr();
+ }
+ goto bad;
+ }
+ /* now have days since Jan 1, 1970; the rest is easy... */
+ time.tv_sec = clock_ymdhms_to_secs(&dt);
+
+ if (!badbase) {
+ /*
+ * See if we gained/lost two or more days;
+ * if so, assume something is amiss.
+ */
+ deltat = time.tv_sec - base;
+ if (deltat < 0)
+ deltat = -deltat;
+ if (deltat < 2 * SECDAY)
+ return;
+ printf("WARNING: clock %s %d days",
+ time.tv_sec < base ? "lost" : "gained",
+ (int) (deltat / SECDAY));
+ }
+bad:
+ printf(" -- CHECK AND RESET THE DATE!\n");
+}
+
+/*
+ * Reset the TODR based on the time value; used when the TODR
+ * has a preposterous value and also when the time is reset
+ * by the stime system call. Also called when the TODR goes past
+ * TODRZERO + 100*(SECYEAR+2*SECDAY) (e.g. on Jan 2 just after midnight)
+ * to wrap the TODR around.
+ */
+void
+resettodr()
+{
+ struct clock_ymdhms dt;
+
+ if (!clockinitted)
+ return;
+ clock_secs_to_ymdhms(time.tv_sec, &dt);
+ (*clockfns->cf_set)(clockdev, &dt);
+}
diff --git a/sys/arch/luna68k/luna68k/clockvar.h b/sys/arch/luna68k/luna68k/clockvar.h
new file mode 100644
index 00000000000..69795a02570
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/clockvar.h
@@ -0,0 +1,53 @@
+/* $NetBSD: clockvar.h,v 1.1 2000/01/05 08:49:02 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 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.
+ */
+
+struct clock_ymdhms;
+
+/*
+ * clockfns structure:
+ *
+ * function switch used by chip-independent clock code, to access
+ * chip-dependent routines.
+ */
+struct clockfns {
+ void (*cf_init) __P((struct device *));
+ void (*cf_get) __P((struct device *, time_t, struct clock_ymdhms *));
+ void (*cf_set) __P((struct device *, struct clock_ymdhms *));
+};
+
+void clockattach __P((struct device *, struct clockfns *));
diff --git a/sys/arch/luna68k/luna68k/conf.c b/sys/arch/luna68k/luna68k/conf.c
new file mode 100644
index 00000000000..258d1256abe
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/conf.c
@@ -0,0 +1,257 @@
+/* $NetBSD: conf.c,v 1.1 2000/01/05 08:49:02 nisimura Exp $ */
+/* $NetBSD: conf.c,v 1.1 2000/01/05 08:49:02 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 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> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: conf.c,v 1.1 2000/01/05 08:49:02 nisimura Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/ioctl.h>
+#include <sys/tty.h>
+#include <sys/conf.h>
+#include <sys/vnode.h>
+
+bdev_decl(sw);
+#include "st.h"
+bdev_decl(st);
+#include "cd.h"
+bdev_decl(cd);
+#include "sd.h"
+bdev_decl(sd);
+#include "vnd.h"
+bdev_decl(vnd);
+#include "ccd.h"
+bdev_decl(ccd);
+#include "md.h"
+bdev_decl(md);
+
+struct bdevsw bdevsw[] =
+{
+ bdev_notdef(), /* 0 */
+ bdev_swap_init(1,sw), /* 1: swap pseudo-device */
+ bdev_disk_init(NSD,sd), /* 2: SCSI disk */
+ bdev_tape_init(NST,st), /* 3: SCSI tape */
+ bdev_disk_init(NCD,cd), /* 4: SCSI CD-ROM */
+ bdev_disk_init(NCCD,ccd), /* 5: concatenated disk driver */
+ bdev_disk_init(NVND,vnd), /* 6: vnode disk driver */
+ bdev_disk_init(NMD,md), /* 7: memory disk - for install tape */
+ bdev_lkm_dummy(), /* 8 */
+ bdev_lkm_dummy(), /* 9 */
+ bdev_lkm_dummy(), /* 10 */
+ bdev_lkm_dummy(), /* 11 */
+ bdev_lkm_dummy(), /* 12 */
+ bdev_lkm_dummy(), /* 13 */
+};
+int nblkdev = sizeof (bdevsw) / sizeof (bdevsw[0]);
+
+cdev_decl(cn);
+cdev_decl(ctty);
+#define mmread mmrw
+#define mmwrite mmrw
+cdev_decl(mm);
+cdev_decl(sw);
+#include "pty.h"
+#define ptstty ptytty
+#define ptsioctl ptyioctl
+cdev_decl(pts);
+#define ptctty ptytty
+#define ptcioctl ptyioctl
+cdev_decl(ptc);
+cdev_decl(log);
+#include "tun.h"
+cdev_decl(tun);
+cdev_decl(sd);
+cdev_decl(vnd);
+cdev_decl(ccd);
+dev_type_open(filedescopen);
+#include "bpfilter.h"
+cdev_decl(bpf);
+cdev_decl(st);
+cdev_decl(cd);
+#include "ch.h"
+cdev_decl(ch);
+cdev_decl(md);
+#include "ss.h"
+cdev_decl(ss);
+#include "uk.h"
+cdev_decl(uk);
+cdev_decl(fd);
+#include "ipfilter.h"
+cdev_decl(ipl);
+#include "siotty.h"
+cdev_decl(sio);
+
+#include "wsdisplay.h"
+cdev_decl(wsdisplay);
+#include "wskbd.h"
+cdev_decl(wskbd);
+#include "wsmouse.h"
+cdev_decl(wsmouse);
+
+#include "scsibus.h"
+cdev_decl(scsibus);
+
+struct cdevsw cdevsw[] =
+{
+ cdev_cn_init(1,cn), /* 0: virtual console */
+ cdev_ctty_init(1,ctty), /* 1: controlling terminal */
+ cdev_mm_init(1,mm), /* 2: /dev/{null,mem,kmem,...} */
+ cdev_swap_init(1,sw), /* 3: /dev/drum (swap pseudo-device) */
+ cdev_tty_init(NPTY,pts), /* 4: pseudo-tty slave */
+ cdev_ptc_init(NPTY,ptc), /* 5: pseudo-tty master */
+ cdev_log_init(1,log), /* 6: /dev/klog */
+ cdev_tty_init(NSIOTTY,sio), /* 7: ttya */
+ cdev_disk_init(NSD,sd), /* 8: SCSI disk */
+ cdev_tape_init(NST,st), /* 9: SCSI tape */
+ cdev_disk_init(NCD,cd), /* 10: SCSI CD-ROM */
+ cdev_ch_init(NCH,ch), /* 11: SCSI autochanger */
+ cdev_scanner_init(NSS,ss), /* 12: SCSI scanner */
+ cdev_uk_init(NUK,uk), /* 13: SCSI unknown */
+ cdev_disk_init(NCCD,ccd), /* 14: concatenated disk driver */
+ cdev_disk_init(NVND,vnd), /* 15: vnode disk */
+ cdev_disk_init(NMD,md), /* 16: memory disk driver */
+ cdev_mouse_init(NWSKBD, wskbd), /* 17: keyboards */
+ cdev_mouse_init(NWSMOUSE,
+ wsmouse), /* 18: mice */
+ cdev_wsdisplay_init(NWSDISPLAY,
+ wsdisplay), /* 19: frame buffers, etc. */
+ cdev_fd_init(1,filedesc), /* 20: file descriptor pseudo-dev */
+ cdev_bpftun_init(NBPFILTER,bpf),/* 21: berkeley packet filter */
+ cdev_bpftun_init(NTUN,tun), /* 22: network tunnel */
+ cdev_ipf_init(NIPFILTER,ipl), /* 23: ip-filter device */
+ cdev_lkm_init(NLKM,lkm), /* 24: loadable module driver */
+ cdev_lkm_dummy(), /* 25 */
+ cdev_lkm_dummy(), /* 26 */
+ cdev_lkm_dummy(), /* 27 */
+ cdev_lkm_dummy(), /* 28 */
+ cdev_lkm_dummy(), /* 30 */
+ cdev_lkm_dummy(), /* 31 */
+ cdev_scsibus_init(NSCSIBUS,scsibus), /* 32: SCSI bus */
+};
+int nchrdev = sizeof (cdevsw) / sizeof (cdevsw[0]);
+
+int mem_no = 2; /* major device number of memory special file */
+
+/*
+ * Swapdev is a fake device implemented
+ * in sw.c used only internally to get to swstrategy.
+ * It cannot be provided to the users, because the
+ * swstrategy routine munches the b_dev and b_blkno entries
+ * before calling the appropriate driver. This would horribly
+ * confuse, e.g. the hashing routines. Instead, /dev/drum is
+ * provided as a character (raw) device.
+ */
+dev_t swapdev = makedev(1, 0);
+
+/*
+ * Returns true if dev is /dev/mem or /dev/kmem.
+ */
+int
+iskmemdev(dev)
+ dev_t dev;
+{
+ return (major(dev) == mem_no && minor(dev) < 2);
+}
+
+/*
+ * Returns true if dev is /dev/zero.
+ */
+int
+iszerodev(dev)
+ dev_t dev;
+{
+ return (major(dev) == mem_no && minor(dev) == 12);
+}
+
+static int chrtoblktbl[] = {
+ /*VCHR*/ /*VBLK*/
+ /* 0 */ NODEV,
+ /* 1 */ NODEV,
+ /* 2 */ NODEV,
+ /* 3 */ NODEV,
+ /* 4 */ NODEV,
+ /* 5 */ NODEV,
+ /* 6 */ NODEV,
+ /* 7 */ NODEV,
+ /* 8 */ 2, /* sd */
+ /* 9 */ 3, /* st */
+ /* 10 */ 4, /* cd */
+ /* 11 */ NODEV,
+ /* 12 */ NODEV,
+ /* 13 */ NODEV,
+ /* 14 */ 5, /* ccd */
+ /* 15 */ 6, /* vnd */
+ /* 16 */ 7, /* md */
+ /* 17 */ NODEV,
+ /* 18 */ NODEV,
+ /* 19 */ NODEV,
+ /* 20 */ NODEV,
+ /* 21 */ NODEV,
+ /* 22 */ NODEV,
+ /* 23 */ NODEV,
+ /* 24 */ NODEV,
+ /* 25 */ NODEV,
+ /* 26 */ NODEV,
+ /* 27 */ NODEV,
+ /* 28 */ NODEV,
+ /* 29 */ NODEV,
+ /* 30 */ NODEV,
+ /* 31 */ NODEV,
+ /* 32 */ NODEV,
+};
+
+/*
+ * Convert a character device number to a block device number.
+ */
+dev_t
+chrtoblk(dev)
+ dev_t dev;
+{
+ int blkmaj;
+
+ if (major(dev) >= nchrdev
+ || major(dev) >= (sizeof(chrtoblktbl) / sizeof(chrtoblktbl[0])))
+ return (NODEV);
+ blkmaj = chrtoblktbl[major(dev)];
+ if (blkmaj == NODEV)
+ return (NODEV);
+ return (makedev(blkmaj, minor(dev)));
+}
diff --git a/sys/arch/luna68k/luna68k/db_memrw.c b/sys/arch/luna68k/luna68k/db_memrw.c
new file mode 100644
index 00000000000..06e536f1b12
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/db_memrw.c
@@ -0,0 +1,230 @@
+/* $NetBSD: db_memrw.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $ */
+/* $NetBSD: db_memrw.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Gordon W. Ross and Jason R. Thorpe.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: db_memrw.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $");
+
+/*
+ * Interface to the debugger for virtual memory read/write.
+ * This file is shared by DDB and KGDB, and must work even
+ * when only KGDB is included (thus no db_printf calls).
+ *
+ * To write in the text segment, we have to first make
+ * the page writable, do the write, then restore the PTE.
+ * For writes outside the text segment, and all reads,
+ * just do the access -- if it causes a fault, the debugger
+ * will recover with a longjmp to an appropriate place.
+ *
+ * ALERT! If you want to access device registers with a
+ * specific size, then the read/write functions have to
+ * make sure to do the correct sized pointer access.
+ *
+ * Modified from sun3 version for hp300 (and probably other m68ks, too)
+ * by Jason R. Thorpe <thorpej@NetBSD.ORG>.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+
+#include <machine/pte.h>
+#include <machine/db_machdep.h>
+#include <machine/cpu.h>
+#include <m68k/cacheops.h>
+
+#include <ddb/db_access.h>
+
+static void db_write_text __P((db_addr_t, size_t, char *));
+
+/*
+ * Read bytes from kernel address space for debugger.
+ * This used to check for valid PTEs, but now that
+ * traps in DDB work correctly, "Just Do It!"
+ */
+void
+db_read_bytes(addr, size, data)
+ db_addr_t addr;
+ size_t size;
+ char *data;
+{
+ char *src = (char*)addr;
+
+ if (size == 4) {
+ *((int*)data) = *((int*)src);
+ return;
+ }
+
+ if (size == 2) {
+ *((short*)data) = *((short*)src);
+ return;
+ }
+
+ while (size > 0) {
+ --size;
+ *data++ = *src++;
+ }
+}
+
+/*
+ * Write bytes somewhere in kernel text.
+ * Makes text page writable temporarily.
+ * We're probably a little to cache-paranoid.
+ */
+static void
+db_write_text(addr, size, data)
+ db_addr_t addr;
+ size_t size;
+ char *data;
+{
+ char *dst, *odst;
+ pt_entry_t *pte, oldpte, tmppte;
+ vaddr_t pgva;
+ int limit;
+
+ if (size == 0)
+ return;
+
+ dst = (char *)addr;
+
+ do {
+ /*
+ * Get the VA for the page.
+ */
+ pgva = m68k_trunc_page((u_long)dst);
+
+ /*
+ * Save this destination address, for TLB
+ * flush.
+ */
+ odst = dst;
+
+ /*
+ * Compute number of bytes that can be written
+ * with this mapping and subtract it from the
+ * total size.
+ */
+ limit = NBPG - ((u_long)dst & PGOFSET);
+ if (limit > size)
+ limit = size;
+ size -= limit;
+
+#ifdef M68K_MMU_HP
+ /*
+ * Flush the supervisor side of the VAC to
+ * prevent a cache hit on the old, read-only PTE.
+ * XXX Is this really necessary, or am I just
+ * paranoid?
+ */
+ if (ectype == EC_VIRT)
+ DCIS();
+#endif
+
+ /*
+ * Make the page writable. Note the mapping is
+ * cache-inhibited to save hair.
+ */
+ pte = kvtopte(pgva);
+ oldpte = *pte;
+
+ if ((oldpte & PG_V) == 0) {
+ printf(" address %p not a valid page\n", dst);
+ return;
+ }
+
+ tmppte = (oldpte & ~PG_RO) | PG_RW | PG_CI;
+ *pte = tmppte;
+ TBIS((vaddr_t)odst);
+
+ /*
+ * Page is now writable. Do as much access as we
+ * can in this page.
+ */
+ for (; limit > 0; limit--)
+ *dst++ = *data++;
+
+ /*
+ * Restore the old PTE.
+ */
+ *pte = oldpte;
+ TBIS((vaddr_t)odst);
+ } while (size != 0);
+
+ /*
+ * Invalidate the instruction cache so our changes
+ * take effect.
+ */
+ ICIA();
+}
+
+/*
+ * Write bytes to kernel address space for debugger.
+ */
+extern char kernel_text[], etext[];
+void
+db_write_bytes(addr, size, data)
+ db_addr_t addr;
+ size_t size;
+ char *data;
+{
+ char *dst = (char *)addr;
+
+ /* If any part is in kernel text, use db_write_text() */
+ if ((dst < etext) && ((dst + size) > kernel_text)) {
+ db_write_text(addr, size, data);
+ return;
+ }
+
+ if (size == 4) {
+ *((int*)dst) = *((int*)data);
+ return;
+ }
+
+ if (size == 2) {
+ *((short*)dst) = *((short*)data);
+ return;
+ }
+
+ while (size > 0) {
+ --size;
+ *dst++ = *data++;
+ }
+}
diff --git a/sys/arch/luna68k/luna68k/disksubr.c b/sys/arch/luna68k/luna68k/disksubr.c
new file mode 100644
index 00000000000..f2033e6bbee
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/disksubr.c
@@ -0,0 +1,487 @@
+/* $NetBSD: disksubr.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $ */
+/* $NetBSD: disksubr.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Gordon W. Ross
+ * Copyright (c) 1994 Theo de Raadt
+ * Copyright (c) 1982, 1986, 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.
+ *
+ * Credits:
+ * This file was based mostly on the i386/disksubr.c file:
+ * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
+ * The functions: disklabel_sun_to_bsd, disklabel_bsd_to_sun
+ * were originally taken from arch/sparc/scsi/sun_disklabel.c
+ * (which was written by Theo de Raadt) and then substantially
+ * rewritten by Gordon W. Ross.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/device.h>
+#include <sys/disklabel.h>
+#include <sys/disk.h>
+#include <sys/dkbad.h>
+
+#include <dev/sun/disklabel.h>
+
+/* XXX encoding of disk minor numbers, should be elsewhere... */
+#define dkpart(dev) (minor(dev) & 7)
+
+#define b_cylin b_resid
+
+#if LABELSECTOR != 0
+#error "Default value of LABELSECTOR no longer zero?"
+#endif
+
+static char * disklabel_om_to_bsd(char *, struct disklabel *);
+static int disklabel_bsd_to_om(struct disklabel *, char *);
+#define OM_DKMAGIC 0xdabe
+
+/*
+ * Attempt to read a disk label from a device
+ * using the indicated stategy routine.
+ * The label must be partly set up before this:
+ * secpercyl, secsize and anything required for a block i/o read
+ * operation in the driver's strategy/start routines
+ * must be filled in before calling us.
+ *
+ * Return buffer for use in signalling errors if requested.
+ *
+ * Returns null on success and an error string on failure.
+ */
+char *
+readdisklabel(dev, strat, lp, clp)
+ dev_t dev;
+ void (*strat) __P((struct buf *));
+ struct disklabel *lp;
+ struct cpu_disklabel *clp;
+{
+ struct buf *bp;
+ struct disklabel *dlp;
+ struct sun_disklabel *slp;
+ int error;
+
+ /* minimal requirements for archtypal disk label */
+ if (lp->d_secperunit == 0)
+ lp->d_secperunit = 0x1fffffff;
+ lp->d_npartitions = 1;
+ if (lp->d_partitions[0].p_size == 0)
+ lp->d_partitions[0].p_size = 0x1fffffff;
+ lp->d_partitions[0].p_offset = 0;
+
+ /* obtain buffer to probe drive with */
+ bp = geteblk((int)lp->d_secsize);
+
+ /* next, dig out disk label */
+ bp->b_dev = dev;
+ bp->b_blkno = LABELSECTOR;
+ bp->b_cylin = 0;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ (*strat)(bp);
+
+ /* if successful, locate disk label within block and validate */
+ error = biowait(bp);
+ if (!error) {
+ /* Save the whole block in case it has info we need. */
+ bcopy(bp->b_un.b_addr, clp->cd_block, sizeof(clp->cd_block));
+ }
+ bp->b_flags = B_INVAL | B_AGE | B_READ;
+ brelse(bp);
+ if (error)
+ return ("disk label read error");
+
+ /* Check for a UniOS-B disk label (for PROM compatibility). */
+ slp = (struct sun_disklabel *)clp->cd_block;
+ if (slp->sl_magic == OM_DKMAGIC) {
+ return (disklabel_om_to_bsd(clp->cd_block, lp));
+ }
+
+ /* Check for a NetBSD disk label (PROM can not boot it). */
+ dlp = (struct disklabel *)(clp->cd_block + LABELOFFSET);
+ if (dlp->d_magic == DISKMAGIC) {
+ if (dkcksum(dlp))
+ return ("NetBSD disk label corrupted");
+ *lp = *dlp; /* struct assignment */
+ return (NULL);
+ }
+
+ memset(clp->cd_block, 0, sizeof(clp->cd_block));
+ return ("no disk label");
+}
+
+/*
+ * Check new disk label for sensibility
+ * before setting it.
+ */
+int
+setdisklabel(olp, nlp, openmask, clp)
+ struct disklabel *olp, *nlp;
+ u_long openmask;
+ struct cpu_disklabel *clp;
+{
+ struct partition *opp, *npp;
+ int i;
+
+ /* 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 (openmask != 0) {
+ i = ffs(openmask) - 1;
+ 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);
+ }
+
+ /* We did not modify the new label, so the checksum is OK. */
+ *olp = *nlp;
+ return (0);
+}
+
+
+/*
+ * Write disk label back to device after modification.
+ * Current label is already in clp->cd_block[]
+ */
+int
+writedisklabel(dev, strat, lp, clp)
+ dev_t dev;
+ void (*strat) __P((struct buf *));
+ struct disklabel *lp;
+ struct cpu_disklabel *clp;
+{
+ struct buf *bp;
+ int error;
+
+ error = disklabel_bsd_to_om(lp, clp->cd_block);
+ if (error)
+ return(error);
+
+#if 0 /* XXX - Allow writing NetBSD disk labels? */
+ {
+ struct disklabel *dlp;
+ dlp = (struct disklabel *)(clp->cd_block + LABELOFFSET);
+ *dlp = *lp; /* struct assignment */
+ }
+#endif
+
+ /* Get a buffer and copy the new label into it. */
+ bp = geteblk((int)lp->d_secsize);
+ bcopy(clp->cd_block, bp->b_un.b_addr, sizeof(clp->cd_block));
+
+ /* Write out the updated label. */
+ bp->b_dev = dev;
+ bp->b_blkno = LABELSECTOR;
+ bp->b_cylin = 0;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_WRITE;
+ (*strat)(bp);
+ error = biowait(bp);
+ brelse(bp);
+
+ return (error);
+}
+
+/*
+ * Determine the size of the transfer, and make sure it is
+ * within the boundaries of the partition. Adjust transfer
+ * if needed, and signal errors or early completion.
+ */
+int
+bounds_check_with_label(bp, lp, wlabel)
+ struct buf *bp;
+ struct disklabel *lp;
+ int wlabel;
+{
+ struct partition *p;
+ int sz, maxsz;
+
+ p = lp->d_partitions + dkpart(bp->b_dev);
+ maxsz = p->p_size;
+ sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
+
+ /* overwriting disk label ? */
+ /* XXX should also protect bootstrap in first 8K */
+ /* XXX PR#2598: labelsect is always sector zero. */
+ if (((bp->b_blkno + p->p_offset) <= LABELSECTOR) &&
+ ((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);
+}
+
+/*
+ * This function appears to be called by each disk driver.
+ * Aparently this is to give this MD code a chance to do
+ * additional "device registration" types of work. (?)
+ * For example, the sparc port uses this to record the
+ * device node for the PROM-specified boot device.
+ */
+void
+dk_establish(dk, dev)
+ struct disk *dk;
+ struct device *dev;
+{
+}
+
+/************************************************************************
+ *
+ * The rest of this was taken from arch/sparc/scsi/sun_disklabel.c
+ * and then substantially rewritten by Gordon W. Ross
+ *
+ ************************************************************************/
+
+/* What partition types to assume for Sun disklabels: */
+static u_char
+sun_fstypes[8] = {
+ FS_BSDFFS, /* a */
+ FS_SWAP, /* b */
+ FS_OTHER, /* c - whole disk */
+ FS_BSDFFS, /* d */
+ FS_BSDFFS, /* e */
+ FS_BSDFFS, /* f */
+ FS_BSDFFS, /* g */
+ FS_BSDFFS, /* h */
+};
+
+/*
+ * Given a UniOS-B disk label, set lp to a BSD disk label.
+ * Returns NULL on success, else an error string.
+ *
+ * The BSD label is cleared out before this is called.
+ */
+static char *
+disklabel_om_to_bsd(cp, lp)
+ char *cp;
+ struct disklabel *lp;
+{
+ struct sun_disklabel *sl;
+ struct partition *npp;
+ struct sun_dkpart *spp;
+ int i, secpercyl;
+ u_short cksum, *sp1, *sp2;
+
+ sl = (struct sun_disklabel *)cp;
+
+ /* Verify the XOR check. */
+ sp1 = (u_short *)sl;
+ sp2 = (u_short *)(sl + 1);
+ cksum = 0;
+ while (sp1 < sp2)
+ cksum ^= *sp1++;
+ if (cksum != 0)
+ return ("UNIOS-B disk label, bad checksum");
+
+ memset((caddr_t)lp, 0, sizeof(struct disklabel));
+
+ /* Format conversion. */
+ lp->d_magic = DISKMAGIC;
+ lp->d_magic2 = DISKMAGIC;
+ memcpy(lp->d_packname, sl->sl_text, sizeof(lp->d_packname));
+
+ lp->d_type = DTYPE_SCSI;
+ lp->d_secsize = 512;
+ lp->d_nsectors = sl->sl_nsectors;
+ lp->d_ntracks = sl->sl_ntracks;
+ lp->d_ncylinders = sl->sl_ncylinders;
+
+ secpercyl = sl->sl_nsectors * sl->sl_ntracks;
+ lp->d_secpercyl = secpercyl;
+ lp->d_secperunit = secpercyl * sl->sl_ncylinders;
+
+ lp->d_rpm = 3600; /* XXX */
+ lp->d_interleave = 1; /* XXX */
+
+ lp->d_npartitions = 8;
+ /* These are as defined in <ufs/ffs/fs.h> */
+ lp->d_bbsize = 8192; /* XXX */
+ lp->d_sbsize = 8192; /* XXX */
+
+ for (i = 0; i < 8; i++) {
+ spp = &sl->sl_part[i];
+ npp = &lp->d_partitions[i];
+ npp->p_offset = spp->sdkp_cyloffset * secpercyl;
+ npp->p_size = spp->sdkp_nsectors;
+ if (npp->p_size == 0)
+ npp->p_fstype = FS_UNUSED;
+ else {
+ /* Partition has non-zero size. Set type, etc. */
+ npp->p_fstype = sun_fstypes[i];
+ /*
+ * The sun label does not store the FFS fields,
+ * so just set them with default values here.
+ * XXX: This keeps newfs from trying to rewrite
+ * XXX: the disk label in the most common case.
+ * XXX: (Should remove that code from newfs...)
+ */
+ if (npp->p_fstype == FS_BSDFFS) {
+ npp->p_fsize = 1024;
+ npp->p_frag = 8;
+ npp->p_cpg = 16;
+ }
+ }
+ }
+
+ lp->d_checksum = 0;
+ lp->d_checksum = dkcksum(lp);
+
+ return (NULL);
+}
+
+/*
+ * Given a BSD disk label, update the Sun disklabel
+ * pointed to by cp with the new info. Note that the
+ * Sun disklabel may have other info we need to keep.
+ * Returns zero or error code.
+ */
+static int
+disklabel_bsd_to_om(lp, cp)
+ struct disklabel *lp;
+ char *cp;
+{
+ struct sun_disklabel *sl;
+ struct partition *npp;
+ struct sun_dkpart *spp;
+ int i, secpercyl;
+ u_short cksum, *sp1, *sp2;
+
+ if (lp->d_secsize != 512)
+ return (EINVAL);
+
+ sl = (struct sun_disklabel *)cp;
+
+ /* Format conversion. */
+ memcpy(sl->sl_text, lp->d_packname, sizeof(lp->d_packname));
+#if 0
+ sl->sl_rpm = lp->d_rpm;
+ sl->sl_pcyl = lp->d_ncylinders + lp->d_acylinders; /* XXX */
+ sl->sl_sparespercyl = lp->d_sparespercyl;
+ sl->sl_interleave = lp->d_interleave;
+#endif
+ sl->sl_ncylinders = lp->d_ncylinders;
+#if 0
+ sl->sl_acylinders = lp->d_acylinders;
+#endif
+ sl->sl_ntracks = lp->d_ntracks;
+ sl->sl_nsectors = lp->d_nsectors;
+
+ secpercyl = sl->sl_nsectors * sl->sl_ntracks;
+ for (i = 0; i < 8; i++) {
+ spp = &sl->sl_part[i];
+ npp = &lp->d_partitions[i];
+
+ if (npp->p_offset % secpercyl)
+ return (EINVAL);
+ spp->sdkp_cyloffset = npp->p_offset / secpercyl;
+ spp->sdkp_nsectors = npp->p_size;
+ }
+ sl->sl_magic = OM_DKMAGIC;
+
+ /* Correct the XOR check. */
+ sp1 = (u_short *)sl;
+ sp2 = (u_short *)(sl + 1);
+ sl->sl_cksum = cksum = 0;
+ while (sp1 < sp2)
+ cksum ^= *sp1++;
+ sl->sl_cksum = cksum;
+
+ return (0);
+}
+
+/*
+ * Search the bad sector table looking for the specified sector.
+ * Return index if found.
+ * Return -1 if not found.
+ */
+int
+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);
+}
diff --git a/sys/arch/luna68k/luna68k/genassym.cf b/sys/arch/luna68k/luna68k/genassym.cf
new file mode 100644
index 00000000000..c2e76bff560
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/genassym.cf
@@ -0,0 +1,205 @@
+# $NetBSD: genassym.cf,v 1.1 2000/01/05 08:49:03 nisimura Exp $
+
+#
+# Copyright (c) 1982, 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.
+#
+# @(#)genassym.c 8.3 (Berkeley) 1/4/94
+#
+
+include "opt_compat_svr4.h"
+
+include <sys/param.h>
+include <sys/buf.h>
+include <sys/map.h>
+include <sys/proc.h>
+include <sys/mbuf.h>
+include <sys/msgbuf.h>
+include <sys/syscall.h>
+include <sys/user.h>
+
+include <vm/vm.h>
+
+include <uvm/uvm_extern.h>
+
+ifdef COMPAT_SVR4
+include <compat/svr4/svr4_syscall.h>
+include <compat/svr4/svr4_ucontext.h>
+endif
+
+include <machine/cpu.h>
+include <machine/psl.h>
+include <machine/reg.h>
+include <machine/pte.h>
+
+# values for mmutype
+define MMU_68030 MMU_68030
+define MMU_68851 MMU_68851
+define MMU_68040 MMU_68040
+
+# values for cputype
+define CPU_68020 CPU_68020
+define CPU_68030 CPU_68030
+define CPU_68040 CPU_68040
+
+# CPU configuration options
+ifdef M68020
+define M68020 1
+endif
+ifdef M68030
+define M68030 1
+endif
+ifdef M68040
+define M68040 1
+endif
+
+# values for fputype
+define FPU_NONE FPU_NONE
+define FPU_68881 FPU_68881
+define FPU_68882 FPU_68882
+define FPU_68040 FPU_68040
+
+# values for ectype
+define EC_PHYS EC_PHYS
+define EC_NONE EC_NONE
+define EC_VIRT EC_VIRT
+
+# general constants
+define UPAGES UPAGES
+define USPACE USPACE
+define NBPG NBPG
+define PGSHIFT PGSHIFT
+define USRSTACK USRSTACK
+
+# proc fields and values
+define P_FORW offsetof(struct proc, p_forw)
+define P_BACK offsetof(struct proc, p_back)
+define P_VMSPACE offsetof(struct proc, p_vmspace)
+define P_ADDR offsetof(struct proc, p_addr)
+define P_PRIORITY offsetof(struct proc, p_priority)
+define P_STAT offsetof(struct proc, p_stat)
+define P_WCHAN offsetof(struct proc, p_wchan)
+define P_MD_FLAGS offsetof(struct proc, p_md.md_flags)
+define P_MD_REGS offsetof(struct proc, p_md.md_regs)
+define SSLEEP SSLEEP
+define SRUN SRUN
+
+# interrupt/fault metering
+define UVMEXP_INTRS offsetof(struct uvmexp, intrs)
+
+define T_BUSERR T_BUSERR
+define T_ADDRERR T_ADDRERR
+define T_ILLINST T_ILLINST
+define T_ZERODIV T_ZERODIV
+define T_CHKINST T_CHKINST
+define T_TRAPVINST T_TRAPVINST
+define T_PRIVINST T_PRIVINST
+define T_TRACE T_TRACE
+define T_MMUFLT T_MMUFLT
+define T_SSIR T_SSIR
+define T_FMTERR T_FMTERR
+define T_COPERR T_COPERR
+define T_FPERR T_FPERR
+define T_ASTFLT T_ASTFLT
+define T_TRAP15 T_TRAP15
+define T_FPEMULI T_FPEMULI
+define T_FPEMULD T_FPEMULD
+
+# PSL values (should just include psl.h?)
+define PSL_S PSL_S
+define PSL_IPL7 PSL_IPL7
+define PSL_LOWIPL PSL_LOWIPL
+define PSL_HIGHIPL PSL_HIGHIPL
+define PSL_USER PSL_USER
+define PSL_TS PSL_T | PSL_S
+define SPL1 PSL_S | PSL_IPL1
+define SPL2 PSL_S | PSL_IPL2
+define SPL3 PSL_S | PSL_IPL3
+define SPL4 PSL_S | PSL_IPL4
+define SPL5 PSL_S | PSL_IPL5
+define SPL6 PSL_S | PSL_IPL6
+
+# magic
+define FC_USERD FC_USERD
+define FC_SUPERD FC_SUPERD
+define CACHE_ON CACHE_ON
+define CACHE_OFF CACHE_OFF
+define CACHE_CLR CACHE_CLR
+define IC_CLEAR IC_CLEAR
+define DC_CLEAR DC_CLEAR
+
+# pte/ste bits
+define PG_V PG_V
+define PG_NV PG_NV
+define PG_RO PG_RO
+define PG_RW PG_RW
+define PG_CI PG_CI
+define PG_PROT PG_PROT
+define PG_FRAME PG_FRAME
+define SG_V SG_V
+define SG_NV SG_NV
+define SG_RW SG_RW
+define SG_FRAME SG_FRAME
+define SG_ISHIFT SG_ISHIFT
+
+# pcb fields
+define PCB_PS offsetof(struct pcb, pcb_ps)
+define PCB_USP offsetof(struct pcb, pcb_usp)
+define PCB_REGS offsetof(struct pcb, pcb_regs)
+define PCB_ONFAULT offsetof(struct pcb, pcb_onfault)
+define PCB_FPCTX offsetof(struct pcb, pcb_fpregs)
+define SIZEOF_PCB sizeof(struct pcb)
+
+# exception frame offset/sizes
+define FR_SP offsetof(struct frame, f_regs[15])
+define FR_HW offsetof(struct frame, f_sr)
+define FR_ADJ offsetof(struct frame, f_stackadj)
+define FR_SIZE sizeof(struct trapframe)
+
+# system calls
+define SYS_exit SYS_exit
+define SYS_execve SYS_execve
+define SYS___sigreturn14 SYS___sigreturn14
+define SYS_compat_13_sigreturn13 SYS_compat_13_sigreturn13
+
+# errno
+define EFAULT EFAULT
+define ENAMETOOLONG ENAMETOOLONG
+
+# SVR4 binary compatibility
+ifdef COMPAT_SVR4
+define SVR4_SIGF_HANDLER offsetof(struct svr4_sigframe, sf_handler)
+define SVR4_SIGF_UC offsetof(struct svr4_sigframe, sf_uc)
+define SVR4_SYS_context SVR4_SYS_context
+define SVR4_SYS_exit SVR4_SYS_exit
+define SVR4_SETCONTEXT SVR4_SETCONTEXT
+endif
+
diff --git a/sys/arch/luna68k/luna68k/isr.c b/sys/arch/luna68k/luna68k/isr.c
new file mode 100644
index 00000000000..917c82955f3
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/isr.c
@@ -0,0 +1,356 @@
+/* $NetBSD: isr.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $ */
+/* $NetBSD: isr.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: isr.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $");
+
+/*
+ * Link and dispatch interrupts.
+ */
+
+#include "opt_inet.h"
+#include "opt_atalk.h"
+#include "opt_ccitt.h"
+#include "opt_iso.h"
+#include "opt_ns.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/vmmeter.h>
+
+#include <vm/vm.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <net/netisr.h>
+
+#include <machine/cpu.h>
+
+#include <luna68k/luna68k/isr.h>
+
+isr_autovec_list_t isr_autovec[NISRAUTOVEC];
+struct isr_vectored isr_vectored[NISRVECTORED];
+
+extern int intrcnt[]; /* from locore.s */
+extern void (*vectab[]) __P((void));
+extern void badtrap __P((void));
+extern void intrhand_vectored __P((void));
+
+extern int getsr __P((void)); /* in locore.s */
+
+void
+isrinit()
+{
+ int i;
+
+ /* Initialize the autovector lists. */
+ for (i = 0; i < NISRAUTOVEC; ++i) {
+ LIST_INIT(&isr_autovec[i]);
+ }
+}
+
+/*
+ * Establish an autovectored interrupt handler.
+ * Called by driver attach functions.
+ */
+void
+isrlink_autovec(func, arg, ipl, priority)
+ int (*func) __P((void *));
+ void *arg;
+ int ipl;
+ int priority;
+{
+ struct isr_autovec *newisr, *curisr;
+ isr_autovec_list_t *list;
+
+ if ((ipl < 0) || (ipl >= NISRAUTOVEC))
+ panic("isrlink_autovec: bad ipl %d", ipl);
+
+ newisr = (struct isr_autovec *)malloc(sizeof(struct isr_autovec),
+ M_DEVBUF, M_NOWAIT);
+ if (newisr == NULL)
+ panic("isrlink_autovec: can't allocate space for isr");
+
+ /* Fill in the new entry. */
+ newisr->isr_func = func;
+ newisr->isr_arg = arg;
+ newisr->isr_ipl = ipl;
+ newisr->isr_priority = priority;
+
+ /*
+ * Some devices are particularly sensitive to interrupt
+ * handling latency. The SCC, for example, can lose many
+ * characters if its interrupt isn't handled with reasonable
+ * speed.
+ *
+ * To work around this problem, each device can give itself a
+ * "priority". An unbuffered SCC would give itself a higher
+ * priority than a SCSI device, for example.
+ *
+ * This solution was originally developed for the hp300, which
+ * has a flat spl scheme (by necessity). Thankfully, the
+ * MVME systems don't have this problem, though this may serve
+ * a useful purpose in any case.
+ */
+
+ /*
+ * Get the appropriate ISR list. If the list is empty, no
+ * additional work is necessary; we simply insert ourselves
+ * at the head of the list.
+ */
+ list = &isr_autovec[ipl];
+ if (list->lh_first == NULL) {
+ LIST_INSERT_HEAD(list, newisr, isr_link);
+ return;
+ }
+
+ /*
+ * A little extra work is required. We traverse the list
+ * and place ourselves after any ISRs with our current (or
+ * higher) priority.
+ */
+ for (curisr = list->lh_first; curisr->isr_link.le_next != NULL;
+ curisr = curisr->isr_link.le_next) {
+ if (newisr->isr_priority > curisr->isr_priority) {
+ LIST_INSERT_BEFORE(curisr, newisr, isr_link);
+ return;
+ }
+ }
+
+ /*
+ * We're the least important entry, it seems. We just go
+ * on the end.
+ */
+ LIST_INSERT_AFTER(curisr, newisr, isr_link);
+}
+
+/*
+ * Establish a vectored interrupt handler.
+ * Called by bus interrupt establish functions.
+ */
+void
+isrlink_vectored(func, arg, ipl, vec)
+ int (*func) __P((void *));
+ void *arg;
+ int ipl, vec;
+{
+ struct isr_vectored *isr;
+
+ if ((ipl < 0) || (ipl >= NISRAUTOVEC))
+ panic("isrlink_vectored: bad ipl %d", ipl);
+ if ((vec < ISRVECTORED) || (vec >= ISRVECTORED + NISRVECTORED))
+ panic("isrlink_vectored: bad vec 0x%x", vec);
+
+ isr = &isr_vectored[vec - ISRVECTORED];
+
+ if ((vectab[vec] != badtrap) || (isr->isr_func != NULL))
+ panic("isrlink_vectored: vec 0x%x not available", vec);
+
+ /* Fill in the new entry. */
+ isr->isr_func = func;
+ isr->isr_arg = arg;
+ isr->isr_ipl = ipl;
+
+ /* Hook into the vector table. */
+ vectab[vec] = intrhand_vectored;
+}
+
+/*
+ * Unhook a vectored interrupt.
+ */
+void
+isrunlink_vectored(vec)
+ int vec;
+{
+
+ if ((vec < ISRVECTORED) || (vec >= ISRVECTORED + NISRVECTORED))
+ panic("isrunlink_vectored: bad vec 0x%x", vec);
+
+ if (vectab[vec] != intrhand_vectored)
+ panic("isrunlink_vectored: not vectored interrupt");
+
+ vectab[vec] = badtrap;
+ bzero(&isr_vectored[vec - ISRVECTORED], sizeof(struct isr_vectored));
+}
+
+/*
+ * This is the dispatcher called by the low-level
+ * assembly language autovectored interrupt routine.
+ */
+void
+isrdispatch_autovec(evec)
+ int evec; /* format | vector offset */
+{
+ struct isr_autovec *isr;
+ isr_autovec_list_t *list;
+ int handled = 0, ipl, vec;
+ static int straycount, unexpected;
+
+ vec = (evec & 0xfff) >> 2;
+ if ((vec < ISRAUTOVEC) || (vec >= (ISRAUTOVEC + NISRAUTOVEC)))
+ panic("isrdispatch_autovec: bad vec 0x%x\n", vec);
+ ipl = vec - ISRAUTOVEC;
+
+ intrcnt[ipl]++;
+ uvmexp.intrs++;
+
+ list = &isr_autovec[ipl];
+ if (list->lh_first == NULL) {
+ printf("isrdispatch_autovec: ipl %d unexpected\n", ipl);
+ if (++unexpected > 10)
+ panic("too many unexpected interrupts");
+ return;
+ }
+
+ /* Give all the handlers a chance. */
+ for (isr = list->lh_first ; isr != NULL; isr = isr->isr_link.le_next)
+ handled |= (*isr->isr_func)(isr->isr_arg);
+
+ if (handled)
+ straycount = 0;
+ else if (++straycount > 50)
+ panic("isr_dispatch_autovec: too many stray interrupts");
+ else
+ printf("isrdispatch_autovec: stray level %d interrupt\n", ipl);
+}
+
+/*
+ * This is the dispatcher called by the low-level
+ * assembly language vectored interrupt routine.
+ */
+void
+isrdispatch_vectored(pc, evec, frame)
+ int pc, evec;
+ void *frame;
+{
+ struct isr_vectored *isr;
+ int ipl, vec;
+
+ vec = (evec & 0xfff) >> 2;
+ ipl = (getsr() >> 8) & 7;
+
+ intrcnt[ipl]++;
+ uvmexp.intrs++;
+
+ if ((vec < ISRVECTORED) || (vec >= (ISRVECTORED + NISRVECTORED)))
+ panic("isrdispatch_vectored: bad vec 0x%x\n", vec);
+ isr = &isr_vectored[vec - ISRVECTORED];
+
+ if (isr->isr_func == NULL) {
+ printf("isrdispatch_vectored: no handler for vec 0x%x\n", vec);
+ vectab[vec] = badtrap;
+ return;
+ }
+
+ /*
+ * Handler gets exception frame if argument is NULL.
+ */
+ if ((*isr->isr_func)(isr->isr_arg ? isr->isr_arg : frame) == 0)
+ printf("isrdispatch_vectored: vec 0x%x not claimed\n", vec);
+}
+
+/*
+ * XXX Why on earth isn't this in a common file?!
+ */
+void netintr __P((void));
+void arpintr __P((void));
+void atintr __P((void));
+void ipintr __P((void));
+void ip6intr __P((void));
+void nsintr __P((void));
+void clnlintr __P((void));
+void ccittintr __P((void));
+void pppintr __P((void));
+
+void
+netintr()
+{
+#ifdef INET
+#include "arp.h"
+#if NARP > 0
+ if (netisr & (1 << NETISR_ARP)) {
+ netisr &= ~(1 << NETISR_ARP);
+ arpintr();
+ }
+#endif
+ if (netisr & (1 << NETISR_IP)) {
+ netisr &= ~(1 << NETISR_IP);
+ ipintr();
+ }
+#endif
+#ifdef INET6
+ if (netisr & (1 << NETISR_IPV6)) {
+ netisr &= ~(1 << NETISR_IPV6);
+ ip6intr();
+ }
+#endif
+#ifdef NETATALK
+ if (netisr & (1 << NETISR_ATALK)) {
+ netisr &= ~(1 << NETISR_ATALK);
+ atintr();
+ }
+#endif
+#ifdef NS
+ if (netisr & (1 << NETISR_NS)) {
+ netisr &= ~(1 << NETISR_NS);
+ nsintr();
+ }
+#endif
+#ifdef ISO
+ if (netisr & (1 << NETISR_ISO)) {
+ netisr &= ~(1 << NETISR_ISO);
+ clnlintr();
+ }
+#endif
+#ifdef CCITT
+ if (netisr & (1 << NETISR_CCITT)) {
+ netisr &= ~(1 << NETISR_CCITT);
+ ccittintr();
+ }
+#endif
+#include "ppp.h"
+#if NPPP > 0
+ if (netisr & (1 << NETISR_PPP)) {
+ netisr &= ~(1 << NETISR_PPP);
+ pppintr();
+ }
+#endif
+}
diff --git a/sys/arch/luna68k/luna68k/isr.h b/sys/arch/luna68k/luna68k/isr.h
new file mode 100644
index 00000000000..a1faca6cb47
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/isr.h
@@ -0,0 +1,92 @@
+/* $NetBSD: isr.h,v 1.1 2000/01/05 08:49:04 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/queue.h>
+
+/*
+ * The location and size of the autovectored interrupt portion
+ * of the vector table.
+ */
+#define ISRAUTOVEC 0x18
+#define NISRAUTOVEC 8
+
+/*
+ * The location and size of the vectored interrupt portion
+ * of the vector table.
+ */
+#define ISRVECTORED 0x40
+#define NISRVECTORED 192
+
+/*
+ * Autovectored interupt handler cookie.
+ */
+struct isr_autovec {
+ LIST_ENTRY(isr_autovec) isr_link;
+ int (*isr_func) __P((void *));
+ void *isr_arg;
+ int isr_ipl;
+ int isr_priority;
+};
+
+typedef LIST_HEAD(, isr_autovec) isr_autovec_list_t;
+
+/*
+ * Vectored interrupt handler cookie. The handler may request to
+ * receive the exception frame as an argument by specifying NULL
+ * when establishing the interrupt.
+ */
+struct isr_vectored {
+ int (*isr_func) __P((void *));
+ void *isr_arg;
+ int isr_ipl;
+};
+
+/*
+ * Autovectored ISR priorities. These are not the same as interrupt levels.
+ */
+#define ISRPRI_BIO 0
+#define ISRPRI_NET 1
+#define ISRPRI_TTY 2
+#define ISRPRI_TTYNOBUF 3
+
+void isrinit __P((void));
+void isrlink_autovec __P((int (*)(void *), void *, int, int));
+void isrlink_vectored __P((int (*)(void *), void *, int, int));
+void isrunlink_vectored __P((int));
+void isrdispatch_autovec __P((int));
+void isrdispatch_vectored __P((int, int, void *));
diff --git a/sys/arch/luna68k/luna68k/locore.s b/sys/arch/luna68k/luna68k/locore.s
new file mode 100644
index 00000000000..ddc4629fc2f
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/locore.s
@@ -0,0 +1,1427 @@
+/* $NetBSD: locore.s,v 1.1 2000/01/05 08:49:03 nisimura Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1980, 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.
+ *
+ * from: Utah $Hdr: locore.s 1.66 92/12/22$
+ *
+ * @(#)locore.s 8.6 (Berkeley) 5/27/94
+ */
+
+#include "opt_compat_netbsd.h"
+#include "opt_ddb.h"
+
+#include "assym.h"
+#include <machine/asm.h>
+#include <machine/trap.h>
+
+#define PRINT(msg) \
+ pea 9f ; \
+ jbsr _C_LABEL(printf); \
+ addl #4,sp ; \
+ .data ; \
+ 9: .asciz msg ; \
+ .text
+#undef PRINT
+
+/*
+ * Temporary stack for a variety of purposes.
+ * Try and make this the first thing is the data segment so it
+ * is page aligned. Note that if we overflow here, we run into
+ * our text segment.
+ */
+ .data
+ .space NBPG
+ASLOCAL(tmpstk)
+
+#include <luna68k/luna68k/vectors.s>
+
+/*
+ * Macro to relocate a symbol, used before MMU is enabled.
+ */
+#define _RELOC(var,ar) \
+ lea var,ar; \
+ addl a5,ar
+#define RELOC(var,ar) _RELOC(_C_LABEL(var), ar)
+#define ASRELOC(var,ar) _RELOC(_ASM_LABEL(var), ar)
+
+BSS(lowram,4)
+BSS(esym,4)
+
+/*
+ * This is for kvm_mkdb, and should be the address of the beginning
+ * of the kernel text segment (not necessarily the same as kernbase).
+ */
+ .text
+GLOBAL(kernel_text)
+
+/*
+ * start of kernel and .text!
+ */
+ASENTRY_NOPROFILE(start)
+ movw #PSL_HIGHIPL,sr | no interrupts
+ movl #0,a5 | RAM starts at 0
+ ASRELOC(tmpstk,a0)
+ movl a0,sp | give ourselves a temporary stack
+
+#if 0 /* not sure useful values, need a bootloader tailored for us */
+ RELOC(boothowto,a0)
+ movl d7,a0@ | save boothowto
+ RELOC(bootdev,a0)
+ movl d6,a0@ | save bootdev
+ RELOC(esym,a0)
+ movl d5,a0@ | save esym
+#endif
+ RELOC(edata,a0) | clear out BSS
+ movl #_C_LABEL(end)-4,d0 | (must be <= 256 kB)
+ subl #_C_LABEL(edata),d0
+ lsrl #2,d0
+1: clrl a0@+
+ dbra d0,1b
+
+#if 1
+ RELOC(esym,a0)
+ clrl a0@ | store end of symbol table XXX
+#endif
+ RELOC(lowram,a0)
+ movl a5,a0@ | store start of physical memory
+
+ movl #0x41000000,a0 | available memory in bytes
+ movl a0@(12),a0 | (int *)base[3])
+ movl a0@,d5
+ RELOC(memavail,a0)
+ movl d5, a0@ | save memavail
+
+ movl #0x41000000,a0 | planemask; 0x0f or 0xff
+ movl a0@(184),a0 | (int *)base[46]
+ movl a0@,d5
+ RELOC(hwplanemask,a0)
+ movl d5,a0@ | save hwplanemask
+
+ movl #0x41000000,a0 | argument of 'x' command on boot
+ movl a0@(212),a0 | (char *)base[53]
+ RELOC(bootarg, a1)
+ movl #63,d0
+1: movb a0@+,a1@+ | copy to bootarg
+ dbra d0,1b | upto 63 characters
+
+ movl #CACHE_OFF,d0
+ movc d0,cacr | clear and disable on-chip cache(s)
+
+/* determine our CPU/MMU combo - check for all regardless of kernel config */
+ movl #0x200,d0 | data freeze bit
+ movc d0,cacr | only exists on 68030
+ movc cacr,d0 | read it back
+ tstl d0 | zero?
+ jeq Lnot68030 | yes, we have 68040
+ movl #CPU_68030,d0
+ movl #MMU_68030,d1
+ movl #FPU_68881,d2
+ jra Lstart0
+Lnot68030:
+ movl #CPU_68040,d0
+ movl #MMU_68040,d1
+ movl #FPU_68040,d2
+Lstart0:
+ RELOC(cputype,a0)
+ movl d0,a0@
+ RELOC(mmutype,a0)
+ movl d1,a0@
+ RELOC(fputype,a0)
+ movl d2,a0@
+
+ /*
+ * Now that we know what CPU we have, initialize the address error
+ * and bus error handlers in the vector table:
+ *
+ * vectab+8 bus error
+ * vectab+12 address error
+ */
+ lea _C_LABEL(cputype),a0
+ lea _C_LABEL(vectab),a2
+#if defined(M68040)
+ cmpl #CPU_68040,a0@ | 68040?
+ jne 1f | no, skip
+ movl #_C_LABEL(buserr40),a2@(8)
+ movl #_C_LABEL(addrerr4060),a2@(12)
+ jra Lstart2
+1:
+#endif
+ cmpl #CPU_68030,a0@ | 68030?
+ jne 1f | no, skip
+ movl #_C_LABEL(busaddrerr2030),a2@(8)
+ movl #_C_LABEL(busaddrerr2030),a2@(12)
+ jra Lstart2
+1:
+ /* Config botch; no hope. */
+ PANIC("Config botch in locore")
+
+Lstart2:
+/* initialize source/destination control registers for movs */
+ moveq #FC_USERD,d0 | user space
+ movc d0,sfc | as source
+ movc d0,dfc | and destination of transfers
+/* initialize memory sizes (for pmap_bootstrap) */
+ RELOC(memavail,a0)
+ movl a0@,d1
+ moveq #PGSHIFT,d2
+ lsrl d2,d1 | convert to page (click) number
+ RELOC(maxmem,a0)
+ movl d1,a0@ | save as maxmem
+ RELOC(physmem,a0)
+ movl d1,a0@ | and physmem
+/* configure kernel and proc0 VA space so we can get going */
+#ifdef DDB
+ RELOC(esym,a0) | end of static kernel test/data/syms
+ movl a0@,d2
+ jne Lstart3
+#endif
+ RELOC(end,a0)
+ movl a0,d2 | end of static kernel text/data
+Lstart3:
+ addl #NBPG-1,d2
+ andl #PG_FRAME,d2 | round to a page
+ movl d2,a4
+ addl a5,a4 | convert to PA
+ pea a5@ | firstpa
+ pea a4@ | nextpa
+ RELOC(pmap_bootstrap,a0)
+ jbsr a0@ | pmap_bootstrap(firstpa, nextpa)
+ addql #8,sp
+/*
+ * Enable the MMU.
+ * Since the kernel is mapped logical == physical, we just turn it on.
+ */
+ RELOC(Sysseg,a0) | system segment table addr
+ movl a0@,d1 | read value (a KVA)
+ addl a5,d1 | convert to PA (a5 == 0, indeed)
+#if defined(M68040)
+ RELOC(mmutype,a0)
+ cmpl #MMU_68040,a0@ | 68040?
+ jne Lmotommu1 | no, skip
+Lmotommu0:
+ .long 0x4e7b1807 | movc d1,srp
+ RELOC(proto040tt0,a0)
+ movl a0@,d0 | tt0 range 4000.0000-7fff.ffff
+ .long 0x4e7b0004 | movc d0,itt0
+ .long 0x4e7b0006 | movc d0,dtt0
+ RELOC(proto040tt1,a0)
+ movl a0@,d0 | tt1 range 8000.0000-feff.ffff
+ .long 0x4e7b0005 | movc d0,itt1
+ .long 0x4e7b0007 | movc d0,dtt1
+ .word 0xf4d8 | cinva bc
+ pflusha | flush entire TLB
+ RELOC(proto040tc,a0)
+ movl a0@,d0
+ .long 0x4e7b0003 | movc d0,tc
+ movl #0x80008000,d0
+ movc d0,cacr | turn on both caches
+ jmp Lenab1
+Lmotommu1:
+#endif
+ RELOC(protosrp,a0) | nolimit + share global + 4 byte PTEs
+ movl d1,a0@(4) | + segtable address
+ RELOC(protocrp,a1)
+ movl d1,a1@(4) | set lower half of CRP
+ pmove a0@,srp | load the supervisor root pointer
+ RELOC(protott0,a0) | tt0 range 4000.0000-7fff.ffff
+ .long 0xf0100800 | pmove a0@,mmutt0
+ RELOC(protott1,a0) | tt1 range 8000.0000-ffff.ffff
+ .long 0xf0100c00 | pmove a0@,mmutt1
+ RELOC(prototc,a0) | tc: SRP,CRP,4KB page,A=10bit,B=10bit
+ pmove a0@,tc
+/*
+ * Should be running mapped from this point on
+ */
+Lenab1:
+/* select the software page size now */
+ lea _ASM_LABEL(tmpstk),sp | temporary stack
+ jbsr _C_LABEL(uvm_setpagesize) | select software page size
+
+/* set kernel stack, user SP, proc0, and initial pcb */
+ movl _C_LABEL(proc0paddr),a1 | get proc0 pcb addr
+ lea a1@(USPACE-4),sp | set kernel stack to end of area
+ lea _C_LABEL(proc0),a2 | initialize proc0.p_addr so that
+ movl a1,a2@(P_ADDR) | we don't deref NULL in trap()
+ movl #USRSTACK-4,a2
+ movl a2,usp | init user SP
+ movl a1,_C_LABEL(curpcb) | proc0 is running
+
+ tstl _C_LABEL(fputype) | Have an FPU?
+ jeq Lenab2 | No, skip.
+ clrl a1@(PCB_FPCTX) | ensure null FP context
+ movl a1,sp@-
+ jbsr _C_LABEL(m68881_restore) | restore it (does not kill a1)
+ addql #4,sp
+Lenab2:
+ pflusha | flush entire TLB
+ cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
+ jeq Lenab3 | yes, cache already on
+ tstl _C_LABEL(mmutype)
+ jpl Lenab3 | 68851 implies no d-cache
+ movl #CACHE_ON,d0
+ movc d0,cacr | clear cache(s)
+Lenab3:
+
+/* final setup for C code */
+ movl #_C_LABEL(vectab),d0 | get our VBR address
+ movc d0,vbr
+ jbsr _C_LABEL(luna68k_init) | additional pre-main initialization
+
+/*
+ * Create a fake exception frame that returns to user mode,
+ * and save its address in p->p_md.md_regs for cpu_fork().
+ * The new frames for process 1 and 2 will be adjusted by
+ * cpu_set_kpc() to arrange for a call to a kernel function
+ * before the new process does its rte out to user mode.
+ */
+ clrw sp@- | vector offset/frame type
+ clrl sp@- | PC - filled in by "execve"
+ movw #PSL_USER,sp@- | in user mode
+ clrl sp@- | stack adjust count and padding
+ lea sp@(-64),sp | construct space for D0-D7/A0-A7
+ lea _C_LABEL(proc0),a0 | save pointer to frame
+ movl sp,a0@(P_MD_REGS) | in proc0.p_md.md_regs
+ jra _C_LABEL(main) | main()
+ PANIC("main() returned")
+ /* NOTREACHED */
+
+/*
+ * proc_trampoline: call function in register a2 with a3 as an arg
+ * and then rei.
+ */
+GLOBAL(proc_trampoline)
+ movl a3,sp@- | process' frame pointer in sp
+ jbsr a2@
+ addql #4,sp
+ movl sp@(FR_SP),a0 | grab and load
+ movl a0,usp | user SP
+ moveml sp@+,#0x7FFF | restore most user regs
+ addql #8,sp | toss SP and stack adjust
+ jra _ASM_LABEL(rei) | and return
+
+/*
+ * Trap/interrupt vector routines
+ */
+#include <m68k/m68k/trap_subr.s>
+
+ .data
+GLOBAL(m68k_fault_addr)
+ .long 0
+
+#if defined(M68040) || defined(M68060)
+ENTRY_NOPROFILE(addrerr4060)
+ clrl sp@- | stack adjust count
+ moveml #0xFFFF,sp@- | save user registers
+ movl usp,a0 | save the user SP
+ movl a0,sp@(FR_SP) | in the savearea
+ movl sp@(FR_HW+8),sp@-
+ clrl sp@- | dummy code
+ movl #T_ADDRERR,sp@- | mark address error
+ jra _ASM_LABEL(faultstkadj) | and deal with it
+#endif
+
+#if defined(M68060)
+ENTRY_NOPROFILE(buserr60)
+ clrl sp@- | stack adjust count
+ moveml #0xFFFF,sp@- | save user registers
+ movl usp,a0 | save the user SP
+ movl a0,sp@(FR_SP) | in the savearea
+ movel sp@(FR_HW+12),d0 | FSLW
+ btst #2,d0 | branch prediction error?
+ jeq Lnobpe
+ movc cacr,d2
+ orl #IC60_CABC,d2 | clear all branch cache entries
+ movc d2,cacr
+ movl d0,d1
+ addql #1,L60bpe
+ andl #0x7ffd,d1
+ jeq _ASM_LABEL(faultstkadjnotrap2)
+Lnobpe:
+| we need to adjust for misaligned addresses
+ movl sp@(FR_HW+8),d1 | grab VA
+ btst #27,d0 | check for mis-aligned access
+ jeq Lberr3 | no, skip
+ addl #28,d1 | yes, get into next page
+ | operand case: 3,
+ | instruction case: 4+12+12
+ andl #PG_FRAME,d1 | and truncate
+Lberr3:
+ movl d1,sp@-
+ movl d0,sp@- | code is FSLW now.
+ andw #0x1f80,d0
+ jeq Lberr60 | it is a bus error
+ movl #T_MMUFLT,sp@- | show that we are an MMU fault
+ jra _ASM_LABEL(faultstkadj) | and deal with it
+Lberr60:
+ tstl _C_LABEL(nofault) | catch bus error?
+ jeq Lisberr | no, handle as usual
+ movl sp@(FR_HW+8+8),_C_LABEL(m68k_fault_addr) | save fault addr
+ movl _C_LABEL(nofault),sp@- | yes,
+ jbsr _C_LABEL(longjmp) | longjmp(nofault)
+ /* NOTREACHED */
+#endif
+#if defined(M68040)
+ENTRY_NOPROFILE(buserr40)
+ clrl sp@- | stack adjust count
+ moveml #0xFFFF,sp@- | save user registers
+ movl usp,a0 | save the user SP
+ movl a0,sp@(FR_SP) | in the savearea
+ movl sp@(FR_HW+20),d1 | get fault address
+ moveq #0,d0
+ movw sp@(FR_HW+12),d0 | get SSW
+ btst #11,d0 | check for mis-aligned
+ jeq Lbe1stpg | no skip
+ addl #3,d1 | get into next page
+ andl #PG_FRAME,d1 | and truncate
+Lbe1stpg:
+ movl d1,sp@- | pass fault address.
+ movl d0,sp@- | pass SSW as code
+ btst #10,d0 | test ATC
+ jeq Lberr40 | it is a bus error
+ movl #T_MMUFLT,sp@- | show that we are an MMU fault
+ jra _ASM_LABEL(faultstkadj) | and deal with it
+Lberr40:
+ tstl _C_LABEL(nofault) | catch bus error?
+ jeq Lisberr | no, handle as usual
+ movl sp@(FR_HW+8+20),_C_LABEL(m68k_fault_addr) | save fault addr
+ movl _C_LABEL(nofault),sp@- | yes,
+ jbsr _C_LABEL(longjmp) | longjmp(nofault)
+ /* NOTREACHED */
+#endif
+
+ENTRY_NOPROFILE(busaddrerr2030)
+ clrl sp@- | stack adjust count
+ moveml #0xFFFF,sp@- | save user registers
+ movl usp,a0 | save the user SP
+ movl a0,sp@(FR_SP) | in the savearea
+ moveq #0,d0
+ movw sp@(FR_HW+10),d0 | grab SSW for fault processing
+ btst #12,d0 | RB set?
+ jeq LbeX0 | no, test RC
+ bset #14,d0 | yes, must set FB
+ movw d0,sp@(FR_HW+10) | for hardware too
+LbeX0:
+ btst #13,d0 | RC set?
+ jeq LbeX1 | no, skip
+ bset #15,d0 | yes, must set FC
+ movw d0,sp@(FR_HW+10) | for hardware too
+LbeX1:
+ btst #8,d0 | data fault?
+ jeq Lbe0 | no, check for hard cases
+ movl sp@(FR_HW+16),d1 | fault address is as given in frame
+ jra Lbe10 | thats it
+Lbe0:
+ btst #4,sp@(FR_HW+6) | long (type B) stack frame?
+ jne Lbe4 | yes, go handle
+ movl sp@(FR_HW+2),d1 | no, can use save PC
+ btst #14,d0 | FB set?
+ jeq Lbe3 | no, try FC
+ addql #4,d1 | yes, adjust address
+ jra Lbe10 | done
+Lbe3:
+ btst #15,d0 | FC set?
+ jeq Lbe10 | no, done
+ addql #2,d1 | yes, adjust address
+ jra Lbe10 | done
+Lbe4:
+ movl sp@(FR_HW+36),d1 | long format, use stage B address
+ btst #15,d0 | FC set?
+ jeq Lbe10 | no, all done
+ subql #2,d1 | yes, adjust address
+Lbe10:
+ movl d1,sp@- | push fault VA
+ movl d0,sp@- | and padded SSW
+ movw sp@(FR_HW+8+6),d0 | get frame format/vector offset
+ andw #0x0FFF,d0 | clear out frame format
+ cmpw #12,d0 | address error vector?
+ jeq Lisaerr | yes, go to it
+ movl d1,a0 | fault address
+ movl sp@,d0 | function code from ssw
+ btst #8,d0 | data fault?
+ jne Lbe10a
+ movql #1,d0 | user program access FC
+ | (we dont seperate data/program)
+ btst #5,sp@(FR_HW+8) | supervisor mode?
+ jeq Lbe10a | if no, done
+ movql #5,d0 | else supervisor program access
+Lbe10a:
+ ptestr d0,a0@,#7 | do a table search
+ pmove psr,sp@ | save result
+ movb sp@,d1
+ btst #2,d1 | invalid (incl. limit viol. and berr)?
+ jeq Lmightnotbemerr | no -> wp check
+ btst #7,d1 | is it MMU table berr?
+ jne Lisberr1 | yes, needs not be fast.
+Lismerr:
+ movl #T_MMUFLT,sp@- | show that we are an MMU fault
+ jra _ASM_LABEL(faultstkadj) | and deal with it
+Lmightnotbemerr:
+ btst #3,d1 | write protect bit set?
+ jeq Lisberr1 | no: must be bus error
+ movl sp@,d0 | ssw into low word of d0
+ andw #0xc0,d0 | Write protect is set on page:
+ cmpw #0x40,d0 | was it read cycle?
+ jne Lismerr | no, was not WPE, must be MMU fault
+ jra Lisberr1 | real bus err needs not be fast.
+Lisaerr:
+ movl #T_ADDRERR,sp@- | mark address error
+ jra _ASM_LABEL(faultstkadj) | and deal with it
+Lisberr1:
+ clrw sp@ | re-clear pad word
+ tstl _C_LABEL(nofault) | catch bus error?
+ jeq Lisberr | no, handle as usual
+ movl sp@(FR_HW+8+16),_C_LABEL(m68k_fault_addr) | save fault addr
+ movl _C_LABEL(nofault),sp@- | yes,
+ jbsr _C_LABEL(longjmp) | longjmp(nofault)
+ /* NOTREACHED */
+ .even
+Lisberr: | also used by M68040/60
+ movl #T_BUSERR,sp@- | mark bus error
+ jra _ASM_LABEL(faultstkadj) | and deal with it
+
+/*
+ * FP exceptions.
+ */
+ENTRY_NOPROFILE(fpfline)
+#if defined(M68040)
+ cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU?
+ jne Lfp_unimp | no, skip FPSP
+ cmpw #0x202c,sp@(6) | format type 2?
+ jne _C_LABEL(illinst) | no, not an FP emulation
+Ldofp_unimp:
+#ifdef FPSP
+ jmp _ASM_LABEL(fpsp_unimp) | yes, go handle it
+#endif
+Lfp_unimp:
+#endif /* M68040 */
+#ifdef FPU_EMULATE
+ clrl sp@- | stack adjust count
+ moveml #0xFFFF,sp@- | save registers
+ moveq #T_FPEMULI,d0 | denote as FP emulation trap
+ jra _ASM_LABEL(fault) | do it
+#else
+ jra _C_LABEL(illinst)
+#endif
+
+ENTRY_NOPROFILE(fpunsupp)
+#if defined(M68040)
+ cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU?
+ jne _C_LABEL(illinst) | no, treat as illinst
+#ifdef FPSP
+ jmp _ASM_LABEL(fpsp_unsupp) | yes, go handle it
+#endif
+Lfp_unsupp:
+#endif /* M68040 */
+#ifdef FPU_EMULATE
+ clrl sp@- | stack adjust count
+ moveml #0xFFFF,sp@- | save registers
+ moveq #T_FPEMULD,d0 | denote as FP emulation trap
+ jra _ASM_LABEL(fault) | do it
+#else
+ jra _C_LABEL(illinst)
+#endif
+
+/*
+ * Handles all other FP coprocessor exceptions.
+ * Note that since some FP exceptions generate mid-instruction frames
+ * and may cause signal delivery, we need to test for stack adjustment
+ * after the trap call.
+ */
+ENTRY_NOPROFILE(fpfault)
+ clrl sp@- | stack adjust count
+ moveml #0xFFFF,sp@- | save user registers
+ movl usp,a0 | and save
+ movl a0,sp@(FR_SP) | the user stack pointer
+ clrl sp@- | no VA arg
+ movl _C_LABEL(curpcb),a0 | current pcb
+ lea a0@(PCB_FPCTX),a0 | address of FP savearea
+ fsave a0@ | save state
+#if defined(M68040) || defined(M68060)
+ /* always null state frame on 68040, 68060 */
+ cmpl #FPU_68040,_C_LABEL(fputype)
+ jle Lfptnull
+#endif
+ tstb a0@ | null state frame?
+ jeq Lfptnull | yes, safe
+ clrw d0 | no, need to tweak BIU
+ movb a0@(1),d0 | get frame size
+ bset #3,a0@(0,d0:w) | set exc_pend bit of BIU
+Lfptnull:
+ fmovem fpsr,sp@- | push fpsr as code argument
+ frestore a0@ | restore state
+ movl #T_FPERR,sp@- | push type arg
+ jra _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup
+
+/*
+ * Other exceptions only cause four and six word stack frame and require
+ * no post-trap stack adjustment.
+ */
+
+ENTRY_NOPROFILE(badtrap)
+ moveml #0xC0C0,sp@- | save scratch regs
+ movw sp@(22),sp@- | push exception vector info
+ clrw sp@-
+ movl sp@(22),sp@- | and PC
+ jbsr _C_LABEL(straytrap) | report
+ addql #8,sp | pop args
+ moveml sp@+,#0x0303 | restore regs
+ jra _ASM_LABEL(rei) | all done
+
+ENTRY_NOPROFILE(trap0)
+ clrl sp@- | stack adjust count
+ moveml #0xFFFF,sp@- | save user registers
+ movl usp,a0 | save the user SP
+ movl a0,sp@(FR_SP) | in the savearea
+ movl d0,sp@- | push syscall number
+ jbsr _C_LABEL(syscall) | handle it
+ addql #4,sp | pop syscall arg
+ tstl _C_LABEL(astpending)
+ jne Lrei2
+ tstb _C_LABEL(ssir)
+ jeq Ltrap1
+ movw #SPL1,sr
+ tstb _C_LABEL(ssir)
+ jne Lsir1
+Ltrap1:
+ movl sp@(FR_SP),a0 | grab and restore
+ movl a0,usp | user SP
+ moveml sp@+,#0x7FFF | restore most registers
+ addql #8,sp | pop SP and stack adjust
+ rte
+
+/*
+ * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD)
+ * cachectl(command, addr, length)
+ * command in d0, addr in a1, length in d1
+ */
+ENTRY_NOPROFILE(trap12)
+ movl _C_LABEL(curproc),sp@- | push curproc pointer
+ movl d1,sp@- | push length
+ movl a1,sp@- | push addr
+ movl d0,sp@- | push command
+ jbsr _C_LABEL(cachectl1) | do it
+ lea sp@(16),sp | pop args
+ jra _ASM_LABEL(rei) | all done
+
+/*
+ * Trace (single-step) trap. Kernel-mode is special.
+ * User mode traps are simply passed on to trap().
+ */
+ENTRY_NOPROFILE(trace)
+ clrl sp@- | stack adjust count
+ moveml #0xFFFF,sp@-
+ moveq #T_TRACE,d0
+
+ | Check PSW and see what happen.
+ | T=0 S=0 (should not happen)
+ | T=1 S=0 trace trap from user mode
+ | T=0 S=1 trace trap on a trap instruction
+ | T=1 S=1 trace trap from system mode (kernel breakpoint)
+
+ movw sp@(FR_HW),d1 | get PSW
+ notw d1 | XXX no support for T0 on 680[234]0
+ andw #PSL_TS,d1 | from system mode (T=1, S=1)?
+ jeq Lkbrkpt | yes, kernel breakpoint
+ jra _ASM_LABEL(fault) | no, user-mode fault
+
+/*
+ * Trap 15 is used for:
+ * - GDB breakpoints (in user programs)
+ * - KGDB breakpoints (in the kernel)
+ * - trace traps for SUN binaries (not fully supported yet)
+ * User mode traps are simply passed to trap().
+ */
+ENTRY_NOPROFILE(trap15)
+ clrl sp@- | stack adjust count
+ moveml #0xFFFF,sp@-
+ moveq #T_TRAP15,d0
+ movw sp@(FR_HW),d1 | get PSW
+ andw #PSL_S,d1 | from system mode?
+ jne Lkbrkpt | yes, kernel breakpoint
+ jra _ASM_LABEL(fault) | no, user-mode fault
+
+Lkbrkpt: | Kernel-mode breakpoint or trace trap. (d0=trap_type)
+ | Save the system sp rather than the user sp.
+ movw #PSL_HIGHIPL,sr | lock out interrupts
+ lea sp@(FR_SIZE),a6 | Save stack pointer
+ movl a6,sp@(FR_SP) | from before trap
+
+ | If were are not on tmpstk switch to it.
+ | (so debugger can change the stack pointer)
+ movl a6,d1
+ cmpl #_ASM_LABEL(tmpstk),d1
+ jls Lbrkpt2 | already on tmpstk
+ | Copy frame to the temporary stack
+ movl sp,a0 | a0=src
+ lea _ASM_LABEL(tmpstk)-96,a1 | a1=dst
+ movl a1,sp | sp=new frame
+ moveq #FR_SIZE,d1
+Lbrkpt1:
+ movl a0@+,a1@+
+ subql #4,d1
+ jgt Lbrkpt1
+
+Lbrkpt2:
+ | Call the trap handler for the kernel debugger.
+ | Do not call trap() to do it, so that we can
+ | set breakpoints in trap() if we want. We know
+ | the trap type is either T_TRACE or T_BREAKPOINT.
+ | If we have both DDB and KGDB, let KGDB see it first,
+ | because KGDB will just return 0 if not connected.
+ | Save args in d2, a2
+ movl d0,d2 | trap type
+ movl sp,a2 | frame ptr
+#ifdef KGDB
+ | Let KGDB handle it (if connected)
+ movl a2,sp@- | push frame ptr
+ movl d2,sp@- | push trap type
+ jbsr _C_LABEL(kgdb_trap) | handle the trap
+ addql #8,sp | pop args
+ cmpl #0,d0 | did kgdb handle it?
+ jne Lbrkpt3 | yes, done
+#endif
+#ifdef DDB
+ | Let DDB handle it
+ movl a2,sp@- | push frame ptr
+ movl d2,sp@- | push trap type
+ jbsr _C_LABEL(kdb_trap) | handle the trap
+ addql #8,sp | pop args
+#if 0 /* not needed on hp300 */
+ cmpl #0,d0 | did ddb handle it?
+ jne Lbrkpt3 | yes, done
+#endif
+#endif
+ /* Sun 3 drops into PROM here. */
+Lbrkpt3:
+ | The stack pointer may have been modified, or
+ | data below it modified (by kgdb push call),
+ | so push the hardware frame at the current sp
+ | before restoring registers and returning.
+
+ movl sp@(FR_SP),a0 | modified sp
+ lea sp@(FR_SIZE),a1 | end of our frame
+ movl a1@-,a0@- | copy 2 longs with
+ movl a1@-,a0@- | ... predecrement
+ movl a0,sp@(FR_SP) | sp = h/w frame
+ moveml sp@+,#0x7FFF | restore all but sp
+ movl sp@,sp | ... and sp
+ rte | all done
+
+/* Use common m68k sigreturn */
+#include <m68k/m68k/sigreturn.s>
+
+/*
+ * Interrupt handlers.
+ *
+ * For auto-vectored interrupts, the CPU provides the
+ * vector 0x18+level. Note we count spurious interrupts,
+ * but don't do anything else with them.
+ *
+ * _intrhand_autovec is the entry point for auto-vectored
+ * interrupts.
+ *
+ * For vectored interrupts, we pull the pc, evec, and exception frame
+ * and pass them to the vectored interrupt dispatcher. The vectored
+ * interrupt dispatcher will deal with strays.
+ *
+ * _intrhand_vectored is the entry point for vectored interrupts.
+ */
+
+#define INTERRUPT_SAVEREG moveml #0xC0C0,sp@-
+#define INTERRUPT_RESTOREREG moveml sp@+,#0x0303
+
+ENTRY_NOPROFILE(spurintr) /* Level 0 */
+ addql #1,_C_LABEL(intrcnt)+0
+ addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS
+ jra _ASM_LABEL(rei)
+
+ENTRY_NOPROFILE(intrhand_autovec) /* Levels 1 through 6 */
+ INTERRUPT_SAVEREG
+ movw sp@(22),sp@- | push exception vector
+ clrw sp@-
+ jbsr _C_LABEL(isrdispatch_autovec) | call dispatcher
+ addql #4,sp
+ INTERRUPT_RESTOREREG
+ jra _ASM_LABEL(rei) | all done
+
+ENTRY_NOPROFILE(lev7intr) /* Level 7: NMI */
+ addql #1,_C_LABEL(intrcnt)+32
+ clrl sp@-
+ moveml #0xFFFF,sp@- | save registers
+ movl usp,a0 | and save
+ movl a0,sp@(FR_SP) | the user stack pointer
+ jbsr _C_LABEL(nmihand) | call handler
+ movl sp@(FR_SP),a0 | restore
+ movl a0,usp | user SP
+ moveml sp@+,#0x7FFF | and remaining registers
+ addql #8,sp | pop SP and stack adjust
+ jra _ASM_LABEL(rei) | all done
+
+ENTRY_NOPROFILE(intrhand_vectored)
+ INTERRUPT_SAVEREG
+ lea sp@(16),a1 | get pointer to frame
+ movl a1,sp@-
+ movw sp@(26),d0
+ movl d0,sp@- | push exception vector info
+ movl sp@(26),sp@- | and PC
+ jbsr _C_LABEL(isrdispatch_vectored) | call dispatcher
+ lea sp@(12),sp | pop value args
+ INTERRUPT_RESTOREREG
+ jra _ASM_LABEL(rei) | all done
+
+#if 1 /* XXX wild timer -- how can I disable/enable the interrupt? */
+ENTRY_NOPROFILE(lev5intr)
+ btst #7,0x63000000 | check whether system clock
+ beq 1f
+ movb #1,0x63000000 | clear the interrupt
+ tstl _C_LABEL(clock_enable) | is hardclock() available?
+ jeq 1f
+ INTERRUPT_SAVEREG
+ lea sp@(16),a1 | a1 = &clockframe
+ movl a1,sp@-
+ jbsr _C_LABEL(hardclock) | hardclock(&frame)
+ addql #4,sp
+ addql #1,_C_LABEL(intrcnt)+20
+ INTERRUPT_RESTOREREG
+1:
+ jra _ASM_LABEL(rei) | all done
+#endif
+
+#undef INTERRUPT_SAVEREG
+#undef INTERRUPT_RESTOREREG
+
+/*
+ * Emulation of VAX REI instruction.
+ *
+ * This code deals with checking for and servicing ASTs
+ * (profiling, scheduling) and software interrupts (network, softclock).
+ * We check for ASTs first, just like the VAX. To avoid excess overhead
+ * the T_ASTFLT handling code will also check for software interrupts so we
+ * do not have to do it here. After identifing that we need an AST we
+ * drop the IPL to allow device interrupts.
+ *
+ * This code is complicated by the fact that sendsig may have been called
+ * necessitating a stack cleanup.
+ */
+BSS(ssir,1)
+
+ASENTRY_NOPROFILE(rei)
+ tstl _C_LABEL(astpending) | AST pending?
+ jeq Lchksir | no, go check for SIR
+Lrei1:
+ btst #5,sp@ | yes, are we returning to user mode?
+ jne Lchksir | no, go check for SIR
+ movw #PSL_LOWIPL,sr | lower SPL
+ clrl sp@- | stack adjust
+ moveml #0xFFFF,sp@- | save all registers
+ movl usp,a1 | including
+ movl a1,sp@(FR_SP) | the users SP
+Lrei2:
+ clrl sp@- | VA == none
+ clrl sp@- | code == none
+ movl #T_ASTFLT,sp@- | type == async system trap
+ jbsr _C_LABEL(trap) | go handle it
+ lea sp@(12),sp | pop value args
+ movl sp@(FR_SP),a0 | restore user SP
+ movl a0,usp | from save area
+ movw sp@(FR_ADJ),d0 | need to adjust stack?
+ jne Laststkadj | yes, go to it
+ moveml sp@+,#0x7FFF | no, restore most user regs
+ addql #8,sp | toss SP and stack adjust
+ rte | and do real RTE
+Laststkadj:
+ lea sp@(FR_HW),a1 | pointer to HW frame
+ addql #8,a1 | source pointer
+ movl a1,a0 | source
+ addw d0,a0 | + hole size = dest pointer
+ movl a1@-,a0@- | copy
+ movl a1@-,a0@- | 8 bytes
+ movl a0,sp@(FR_SP) | new SSP
+ moveml sp@+,#0x7FFF | restore user registers
+ movl sp@,sp | and our SP
+ rte | and do real RTE
+Lchksir:
+ tstb _C_LABEL(ssir) | SIR pending?
+ jeq Ldorte | no, all done
+ movl d0,sp@- | need a scratch register
+ movw sp@(4),d0 | get SR
+ andw #PSL_IPL7,d0 | mask all but IPL
+ jne Lnosir | came from interrupt, no can do
+ movl sp@+,d0 | restore scratch register
+Lgotsir:
+ movw #SPL1,sr | prevent others from servicing int
+ tstb _C_LABEL(ssir) | too late?
+ jeq Ldorte | yes, oh well...
+ clrl sp@- | stack adjust
+ moveml #0xFFFF,sp@- | save all registers
+ movl usp,a1 | including
+ movl a1,sp@(FR_SP) | the users SP
+Lsir1:
+ clrl sp@- | VA == none
+ clrl sp@- | code == none
+ movl #T_SSIR,sp@- | type == software interrupt
+ jbsr _C_LABEL(trap) | go handle it
+ lea sp@(12),sp | pop value args
+ movl sp@(FR_SP),a0 | restore
+ movl a0,usp | user SP
+ moveml sp@+,#0x7FFF | and all remaining registers
+ addql #8,sp | pop SP and stack adjust
+ rte
+Lnosir:
+ movl sp@+,d0 | restore scratch register
+Ldorte:
+ rte | real return
+
+/*
+ * Use common m68k sigcode.
+ */
+#include <m68k/m68k/sigcode.s>
+
+/*
+ * Primitives
+ */
+
+/*
+ * Use common m68k support routines.
+ */
+#include <m68k/m68k/support.s>
+
+/*
+ * Use common m68k process manipulation routines.
+ */
+#include <m68k/m68k/proc_subr.s>
+
+ .data
+GLOBAL(curpcb)
+GLOBAL(masterpaddr)
+ .long 0
+
+ASLOCAL(mdpflag)
+ .byte 0 | copy of proc md_flags low byte
+ .align 2
+
+ASBSS(nullpcb, SIZEOF_PCB)
+
+/*
+ * At exit of a process, do a switch for the last time.
+ * Switch to a safe stack and PCB, and select a new process to run. The
+ * old stack and u-area will be freed by the reaper.
+ */
+ENTRY(switch_exit)
+ movl sp@(4),a0
+ /* save state into garbage pcb */
+ movl #_ASM_LABEL(nullpcb),_C_LABEL(curpcb)
+ lea _ASM_LABEL(tmpstk),sp | goto a tmp stack
+
+ /* Schedule the vmspace and stack to be freed. */
+ movl a0,sp@- | exit2(p)
+ jbsr _C_LABEL(exit2)
+ lea sp@(4),sp | pop args
+
+ jra _C_LABEL(cpu_switch)
+
+/*
+ * When no processes are on the runq, Swtch branches to Idle
+ * to wait for something to come ready.
+ */
+ASENTRY_NOPROFILE(Idle)
+ stop #PSL_LOWIPL
+ movw #PSL_HIGHIPL,sr
+ movl _C_LABEL(whichqs),d0
+ jeq _ASM_LABEL(Idle)
+ jra Lsw1
+
+Lbadsw:
+ PANIC("switch")
+ /*NOTREACHED*/
+
+/*
+ * cpu_switch()
+ *
+ * NOTE: On the mc68851 we attempt to avoid flushing the
+ * entire ATC. The effort involved in selective flushing may not be
+ * worth it, maybe we should just flush the whole thing?
+ *
+ * NOTE 2: With the new VM layout we now no longer know if an inactive
+ * user's PTEs have been changed (formerly denoted by the SPTECHG p_flag
+ * bit). For now, we just always flush the full ATC.
+ */
+ENTRY(cpu_switch)
+ movl _C_LABEL(curpcb),a0 | current pcb
+ movw sr,a0@(PCB_PS) | save sr before changing ipl
+#ifdef notyet
+ movl _C_LABEL(curproc),sp@- | remember last proc running
+#endif
+ clrl _C_LABEL(curproc)
+
+ /*
+ * Find the highest-priority queue that isn't empty,
+ * then take the first proc from that queue.
+ */
+ movw #PSL_HIGHIPL,sr | lock out interrupts
+ movl _C_LABEL(whichqs),d0
+ jeq _ASM_LABEL(Idle)
+Lsw1:
+ movl d0,d1
+ negl d0
+ andl d1,d0
+ bfffo d0{#0:#32},d1
+ eorib #31,d1
+
+ movl d1,d0
+ lslb #3,d1 | convert queue number to index
+ addl #_C_LABEL(qs),d1 | locate queue (q)
+ movl d1,a1
+ movl a1@(P_FORW),a0 | p = q->p_forw
+ cmpal d1,a0 | anyone on queue?
+ jeq Lbadsw | no, panic
+ movl a0@(P_FORW),a1@(P_FORW) | q->p_forw = p->p_forw
+ movl a0@(P_FORW),a1 | n = p->p_forw
+ movl d1,a1@(P_BACK) | n->p_back = q
+ cmpal d1,a1 | anyone left on queue?
+ jne Lsw2 | yes, skip
+ movl _C_LABEL(whichqs),d1
+ bclr d0,d1 | no, clear bit
+ movl d1,_C_LABEL(whichqs)
+Lsw2:
+ movl a0,_C_LABEL(curproc)
+ clrl _C_LABEL(want_resched)
+#ifdef notyet
+ movl sp@+,a1
+ cmpl a0,a1 | switching to same proc?
+ jeq Lswdone | yes, skip save and restore
+#endif
+ /*
+ * Save state of previous process in its pcb.
+ */
+ movl _C_LABEL(curpcb),a1
+ moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers
+ movl usp,a2 | grab USP (a2 has been saved)
+ movl a2,a1@(PCB_USP) | and save it
+
+ tstl _C_LABEL(fputype) | Do we have an FPU?
+ jeq Lswnofpsave | No Then don't attempt save.
+ lea a1@(PCB_FPCTX),a2 | pointer to FP save area
+ fsave a2@ | save FP state
+#if defined(M68030) || defined(M68040)
+ tstb a2@ | null state frame?
+ jeq Lswnofpsave | yes, all done
+ fmovem fp0-fp7,a2@(216) | save FP general registers
+ fmovem fpcr/fpsr/fpi,a2@(312) | save FP control registers
+#endif
+Lswnofpsave:
+
+#ifdef DIAGNOSTIC
+ tstl a0@(P_WCHAN)
+ jne Lbadsw
+ cmpb #SRUN,a0@(P_STAT)
+ jne Lbadsw
+#endif
+
+ clrl a0@(P_BACK) | clear back link
+ movb a0@(P_MD_FLAGS+3),mdpflag | low byte of p_md.md_flags
+ movl a0@(P_ADDR),a1 | get p_addr
+ movl a1,_C_LABEL(curpcb)
+
+ /*
+ * Activate process's address space.
+ * XXX Should remember the last USTP value loaded, and call this
+ * XXX only of it has changed.
+ */
+ pea a0@ | push proc
+ jbsr _C_LABEL(pmap_activate) | pmap_activate(p)
+ addql #4,sp
+ movl _C_LABEL(curpcb),a1 | restore p_addr
+
+ lea _ASM_LABEL(tmpstk),sp | now goto a tmp stack for NMI
+
+ moveml a1@(PCB_REGS),#0xFCFC | and registers
+ movl a1@(PCB_USP),a0
+ movl a0,usp | and USP
+
+ tstl _C_LABEL(fputype) | If we don't have an FPU,
+ jeq Lnofprest | don't try to restore it.
+ lea a1@(PCB_FPCTX),a0 | pointer to FP save area
+ tstb a0@ | null state frame?
+ jeq Lresfprest | yes, easy
+#if defined(M68030) || defined(M68040)
+#if defined(M68040)
+ cmpl #FPU_68040,_C_LABEL(fputype) | 68040?
+ jne Lresnot040 | no, skip
+ clrl sp@- | yes...
+ frestore sp@+ | ...magic!
+Lresnot040:
+#endif
+ fmovem a0@(312),fpcr/fpsr/fpi | restore FP control registers
+ fmovem a0@(216),fp0-fp7 | restore FP general registers
+#endif
+Lresfprest:
+ frestore a0@ | restore state
+Lnofprest:
+ movw a1@(PCB_PS),sr | no, restore PS
+ moveq #1,d0 | return 1 (for alternate returns)
+ rts
+
+/*
+ * savectx(pcb)
+ * Update pcb, saving current processor state.
+ */
+ENTRY(savectx)
+ movl sp@(4),a1
+ movw sr,a1@(PCB_PS)
+ movl usp,a0 | grab USP
+ movl a0,a1@(PCB_USP) | and save it
+ moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers
+
+ tstl _C_LABEL(fputype) | Do we have FPU?
+ jeq Lsvnofpsave | No? Then don't save state.
+ lea a1@(PCB_FPCTX),a0 | pointer to FP save area
+ fsave a0@ | save FP state
+ tstb a0@ | null state frame?
+ jeq Lsvnofpsave | yes, all done
+ fmovem fp0-fp7,a0@(216) | save FP general registers
+ fmovem fpcr/fpsr/fpi,a0@(312) | save FP control registers
+Lsvnofpsave:
+ moveq #0,d0 | return 0
+ rts
+
+#if defined(M68040)
+ENTRY(suline)
+ movl sp@(4),a0 | address to write
+ movl _C_LABEL(curpcb),a1 | current pcb
+ movl #Lslerr,a1@(PCB_ONFAULT) | where to return to o0,dfc
+ .word 0xf508 | pflush a0@
+ moveq #5,d0 | super space
+ movc d0,dfc
+ .word 0xf508 | pflush a0@
+ movc d1,dfc
+ rts
+Lmotommu4:
+#endif
+ tstl _C_LABEL(mmutype) | is 68851?
+ jpl Lmc68851b |
+ movl sp@(4),a0 | get addr to flush
+ pflush #0,#0,a0@ | flush address from both sides
+ movl #DC_CLEAR,d0
+ movc d0,cacr | invalidate on-chip data cache
+ rts
+Lmc68851b:
+ pflushs #0,#0,a0@ | flush address from both sides
+ rts
+
+ENTRY(getsr)
+ moveq #0,d0
+ movw sr,d0
+ rts
+
+ENTRY(ecacheon)
+ rts
+
+ENTRY(ecacheoff)
+ rts
+
+/*
+ * Get callers current SP value.
+ * Note that simply taking the address of a local variable in a C function
+ * doesn't work because callee saved registers may be outside the stack frame
+ * defined by A6 (e.g. GCC generated code).
+ */
+ENTRY(getsp)
+ movl sp,d0 | get current SP
+ addql #4,d0 | compensate for return address
+ rts
+
+ENTRY_NOPROFILE(getsfc)
+ movc sfc,d0
+ rts
+
+ENTRY_NOPROFILE(getdfc)
+ movc dfc,d0
+ rts
+
+/*
+ * Load a new user segment table pointer.
+ */
+ENTRY(loadustp)
+ movl sp@(4),d0 | new USTP
+ moveq #PGSHIFT, d1
+ lsll d1,d0 | convert to addr
+#if defined(M68040)
+ cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
+ jne LmotommuC | no, skip
+ .long 0x4e7b0806 | movc d0,urp
+ rts
+LmotommuC:
+#endif
+ lea _C_LABEL(protocrp),a0 | CRP prototype
+ movl d0,a0@(4) | stash USTP
+ pmove a0@,crp | load root pointer
+ movl #DC_CLEAR,d0
+ movc d0,cacr | invalidate on-chip d-cache
+ rts | since pmove flushes TLB
+
+ENTRY(ploadw)
+#if defined(M68040)
+ cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
+ jeq Lploadwskp | yes, skip
+#endif
+ movl sp@(4),a0 | address to load
+ ploadw #1,a0@ | pre-load translation
+#if defined(M68040)
+Lploadwskp:
+#endif
+ rts
+
+/*
+ * Set processor priority level calls. Most are implemented with
+ * inline asm expansions. However, spl0 requires special handling
+ * as we need to check for our emulated software interrupts.
+ */
+
+ENTRY(spl0)
+ moveq #0,d0
+ movw sr,d0 | get old SR for return
+ movw #PSL_LOWIPL,sr | restore new SR
+ tstb _C_LABEL(ssir) | software interrupt pending?
+ jeq Lspldone | no, all done
+ subql #4,sp | make room for RTE frame
+ movl sp@(4),sp@(2) | position return address
+ clrw sp@(6) | set frame type 0
+ movw #PSL_LOWIPL,sp@ | and new SR
+ jra Lgotsir | go handle it
+Lspldone:
+ rts
+
+/*
+ * _delay(unsigned N)
+ *
+ * Delay for at least (N/256) microseconds.
+ * This routine depends on the variable: delay_divisor
+ * which should be set based on the CPU clock rate.
+ */
+GLOBAL(_delay)
+ | d0 = arg = (usecs << 8)
+ movl sp@(4),d0
+ | d1 = delay_divisor
+ movl _C_LABEL(delay_divisor),d1
+L_delay:
+ subl d1,d0
+ jgt L_delay
+ rts
+
+/*
+ * Save and restore 68881 state.
+ */
+ENTRY(m68881_save)
+ movl sp@(4),a0 | save area pointer
+ fsave a0@ | save state
+ tstb a0@ | null state frame?
+ jeq Lm68881sdone | yes, all done
+ fmovem fp0-fp7,a0@(216) | save FP general registers
+ fmovem fpcr/fpsr/fpi,a0@(312) | save FP control registers
+Lm68881sdone:
+ rts
+
+ENTRY(m68881_restore)
+ movl sp@(4),a0 | save area pointer
+ tstb a0@ | null state frame?
+ jeq Lm68881rdone | yes, easy
+ fmovem a0@(312),fpcr/fpsr/fpi | restore FP control registers
+ fmovem a0@(216),fp0-fp7 | restore FP general registers
+Lm68881rdone:
+ frestore a0@ | restore state
+ rts
+
+/*
+ * Do a dump.
+ * Called by auto-restart.
+ */
+GLOBAL(doadump)
+ jbsr _C_LABEL(dumpsys)
+ jbsr _C_LABEL(doboot)
+ /*NOTREACHED*/
+
+/*
+ * Handle the nitty-gritty of rebooting the machine.
+ * Basically we just turn off the MMU, restore the initial VBR
+ * and return to monitor.
+ */
+ENTRY_NOPROFILE(doboot)
+ movw #PSL_HIGHIPL,sr | no interrupts
+#if defined(M68040)
+ cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
+ jeq Lnocache5 | yes, skip
+#endif
+ movl #CACHE_OFF,d0
+ movc d0,cacr | disable on-chip cache(s)
+ movl #0,a7@ | value for pmove to TC
+ pmove a7@,tc | disable MMU
+ lea _ASM_LABEL(nullrp),a0
+ pmove a0@,crp | Invalidate CPU root pointer
+ pmove a0@,srp | and the Supervisor root pointer
+ jra Lbootcommon
+#if defined(M68040)
+Lnocache5:
+ .word 0xf4f8 | cpusha bc
+ movql #0,d0
+ movc d0,cacr
+ .long 0x4e7b0003 | movc d0,tc (disable MMU)
+ .long 0x4e7b0806 | movc d0,URP
+ .long 0x4e7b0807 | movc d0,SRP
+#endif /* M68040 */
+Lbootcommon:
+ movl _C_LABEL(boothowto),d0 | load howto
+ movl sp@(4),d2 | arg
+ lea _ASM_LABEL(tmpstk),sp | physical SP in case of NMI
+ movl #0,d3
+ movc d3,vbr | monitor VBR
+#if 0
+ andl #0,d0 | mask off
+ tstl d0 |
+ bne Lsboot | sboot?
+ tstl d2
+ beq Ldoreset
+#endif
+
+ movl #0x41000000,a0 | base = (int **)0x4100.0000
+ movl a0@,d0 | *((int *)base[0])
+ movc d0,isp | set initial stack pointer
+ movc d0,msp | set initial stack pointer
+ movl a0@(4),a0 | *((int (*)(void))base[1])
+ jmp a0@ | go cold boot!
+
+/*
+ * Utility call for LUNA rom monitor routines
+ */
+ENTRY_NOPROFILE(romcall)
+ link a6,#-8
+ movel a6@(8),d0 | 1st arg is routine no.
+ moveq #0,d1
+ movw sr,d1 | get old SR for return
+ movel d1,a6@(-4)
+ movw #PSL_HIGHIPL,sr | splhigh()
+ movc vbr,d1
+ movel d1,a6@(-8)
+ movl #0,d1
+ movc d1,vbr | switch to monitor VBR
+ movel #0x41000000,a0 | base = (int **)0x41000000
+ movel a6@(12),sp@-
+ movel a0@(d0:l:4),a0 | (*(int (*)(int))base[n])(arg)
+ jbsr a0@
+ movl a6@(-8),d1 | restore previous VBR
+ movc d1,vbr
+ movel a6@(-4),d1
+ movew d1,sr | splx()
+ unlk a6
+ rts
+
+ .data
+GLOBAL(cputype)
+ .long CPU_68030 | default to 68030
+GLOBAL(mmutype)
+ .long MMU_68030 | default to 68030
+GLOBAL(fputype)
+ .long FPU_68881 | default to 68881
+
+GLOBAL(protosrp)
+ .long 0x80000202,0 | prototype supervisor root pointer
+GLOBAL(protocrp)
+ .long 0x80000002,0 | prototype cpu root pointer
+
+GLOBAL(prototc)
+ .long 0x82c0aa00 | tc (SRP,CRP,4KB page, TIA/TIB=10/10bits)
+GLOBAL(protott0) | tt0 0x4000.0000-0x7fff.ffff
+ .long 0x403f8543 |
+GLOBAL(protott1) | tt1 0x8000.0000-0xffff.ffff
+ .long 0x807f8543 |
+GLOBAL(proto040tc)
+ .long 0x8000 | tc (4KB page)
+GLOBAL(proto040tt0) | tt0 0x4000.0000-0x7fff.ffff
+ .long 0x403fa040 | kernel only, cache inhebit, serialized
+GLOBAL(proto040tt1) | tt1 0x8000.0000-0xfeff.ffff
+ .long 0x807ea040 | kernel only, cache inhebit, serialized
+nullrp:
+ .long 0x7fff0001 | do-nothing MMU root pointer
+
+GLOBAL(memavail)
+ .long 0
+GLOBAL(want_resched)
+ .long 0
+GLOBAL(proc0paddr)
+ .long 0
+GLOBAL(boothowto)
+ .long 0
+GLOBAL(bootdev)
+ .long 0
+GLOBAL(hwplanemask)
+ .long 0
+GLOBAL(bootarg)
+ .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+
+#ifdef DEBUG
+ASGLOBAL(fulltflush)
+ .long 0
+
+ASGLOBAL(fullcflush)
+ .long 0
+#endif
+
+GLOBAL(intiobase)
+ .long 0 | KVA of base of internal IO space
+GLOBAL(intiolimit)
+ .long 0 | KVA of end of internal IO space
+GLOBAL(intiobase_phys)
+ .long 0 | PA of board's I/O registers
+GLOBAL(intiotop_phys)
+ .long 0 | PA of top of board's I/O registers
+
+GLOBAL(intrnames)
+ .asciz "spur"
+ .asciz "lev1"
+ .asciz "scsi"
+ .asciz "network"
+ .asciz "lev4"
+ .asciz "clock"
+ .asciz "serial"
+ .asciz "nmi"
+ .asciz "statclock"
+GLOBAL(eintrnames)
+ .even
+GLOBAL(intrcnt)
+ .long 0,0,0,0,0,0,0,0,0,0
+GLOBAL(eintrcnt)
diff --git a/sys/arch/luna68k/luna68k/machdep.c b/sys/arch/luna68k/luna68k/machdep.c
new file mode 100644
index 00000000000..5ff59d0e196
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/machdep.c
@@ -0,0 +1,991 @@
+/* $NetBSD: machdep.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $");
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/map.h>
+#include <sys/proc.h>
+#include <sys/buf.h>
+#include <sys/reboot.h>
+#include <sys/conf.h>
+#include <sys/file.h>
+#include <sys/clist.h>
+#include <sys/callout.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/msgbuf.h>
+#include <sys/ioctl.h>
+#include <sys/tty.h>
+#include <sys/mount.h>
+#include <sys/user.h>
+#include <sys/exec.h>
+#include <sys/core.h>
+#include <sys/kcore.h>
+#include <sys/vnode.h>
+#include <sys/syscallargs.h>
+#ifdef KGDB
+#include <sys/kgdb.h>
+#endif
+
+#include <vm/vm.h>
+#include <vm/vm_map.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <sys/sysctl.h>
+
+#include <machine/cpu.h>
+#include <machine/reg.h>
+#include <machine/psl.h>
+#include <machine/pte.h>
+#include <machine/kcore.h> /* XXX should be pulled in by sys/kcore.h */
+
+#include <dev/cons.h>
+
+#if defined(DDB)
+#include <machine/db_machdep.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_extern.h>
+#endif
+
+/*
+ * Info for CTL_HW
+ */
+char machine[] = MACHINE;
+char cpu_model[60];
+extern char version[];
+
+extern char kernel_text[];
+extern char etext[];
+
+vm_map_t exec_map = NULL;
+vm_map_t mb_map = NULL;
+vm_map_t phys_map = NULL;
+
+caddr_t msgbufaddr;
+int maxmem; /* max memory per process */
+int physmem; /* set by locore */
+/*
+ * safepri is a safe priority for sleep to set for a spin-wait
+ * during autoconfiguration or after a panic.
+ */
+int safepri = PSL_LOWIPL;
+
+void luna68k_init __P((void));
+void identifycpu __P((void));
+void dumpsys __P((void));
+
+void straytrap __P((int, u_short));
+void nmihand __P((struct frame));
+
+int cpu_dumpsize __P((void));
+int cpu_dump __P((int (*)(dev_t, daddr_t, caddr_t, size_t), daddr_t *));
+void cpu_init_kcore_hdr __P((void));
+
+/*
+ * Machine-independent crash dump header info.
+ */
+cpu_kcore_hdr_t cpu_kcore_hdr;
+
+int machtype; /* model: 1 for LUNA-1, 2 for LUNA-2 */
+int sysconsole; /* console: 0 for ttya, 1 for video */
+
+extern struct consdev syscons;
+extern void omfb_cnattach __P((void));
+extern void ws_cnattach __P((void));
+extern void syscnattach __P((int));
+
+/*
+ * On the 68020/68030, the value of delay_divisor is roughly
+ * 2048 / cpuspeed (where cpuspeed is in MHz).
+ *
+ * On the 68040/68060(?), the value of delay_divisor is roughly
+ * 759 / cpuspeed (where cpuspeed is in MHz).
+ * XXX -- is the above formula correct?
+ */
+int cpuspeed = 25; /* only used for printing later */
+int delay_divisor = 300; /* for delay() loop count */
+
+/*
+ * Early initialization, before main() is called.
+ */
+void
+luna68k_init()
+{
+ int i;
+
+ extern paddr_t avail_start, avail_end;
+
+ /*
+ * Tell the VM system about available physical memory. The
+ * luna68k only has one segment.
+ */
+ uvm_page_physload(atop(avail_start), atop(avail_end),
+ atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT);
+
+ /*
+ * Initialize error message buffer (at end of core).
+ * avail_end was pre-decremented in pmap_bootstrap to compensate.
+ */
+ for (i = 0; i < btoc(MSGBUFSIZE); i++)
+ pmap_enter(pmap_kernel(), (vaddr_t)msgbufaddr + i * NBPG,
+ avail_end + i * NBPG, VM_PROT_READ|VM_PROT_WRITE,
+ VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
+ initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE));
+}
+
+/*
+ * Console initialization: called early on from main,
+ */
+void
+consinit()
+{
+ volatile unsigned char *pio0 = (void *)0x49000000;
+ int sw1, i;
+ char *cp;
+ extern char bootarg[64];
+
+ pio0[3] = 0xb6;
+ pio0[2] = 1 << 6; /* enable parity check */
+
+ pio0[3] = 0xb6;
+ sw1 = pio0[0]; /* dipssw1 value */
+ sw1 ^= 0xff;
+ sysconsole = !(sw1 & 0x2); /* console selection */
+
+ boothowto = 0;
+ i = 0;
+ /*
+ * 'bootarg' has;
+ * "<args of x command> ENADDR=<addr> HOST=<host> SERVER=<name>"
+ * where <addr> is MAC address of which network loader used (not
+ * necessarily same as one at 0x4101.FFE0), <host> and <name>
+ * are the values of HOST and SERVER environment variables,
+ *
+ * NetBSD/luna68k cares only the first argment; any of "sda".
+ */
+ for (cp = bootarg; *cp != ' '; cp++) {
+ switch (*cp) {
+ case 's':
+ boothowto |= RB_SINGLE;
+ break;
+ case 'd':
+ boothowto |= RB_KDB;
+ break;
+ case 'a':
+ boothowto |= RB_ASKNAME;
+ break;
+ }
+ if (i++ >= sizeof(bootarg))
+ break;
+ }
+ if (boothowto == 0)
+ boothowto = (sw1 & 0x1) ? RB_SINGLE : 0;
+
+ if (sysconsole == 0)
+ syscnattach(0);
+ else {
+ omfb_cnattach();
+ ws_cnattach();
+ }
+
+#ifdef DDB
+ {
+ extern int end;
+ extern int *esym;
+
+ ddb_init(*(int *)&end, ((int *)&end) + 1, esym);
+ }
+ if (boothowto & RB_KDB)
+ cpu_Debugger();
+#endif
+}
+
+/*
+ * cpu_startup: allocate memory for variable-sized tables.
+ */
+void
+cpu_startup()
+{
+ int i;
+ caddr_t v;
+ int base, residual;
+ vaddr_t minaddr, maxaddr;
+ vsize_t size;
+ char pbuf[9];
+ extern void greeting __P((void));
+
+ /*
+ * Initialize the kernel crash dump header.
+ */
+ cpu_init_kcore_hdr();
+
+ /*
+ * Good {morning,afternoon,evening,night}.
+ */
+ printf(version);
+ identifycpu();
+
+ format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
+ printf("total memory = %s\n", pbuf);
+
+ /*
+ * Find out how much space we need, allocate it,
+ * and then give everything true virtual addresses.
+ */
+ size = (int)allocsys(NULL, NULL);
+ if ((v = (caddr_t)uvm_km_alloc(kernel_map, round_page(size))) == 0)
+ panic("startup: no room for tables");
+ if (allocsys(v, NULL) - v != size)
+ panic("startup: table size inconsistency");
+
+ /*
+ * Now allocate buffers proper. They are different than the above
+ * in that they usually occupy more virtual memory than physical.
+ */
+ size = MAXBSIZE * nbuf;
+ if (uvm_map(kernel_map, (vaddr_t *) &buffers, round_page(size),
+ NULL, UVM_UNKNOWN_OFFSET,
+ UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE,
+ UVM_ADV_NORMAL, 0)) != KERN_SUCCESS)
+ panic("startup: cannot allocate VM for buffers");
+ minaddr = (vaddr_t)buffers;
+ if ((bufpages / nbuf) >= btoc(MAXBSIZE)) {
+ /* don't want to alloc more physical mem than needed */
+ bufpages = btoc(MAXBSIZE) * nbuf;
+ }
+ base = bufpages / nbuf;
+ residual = bufpages % nbuf;
+ for (i = 0; i < nbuf; i++) {
+ vsize_t curbufsize;
+ vaddr_t curbuf;
+ struct vm_page *pg;
+
+ /*
+ * Each buffer has MAXBSIZE bytes of VM space allocated. Of
+ * that MAXBSIZE space, we allocate and map (base+1) pages
+ * for the first "residual" buffers, and then we allocate
+ * "base" pages for the rest.
+ */
+ curbuf = (vsize_t) buffers + (i * MAXBSIZE);
+ curbufsize = NBPG * ((i < residual) ? (base+1) : base);
+
+ while (curbufsize) {
+ pg = uvm_pagealloc(NULL, 0, NULL, 0);
+ if (pg == NULL)
+ panic("cpu_startup: not enough memory for "
+ "buffer cache");
+ pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg),
+ VM_PROT_READ|VM_PROT_WRITE);
+ curbuf += PAGE_SIZE;
+ curbufsize -= PAGE_SIZE;
+ }
+ }
+
+ /*
+ * Allocate a submap for exec arguments. This map effectively
+ * limits the number of processes exec'ing at any time.
+ */
+ exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
+ 16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
+
+ /*
+ * Allocate a submap for physio
+ */
+ phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
+ VM_PHYS_SIZE, 0, FALSE, NULL);
+
+ /*
+ * Finally, allocate mbuf cluster submap.
+ */
+ mb_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
+ nmbclusters * mclbytes, VM_MAP_INTRSAFE,
+ FALSE, NULL);
+
+ /*
+ * Initialize callouts
+ */
+ callfree = callout;
+ for (i = 1; i < ncallout; i++)
+ callout[i-1].c_next = &callout[i];
+ callout[i-1].c_next = NULL;
+
+ format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
+ printf("avail memory = %s\n", pbuf);
+ format_bytes(pbuf, sizeof(pbuf), bufpages * NBPG);
+ printf("using %d buffers containing %s of memory\n", nbuf, pbuf);
+
+ /*
+ * Tell the VM system that the area before the text segment
+ * is invalid.
+ *
+ * XXX Should just change KERNBASE and VM_MIN_KERNEL_ADDRESS,
+ * XXX but not right now.
+ */
+ if (uvm_map_protect(kernel_map, 0, round_page(&kernel_text),
+ UVM_PROT_NONE, TRUE) != KERN_SUCCESS)
+ panic("can't mark pre-text pages off-limits");
+
+ /*
+ * Tell the VM system that writing to kernel text isn't allowed.
+ * If we don't, we might end up COW'ing the text segment!
+ */
+ if (uvm_map_protect(kernel_map, trunc_page(&kernel_text),
+ trunc_page(&etext), UVM_PROT_READ|UVM_PROT_EXEC, TRUE)
+ != KERN_SUCCESS)
+ panic("can't protect kernel text");
+
+ /*
+ * Set up buffers, so they can be used to read disk labels.
+ */
+ bufinit();
+
+ /*
+ * Say "Hi" to the world
+ */
+ greeting();
+}
+
+/*
+ * Set registers on exec.
+ */
+void
+setregs(p, pack, stack)
+ register struct proc *p;
+ struct exec_package *pack;
+ u_long stack;
+{
+ struct frame *frame = (struct frame *)p->p_md.md_regs;
+ extern int fputype;
+
+ frame->f_sr = PSL_USERSET;
+ frame->f_pc = pack->ep_entry & ~1;
+ frame->f_regs[D0] = 0;
+ frame->f_regs[D1] = 0;
+ frame->f_regs[D2] = 0;
+ frame->f_regs[D3] = 0;
+ frame->f_regs[D4] = 0;
+ frame->f_regs[D5] = 0;
+ frame->f_regs[D6] = 0;
+ frame->f_regs[D7] = 0;
+ frame->f_regs[A0] = 0;
+ frame->f_regs[A1] = 0;
+ frame->f_regs[A2] = (int)PS_STRINGS;
+ frame->f_regs[A3] = 0;
+ frame->f_regs[A4] = 0;
+ frame->f_regs[A5] = 0;
+ frame->f_regs[A6] = 0;
+ frame->f_regs[SP] = stack;
+
+ /* restore a null state frame */
+ p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0;
+ if (fputype)
+ m68881_restore(&p->p_addr->u_pcb.pcb_fpregs);
+}
+
+void
+identifycpu()
+{
+ extern int cputype;
+ char *cpu;
+
+ bzero(cpu_model, sizeof(cpu_model));
+ switch (cputype) {
+ case CPU_68030:
+ cpu = "MC68030 CPU+MMU, MC68882 FPU";
+ machtype = LUNA_I;
+ cpuspeed = 20; delay_divisor = 102; /* 20MHz 68030 */
+ hz = 60;
+ break;
+#ifdef M68040
+ case CPU_68040:
+ cpu = "MC68040 CPU+MMU+FPU, 4k on-chip physical I/D caches";
+ machtype = LUNA_II;
+ cpuspeed = 25; delay_divisor = 300; /* 25MHz 68040 */
+ break;
+#endif
+ default:
+ panic("unknown CPU type");
+ }
+ strcpy(cpu_model, cpu);
+ printf("%s\n", cpu_model);
+}
+
+/*
+ * machine dependent system variables.
+ */
+int
+cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
+ int *name;
+ u_int namelen;
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+ struct proc *p;
+{
+ dev_t consdev;
+
+ /* all sysctl names at this level are terminal */
+ if (namelen != 1)
+ return (ENOTDIR); /* overloaded */
+
+ switch (name[0]) {
+ case CPU_CONSDEV:
+ if (cn_tab != NULL)
+ consdev = cn_tab->cn_dev;
+ else
+ consdev = NODEV;
+ return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
+ sizeof consdev));
+ default:
+ return (EOPNOTSUPP);
+ }
+ /* NOTREACHED */
+}
+
+int waittime = -1;
+
+void
+cpu_reboot(howto, bootstr)
+ volatile int howto; /* XXX to shutup GCC XXX */
+ char *bootstr;
+{
+ extern void doboot __P((void));
+
+ /* take a snap shot before clobbering any registers */
+ if (curproc && curproc->p_addr)
+ savectx(&curproc->p_addr->u_pcb);
+
+ /* If system is hold, just halt. */
+ if (cold) {
+ howto |= RB_HALT;
+ goto haltsys;
+ }
+
+ boothowto = howto;
+ if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
+ waittime = 0;
+ vfs_shutdown();
+ /*
+ * If we've been adjusting the clock, the todr
+ * will be out of synch; adjust it now.
+ */
+ resettodr();
+ }
+
+ /* Disable interrupts. */
+ splhigh();
+
+ /* If rebooting and a dump is requested, do it. */
+ if (howto & RB_DUMP)
+ dumpsys();
+
+haltsys:
+ /* Run any shutdown hooks. */
+ doshutdownhooks();
+
+ /* Finally, halt/reboot the system. */
+ if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
+ u_int8_t *pio = (void *)0x4d000000;
+
+ printf("power is going down.\n");
+ DELAY(100000);
+ pio[3] = 0x94;
+ pio[2] = 0 << 4;
+ for (;;) /* NOP */;
+ }
+ if (howto & RB_HALT) {
+ printf("System halted. Hit any key to reboot.\n\n");
+ (void)cngetc();
+ }
+
+ printf("rebooting...\n");
+ DELAY(100000);
+ doboot();
+ /*NOTREACHED*/
+ while (1) ;
+}
+
+/*
+ * Initialize the kernel crash dump header.
+ */
+void
+cpu_init_kcore_hdr()
+{
+ cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
+ struct m68k_kcore_hdr *m = &h->un._m68k;
+ extern char end[];
+
+ bzero(&cpu_kcore_hdr, sizeof(cpu_kcore_hdr));
+
+ /*
+ * Initialize the `dispatcher' portion of the header.
+ */
+ strcpy(h->name, machine);
+ h->page_size = NBPG;
+ h->kernbase = KERNBASE;
+
+ /*
+ * Fill in information about our MMU configuration.
+ */
+ m->mmutype = mmutype;
+ m->sg_v = SG_V;
+ m->sg_frame = SG_FRAME;
+ m->sg_ishift = SG_ISHIFT;
+ m->sg_pmask = SG_PMASK;
+ m->sg40_shift1 = SG4_SHIFT1;
+ m->sg40_mask2 = SG4_MASK2;
+ m->sg40_shift2 = SG4_SHIFT2;
+ m->sg40_mask3 = SG4_MASK3;
+ m->sg40_shift3 = SG4_SHIFT3;
+ m->sg40_addr1 = SG4_ADDR1;
+ m->sg40_addr2 = SG4_ADDR2;
+ m->pg_v = PG_V;
+ m->pg_frame = PG_FRAME;
+
+ /*
+ * Initialize pointer to kernel segment table.
+ */
+ m->sysseg_pa = (u_int32_t)(pmap_kernel()->pm_stpa);
+
+ /*
+ * Initialize relocation value such that:
+ *
+ * pa = (va - KERNBASE) + reloc
+ *
+ * Since we're linked and loaded at the same place,
+ * and the kernel is mapped va == pa, this is 0.
+ */
+ m->reloc = 0;
+
+ /*
+ * Define the end of the relocatable range.
+ */
+ m->relocend = (u_int32_t)end;
+
+ /*
+ * The luna68k has one contiguous memory segment.
+ */
+ m->ram_segs[0].start = 0 /* lowram */;
+ m->ram_segs[0].size = ctob(physmem);
+}
+
+/*
+ * Compute the size of the machine-dependent crash dump header.
+ * Returns size in disk blocks.
+ */
+int
+cpu_dumpsize()
+{
+ int size;
+
+ size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t));
+ return (btodb(roundup(size, dbtob(1))));
+}
+
+/*
+ * Called by dumpsys() to dump the machine-dependent header.
+ */
+int
+cpu_dump(dump, blknop)
+ int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
+ daddr_t *blknop;
+{
+ int buf[dbtob(1) / sizeof(int)];
+ cpu_kcore_hdr_t *chdr;
+ kcore_seg_t *kseg;
+ int error;
+
+ kseg = (kcore_seg_t *)buf;
+ chdr = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(kcore_seg_t)) /
+ sizeof(int)];
+
+ /* Create the segment header. */
+ CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
+ kseg->c_size = dbtob(1) - ALIGN(sizeof(kcore_seg_t));
+
+ bcopy(&cpu_kcore_hdr, chdr, sizeof(cpu_kcore_hdr_t));
+ error = (*dump)(dumpdev, *blknop, (caddr_t)buf, sizeof(buf));
+ *blknop += btodb(sizeof(buf));
+ return (error);
+}
+
+/*
+ * These variables are needed by /sbin/savecore
+ */
+u_long dumpmag = 0x8fca0101; /* magic number */
+int dumpsize = 0; /* pages */
+long dumplo = 0; /* blocks */
+
+/*
+ * This is called by main to set dumplo and dumpsize.
+ * Dumps always skip the first NBPG of disk space
+ * in case there might be a disk label stored there.
+ * If there is extra space, put dump at the end to
+ * reduce the chance that swapping trashes it.
+ */
+void
+cpu_dumpconf()
+{
+ int chdrsize; /* size of dump header */
+ int nblks; /* size of dump area */
+ int maj;
+
+ if (dumpdev == NODEV)
+ return;
+ maj = major(dumpdev);
+ if (maj < 0 || maj >= nblkdev)
+ panic("dumpconf: bad dumpdev=0x%x", dumpdev);
+ if (bdevsw[maj].d_psize == NULL)
+ return;
+ nblks = (*bdevsw[maj].d_psize)(dumpdev);
+ chdrsize = cpu_dumpsize();
+
+ dumpsize = btoc(cpu_kcore_hdr.un._m68k.ram_segs[0].size);
+
+ /*
+ * Check do see if we will fit. Note we always skip the
+ * first NBPG in case there is a disk label there.
+ */
+ if (nblks < (ctod(dumpsize) + chdrsize + ctod(1))) {
+ dumpsize = 0;
+ dumplo = -1;
+ return;
+ }
+
+ /*
+ * Put dump at the end of the partition.
+ */
+ dumplo = (nblks - 1) - ctod(dumpsize) - chdrsize;
+}
+
+/*
+ * Dump physical memory onto the dump device. Called by cpu_reboot().
+ */
+void
+dumpsys()
+{
+ daddr_t blkno; /* current block to write */
+ /* dump routine */
+ int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
+ int pg; /* page being dumped */
+ paddr_t maddr; /* PA being dumped */
+ int error; /* error code from (*dump)() */
+
+ /* XXX initialized here because of gcc lossage */
+ maddr = 0 /* lowram */;
+ pg = 0;
+
+ /* Don't put dump messages in msgbuf. */
+ msgbufenabled = 0;
+
+ /* Make sure dump device is valid. */
+ if (dumpdev == NODEV)
+ return;
+ if (dumpsize == 0) {
+ cpu_dumpconf();
+ if (dumpsize == 0)
+ return;
+ }
+ if (dumplo <= 0) {
+ printf("\ndump to dev %u,%u not possible\n", major(dumpdev),
+ minor(dumpdev));
+ return;
+ }
+ dump = bdevsw[major(dumpdev)].d_dump;
+ blkno = dumplo;
+
+ printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev),
+ minor(dumpdev), dumplo);
+
+ printf("dump ");
+
+ /* Write the dump header. */
+ error = cpu_dump(dump, &blkno);
+ if (error)
+ goto bad;
+
+ for (pg = 0; pg < dumpsize; pg++) {
+#define NPGMB (1024*1024/NBPG)
+ /* print out how many MBs we have dumped */
+ if (pg && (pg % NPGMB) == 0)
+ printf("%d ", pg / NPGMB);
+#undef NPGMB
+ pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr,
+ VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
+
+ error = (*dump)(dumpdev, blkno, vmmap, NBPG);
+ bad:
+ switch (error) {
+ case 0:
+ maddr += NBPG;
+ blkno += btodb(NBPG);
+ break;
+
+ case ENXIO:
+ printf("device bad\n");
+ return;
+
+ case EFAULT:
+ printf("device not ready\n");
+ return;
+
+ case EINVAL:
+ printf("area improper\n");
+ return;
+
+ case EIO:
+ printf("i/o error\n");
+ return;
+
+ case EINTR:
+ printf("aborted from console\n");
+ return;
+
+ default:
+ printf("error %d\n", error);
+ return;
+ }
+ }
+ printf("succeeded\n");
+}
+
+void
+straytrap(pc, evec)
+ int pc;
+ u_short evec;
+{
+ printf("unexpected trap (vector offset %x) from %x\n",
+ evec & 0xFFF, pc);
+}
+
+int *nofault;
+
+int
+badaddr(addr, nbytes)
+ register caddr_t addr;
+ int nbytes;
+{
+ register int i;
+ label_t faultbuf;
+
+#ifdef lint
+ i = *addr; if (i) return (0);
+#endif
+
+ nofault = (int *) &faultbuf;
+ if (setjmp((label_t *)nofault)) {
+ nofault = (int *) 0;
+ return(1);
+ }
+
+ switch (nbytes) {
+ case 1:
+ i = *(volatile char *)addr;
+ break;
+
+ case 2:
+ i = *(volatile short *)addr;
+ break;
+
+ case 4:
+ i = *(volatile int *)addr;
+ break;
+
+ default:
+ panic("badaddr: bad request");
+ }
+ nofault = (int *) 0;
+ return (0);
+}
+
+void luna68k_abort __P((char *));
+
+static int innmihand; /* simple mutex */
+
+/*
+ * Level 7 interrupts are caused by e.g. the ABORT switch.
+ *
+ * If we have DDB, then break into DDB on ABORT. In a production
+ * environment, bumping the ABORT switch would be bad, so we enable
+ * panic'ing on ABORT with the kernel option "PANICBUTTON".
+ */
+void
+nmihand(frame)
+ struct frame frame;
+{
+ /* Prevent unwanted recursion */
+ if (innmihand)
+ return;
+ innmihand = 1;
+
+ luna68k_abort("ABORT SWITCH");
+}
+
+/*
+ * Common code for handling ABORT signals from buttons, switches,
+ * serial lines, etc.
+ */
+void
+luna68k_abort(cp)
+ char *cp;
+{
+#ifdef DDB
+ printf("%s\n", cp);
+ cpu_Debugger();
+#else
+#ifdef PANICBUTTON
+ panic(cp);
+#else
+ printf("%s ignored\n", cp);
+#endif /* PANICBUTTON */
+#endif /* DDB */
+}
+
+/*
+ * cpu_exec_aout_makecmds():
+ * cpu-dependent a.out format hook for execve().
+ *
+ * Determine of the given exec package refers to something which we
+ * understand and, if so, set up the vmcmds for it.
+ */
+int
+cpu_exec_aout_makecmds(p, epp)
+ struct proc *p;
+ struct exec_package *epp;
+{
+ int error = ENOEXEC;
+#ifdef COMPAT_SUNOS
+ extern sunos_exec_aout_makecmds
+ __P((struct proc *, struct exec_package *));
+ if ((error = sunos_exec_aout_makecmds(p, epp)) == 0)
+ return 0;
+#endif
+ return error;
+}
+
+/*
+ * Return the best possible estimate of the time in the timeval
+ * to which tvp points. Unfortunately, we can't read the hardware registers.
+ * We guarantee that the time will be greater than the value obtained by a
+ * previous call.
+ */
+void
+microtime(tvp)
+ register struct timeval *tvp;
+{
+ int s = splclock();
+ static struct timeval lasttime;
+
+ *tvp = time;
+#ifdef notdef
+ tvp->tv_usec += clkread();
+ while (tvp->tv_usec > 1000000) {
+ tvp->tv_sec++;
+ tvp->tv_usec -= 1000000;
+ }
+#endif
+ if (tvp->tv_sec == lasttime.tv_sec &&
+ tvp->tv_usec <= lasttime.tv_usec &&
+ (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) {
+ tvp->tv_sec++;
+ tvp->tv_usec -= 1000000;
+ }
+ lasttime = *tvp;
+ splx(s);
+}
+
+#ifndef ROMCONS
+
+struct consdev *cn_tab = &syscons;
+
+#else
+
+/*
+ * romcons is useful until m68k TC register is initialized.
+ */
+int romcngetc __P((dev_t));
+void romcnputc __P((dev_t, int));
+
+struct consdev romcons = {
+ NULL,
+ NULL,
+ romcngetc,
+ romcnputc,
+ nullcnpollc,
+ makedev(7, 0), /* XXX */
+ CN_DEAD,
+};
+struct consdev *cn_tab = &romcons;
+
+extern int romcall __P((int, int));
+
+#define ROMGETC() romcall(6, 0)
+#define ROMPUTC(x) romcall(7, x)
+
+void
+romcnputc(dev, c)
+ dev_t dev;
+ int c;
+{
+ ROMPUTC(c);
+}
+
+int
+romcngetc(dev)
+ dev_t dev;
+{
+ int c;
+
+ do {
+ c = ROMGETC();
+ } while (c == -1);
+ return c;
+}
+#endif
diff --git a/sys/arch/luna68k/luna68k/mainbus.c b/sys/arch/luna68k/luna68k/mainbus.c
new file mode 100644
index 00000000000..940d476ae3a
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/mainbus.c
@@ -0,0 +1,109 @@
+/* $NetBSD: mainbus.c,v 1.1 2000/01/05 08:49:04 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.1 2000/01/05 08:49:04 nisimura Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/autoconf.h>
+
+extern int machtype;
+
+static struct mainbus_attach_args devs[] = {
+ { "clock", 0x45000000, -1 }, /* Mostek/Dallas TimeKeeper */
+ { "le", 0xf1000000, 3 }, /* Am7990 */
+ { "sio", 0x51000000, 6 }, /* uPD7201A */
+ { "fb", 0xc1100000, -1 }, /* BrookTree RAMDAC */
+#if 0
+ { "spc", 0xe1000000, 2 }, /* MB89352 */
+ { "spc", 0xe1000040, 2 }, /* ditto */
+#endif
+};
+
+static void mainbus_attach __P((struct device *, struct device *, void *));
+static int mainbus_match __P((struct device *, struct cfdata *, void *));
+static int mainbus_print __P((void *, const char *));
+
+const struct cfattach mainbus_ca = {
+ sizeof(struct device), mainbus_match, mainbus_attach
+};
+
+static int
+mainbus_match(parent, cf, args)
+ struct device *parent;
+ struct cfdata *cf;
+ void *args;
+{
+ static int mainbus_matched;
+
+ if (mainbus_matched)
+ return (0);
+
+ return ((mainbus_matched = 1));
+}
+
+static void
+mainbus_attach(parent, self, args)
+ struct device *parent, *self;
+ void *args;
+{
+ int i;
+
+ if (machtype == LUNA_II)
+ devs[1].ma_addr = 0xf0000000;
+ printf("\n");
+ for (i = 0; i < sizeof(devs)/sizeof(devs[0]); i++)
+ config_found(self, (void *)&devs[i], mainbus_print);
+}
+
+static int
+mainbus_print(aux, pnp)
+ void *aux;
+ const char *pnp;
+{
+ struct mainbus_attach_args *ma = aux;
+
+ if (pnp)
+ printf("%s at %s", ma->ma_name, pnp);
+
+ return (UNCONF);
+}
diff --git a/sys/arch/luna68k/luna68k/mem.c b/sys/arch/luna68k/luna68k/mem.c
new file mode 100644
index 00000000000..9c96be25e37
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/mem.c
@@ -0,0 +1,232 @@
+/* $NetBSD: mem.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $ */
+/* $NetBSD: mem.c,v 1.1 2000/01/05 08:49:03 nisimura 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
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: mem.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $");
+
+/*
+ * 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 <sys/proc.h>
+
+#include <machine/cpu.h>
+
+#include <vm/vm.h>
+
+#include <uvm/uvm_extern.h>
+
+#define mmread mmrw
+#define mmwrite mmrw
+cdev_decl(mm);
+
+extern u_int lowram;
+static caddr_t devzeropage;
+
+/*ARGSUSED*/
+int
+mmopen(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+mmclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+mmrw(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+{
+ vaddr_t o, v;
+ int c;
+ struct iovec *iov;
+ int error = 0;
+ static int physlock;
+ vm_prot_t prot;
+
+ 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:
+ v = uio->uio_offset;
+#ifndef DEBUG
+ /* allow reads only in RAM (except for DEBUG) */
+ if (v >= 0xFFFFFFFC || v < lowram) {
+ error = EFAULT;
+ goto unlock;
+ }
+#endif
+ prot = uio->uio_rw == UIO_READ ? VM_PROT_READ :
+ VM_PROT_WRITE;
+ pmap_enter(pmap_kernel(), (vaddr_t)vmmap,
+ trunc_page(v), prot, prot|PMAP_WIRED);
+ 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(), (vaddr_t)vmmap,
+ (vaddr_t)vmmap + NBPG);
+ continue;
+
+/* minor device 1 is kernel memory */
+ case 1:
+ v = uio->uio_offset;
+ c = min(iov->iov_len, MAXPHYS);
+ if (!uvm_kernacc((caddr_t)v, c,
+ uio->uio_rw == UIO_READ ? B_READ : B_WRITE))
+ return (EFAULT);
+ 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);
+
+/* 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;
+ }
+ /*
+ * On the first call, allocate and zero a page
+ * of memory for use with /dev/zero.
+ */
+ if (devzeropage == NULL) {
+ devzeropage = (caddr_t)
+ malloc(NBPG, M_TEMP, M_WAITOK);
+ bzero(devzeropage, NBPG);
+ }
+ c = min(iov->iov_len, NBPG);
+ error = uiomove(devzeropage, c, uio);
+ continue;
+
+ default:
+ return (ENXIO);
+ }
+ if (error)
+ break;
+ iov->iov_base = (caddr_t)iov->iov_base + c;
+ iov->iov_len -= c;
+ uio->uio_offset += c;
+ uio->uio_resid -= c;
+ }
+ if (minor(dev) == 0) {
+#ifndef DEBUG
+unlock:
+#endif
+ if (physlock > 1)
+ wakeup((caddr_t)&physlock);
+ physlock = 0;
+ }
+ return (error);
+}
+
+int
+mmmmap(dev, off, prot)
+ dev_t dev;
+ int off, prot;
+{
+ /*
+ * /dev/mem is the only one that makes sense through this
+ * interface. For /dev/kmem any physaddr we return here
+ * could be transient and hence incorrect or invalid at
+ * a later time. /dev/null just doesn't make any sense
+ * and /dev/zero is a hack that is handled via the default
+ * pager in mmap().
+ */
+ if (minor(dev) != 0)
+ return (-1);
+ /*
+ * Allow access only in RAM.
+ *
+ * XXX could be extended to allow access to IO space but must
+ * be very careful.
+ */
+ if ((u_int)off < lowram || (u_int)off >= 0xFFFFFFFC)
+ return (-1);
+ return (m68k_btop((u_int)off));
+}
diff --git a/sys/arch/luna68k/luna68k/pmap.c b/sys/arch/luna68k/luna68k/pmap.c
new file mode 100644
index 00000000000..38050c4f18a
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/pmap.c
@@ -0,0 +1,2520 @@
+/* $NetBSD: pmap.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1991, 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.
+ *
+ * @(#)pmap.c 8.6 (Berkeley) 5/27/94
+ */
+
+/*
+ * Physical map management code.
+ *
+ * Supports:
+ * 68030 with on-chip MMU
+ * 68040 with on-chip MMU
+ *
+ * Notes:
+ * Don't even pay lip service to multiprocessor support.
+ *
+ * We assume TLB entries don't have process tags (except for the
+ * supervisor/user distinction) so we only invalidate TLB entries
+ * when changing mappings for the current (or kernel) pmap. This is
+ * technically not true for the 68551 but we flush the TLB on every
+ * context switch, so it effectively winds up that way.
+ *
+ * Bitwise and/or operations are significantly faster than bitfield
+ * references so we use them when accessing STE/PTEs in the pmap_pte_*
+ * macros. Note also that the two are not always equivalent; e.g.:
+ * (*pte & PG_PROT) [4] != pte->pg_prot [1]
+ * and a couple of routines that deal with protection and wiring take
+ * some shortcuts that assume the and/or definitions.
+ *
+ * This implementation will only work for PAGE_SIZE == NBPG
+ * (i.e. 4096 bytes).
+ */
+
+/*
+ * Manages physical address maps.
+ *
+ * In addition to hardware address maps, this
+ * module is called upon to provide software-use-only
+ * maps which may or may not be stored in the same
+ * form as hardware maps. These pseudo-maps are
+ * used to store intermediate results from copy
+ * operations to and from address spaces.
+ *
+ * Since the information managed by this module is
+ * also stored by the logical address mapping module,
+ * this module may throw away valid virtual-to-physical
+ * mappings at almost any time. However, invalidations
+ * of virtual-to-physical mappings must be done as
+ * requested.
+ *
+ * In order to cope with hardware architectures which
+ * make virtual-to-physical map invalidates expensive,
+ * this module may delay invalidate or reduced protection
+ * operations until such time as they are actually
+ * necessary. This module is given full information as
+ * to which processors are currently using which maps,
+ * and to when physical maps must be made correct.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/malloc.h>
+#include <sys/user.h>
+#include <sys/pool.h>
+
+#include <machine/vmparam.h>
+#include <machine/pte.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+
+#include <uvm/uvm.h>
+
+#include <machine/cpu.h>
+#include <m68k/cacheops.h>
+
+
+#ifdef DEBUG
+#define PDB_FOLLOW 0x0001
+#define PDB_INIT 0x0002
+#define PDB_ENTER 0x0004
+#define PDB_REMOVE 0x0008
+#define PDB_CREATE 0x0010
+#define PDB_PTPAGE 0x0020
+#define PDB_CACHE 0x0040
+#define PDB_BITS 0x0080
+#define PDB_COLLECT 0x0100
+#define PDB_PROTECT 0x0200
+#define PDB_SEGTAB 0x0400
+#define PDB_MULTIMAP 0x0800
+#define PDB_PARANOIA 0x2000
+#define PDB_WIRING 0x4000
+#define PDB_PVDUMP 0x8000
+
+int debugmap = 0;
+int pmapdebug = PDB_PARANOIA;
+
+#define PMAP_DPRINTF(l, x) if (pmapdebug & (l)) printf x
+
+#if defined(M68040)
+int dowriteback = 1; /* 68040: enable writeback caching */
+int dokwriteback = 1; /* 68040: enable writeback caching of kernel AS */
+#endif
+#else /* ! DEBUG */
+#define PMAP_DPRINTF(l, x) /* nothing */
+#endif /* DEBUG */
+
+/*
+ * Get STEs and PTEs for user/kernel address space
+ */
+#if defined(M68040)
+#define pmap_ste1(m, v) \
+ (&((m)->pm_stab[(vaddr_t)(v) >> SG4_SHIFT1]))
+/* XXX assumes physically contiguous ST pages (if more than one) */
+#define pmap_ste2(m, v) \
+ (&((m)->pm_stab[(st_entry_t *)(*(u_int *)pmap_ste1(m, v) & SG4_ADDR1) \
+ - (m)->pm_stpa + (((v) & SG4_MASK2) >> SG4_SHIFT2)]))
+#define pmap_ste(m, v) \
+ (&((m)->pm_stab[(vaddr_t)(v) \
+ >> (mmutype == MMU_68040 ? SG4_SHIFT1 : SG_ISHIFT)]))
+#define pmap_ste_v(m, v) \
+ (mmutype == MMU_68040 \
+ ? ((*pmap_ste1(m, v) & SG_V) && \
+ (*pmap_ste2(m, v) & SG_V)) \
+ : (*pmap_ste(m, v) & SG_V))
+#else
+#define pmap_ste(m, v) (&((m)->pm_stab[(vaddr_t)(v) >> SG_ISHIFT]))
+#define pmap_ste_v(m, v) (*pmap_ste(m, v) & SG_V)
+#endif
+
+#define pmap_pte(m, v) (&((m)->pm_ptab[(vaddr_t)(v) >> PG_SHIFT]))
+#define pmap_pte_pa(pte) (*(pte) & PG_FRAME)
+#define pmap_pte_w(pte) (*(pte) & PG_W)
+#define pmap_pte_ci(pte) (*(pte) & PG_CI)
+#define pmap_pte_m(pte) (*(pte) & PG_M)
+#define pmap_pte_u(pte) (*(pte) & PG_U)
+#define pmap_pte_prot(pte) (*(pte) & PG_PROT)
+#define pmap_pte_v(pte) (*(pte) & PG_V)
+
+#define pmap_pte_set_w(pte, v) \
+ if (v) *(pte) |= PG_W; else *(pte) &= ~PG_W
+#define pmap_pte_set_prot(pte, v) \
+ if (v) *(pte) |= PG_PROT; else *(pte) &= ~PG_PROT
+#define pmap_pte_w_chg(pte, nw) ((nw) ^ pmap_pte_w(pte))
+#define pmap_pte_prot_chg(pte, np) ((np) ^ pmap_pte_prot(pte))
+
+/*
+ * Given a map and a machine independent protection code,
+ * convert to an m68k protection code.
+ */
+#define pte_prot(m, p) (protection_codes[p])
+int protection_codes[8];
+
+/*
+ * Kernel page table page management.
+ */
+struct kpt_page {
+ struct kpt_page *kpt_next; /* link on either used or free list */
+ vaddr_t kpt_va; /* always valid kernel VA */
+ paddr_t kpt_pa; /* PA of this page (for speed) */
+};
+struct kpt_page *kpt_free_list, *kpt_used_list;
+struct kpt_page *kpt_pages;
+
+/*
+ * Kernel segment/page table and page table map.
+ * The page table map gives us a level of indirection we need to dynamically
+ * expand the page table. It is essentially a copy of the segment table
+ * with PTEs instead of STEs. All are initialized in locore at boot time.
+ * Sysmap will initially contain VM_KERNEL_PT_PAGES pages of PTEs.
+ * Segtabzero is an empty segment table which all processes share til they
+ * reference something.
+ */
+st_entry_t *Sysseg;
+pt_entry_t *Sysmap, *Sysptmap;
+st_entry_t *Segtabzero, *Segtabzeropa;
+vsize_t Sysptsize = VM_KERNEL_PT_PAGES;
+
+struct pmap kernel_pmap_store;
+vm_map_t st_map, pt_map;
+struct vm_map st_map_store, pt_map_store;
+
+paddr_t avail_start; /* PA of first available physical page */
+paddr_t avail_end; /* PA of last available physical page */
+vsize_t mem_size; /* memory size in bytes */
+vaddr_t virtual_avail; /* VA of first avail page (after kernel bss)*/
+vaddr_t virtual_end; /* VA of last avail page (end of kernel AS) */
+int page_cnt; /* number of pages managed by VM system */
+
+boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */
+struct pv_entry *pv_table;
+char *pmap_attributes; /* reference and modify bits */
+TAILQ_HEAD(pv_page_list, pv_page) pv_page_freelist;
+int pv_nfree;
+
+#if defined(M68040)
+int protostfree; /* prototype (default) free ST map */
+#endif
+
+extern caddr_t CADDR1, CADDR2;
+
+pt_entry_t *caddr1_pte; /* PTE for CADDR1 */
+pt_entry_t *caddr2_pte; /* PTE for CADDR2 */
+
+struct pool pmap_pmap_pool; /* memory pool for pmap structures */
+
+struct pv_entry *pmap_alloc_pv __P((void));
+void pmap_free_pv __P((struct pv_entry *));
+void pmap_collect_pv __P((void));
+
+#define PAGE_IS_MANAGED(pa) (pmap_initialized && \
+ vm_physseg_find(atop((pa)), NULL) != -1)
+
+#define pa_to_pvh(pa) \
+({ \
+ int bank_, pg_; \
+ \
+ bank_ = vm_physseg_find(atop((pa)), &pg_); \
+ &vm_physmem[bank_].pmseg.pvent[pg_]; \
+})
+
+#define pa_to_attribute(pa) \
+({ \
+ int bank_, pg_; \
+ \
+ bank_ = vm_physseg_find(atop((pa)), &pg_); \
+ &vm_physmem[bank_].pmseg.attrs[pg_]; \
+})
+
+/*
+ * Internal routines
+ */
+void pmap_remove_mapping __P((pmap_t, vaddr_t, pt_entry_t *, int));
+boolean_t pmap_testbit __P((paddr_t, int));
+void pmap_changebit __P((paddr_t, int, int));
+void pmap_enter_ptpage __P((pmap_t, vaddr_t));
+void pmap_ptpage_addref __P((vaddr_t));
+int pmap_ptpage_delref __P((vaddr_t));
+void pmap_collect1 __P((pmap_t, paddr_t, paddr_t));
+void pmap_pinit __P((pmap_t));
+void pmap_release __P((pmap_t));
+
+#ifdef DEBUG
+void pmap_pvdump __P((paddr_t));
+void pmap_check_wiring __P((char *, vaddr_t));
+#endif
+
+/* pmap_remove_mapping flags */
+#define PRM_TFLUSH 0x01
+#define PRM_CFLUSH 0x02
+#define PRM_KEEPPTPAGE 0x04
+
+/*
+ * pmap_virtual_space: [ INTERFACE ]
+ *
+ * Report the range of available kernel virtual address
+ * space to the VM system during bootstrap.
+ *
+ * This is only an interface function if we do not use
+ * pmap_steal_memory()!
+ *
+ * Note: no locking is necessary in this function.
+ */
+void
+pmap_virtual_space(vstartp, vendp)
+ vaddr_t *vstartp, *vendp;
+{
+
+ *vstartp = virtual_avail;
+ *vendp = virtual_end;
+}
+
+/*
+ * pmap_init: [ INTERFACE ]
+ *
+ * Initialize the pmap module. Called by vm_init(), to initialize any
+ * structures that the pmap system needs to map virtual memory.
+ *
+ * Note: no locking is necessary in this function.
+ */
+void
+pmap_init()
+{
+ vaddr_t addr, addr2;
+ vsize_t s;
+ struct pv_entry *pv;
+ char *attr;
+ int rv;
+ int npages;
+ int bank;
+
+ PMAP_DPRINTF(PDB_FOLLOW, ("pmap_init()\n"));
+
+ /*
+ * Before we do anything else, initialize the PTE pointers
+ * used by pmap_zero_page() and pmap_copy_page().
+ */
+ caddr1_pte = pmap_pte(pmap_kernel(), CADDR1);
+ caddr2_pte = pmap_pte(pmap_kernel(), CADDR2);
+
+ /*
+ * Now that kernel map has been allocated, we can mark as
+ * unavailable regions which we have mapped in pmap_bootstrap().
+ */
+ addr = (vaddr_t) intiobase;
+ if (uvm_map(kernel_map, &addr,
+ intiotop_phys - intiobase_phys,
+ NULL, UVM_UNKNOWN_OFFSET,
+ UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE,
+ UVM_INH_NONE, UVM_ADV_RANDOM,
+ UVM_FLAG_FIXED)) != KERN_SUCCESS)
+ goto bogons;
+ addr = (vaddr_t) Sysmap;
+ if (uvm_map(kernel_map, &addr, MAX_PTSIZE,
+ NULL, UVM_UNKNOWN_OFFSET,
+ UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE,
+ UVM_INH_NONE, UVM_ADV_RANDOM,
+ UVM_FLAG_FIXED)) != KERN_SUCCESS) {
+ /*
+ * If this fails, it is probably because the static
+ * portion of the kernel page table isn't big enough
+ * and we overran the page table map.
+ */
+ bogons:
+ panic("pmap_init: bogons in the VM system!\n");
+ }
+
+ PMAP_DPRINTF(PDB_INIT,
+ ("pmap_init: Sysseg %p, Sysmap %p, Sysptmap %p\n",
+ Sysseg, Sysmap, Sysptmap));
+ PMAP_DPRINTF(PDB_INIT,
+ (" pstart %lx, pend %lx, vstart %lx, vend %lx\n",
+ avail_start, avail_end, virtual_avail, virtual_end));
+
+ /*
+ * Allocate memory for random pmap data structures. Includes the
+ * initial segment table, pv_head_table and pmap_attributes.
+ */
+ for (page_cnt = 0, bank = 0; bank < vm_nphysseg; bank++)
+ page_cnt += vm_physmem[bank].end - vm_physmem[bank].start;
+ s = STSIZE; /* Segtabzero */
+ s += page_cnt * sizeof(struct pv_entry); /* pv table */
+ s += page_cnt * sizeof(char); /* attribute table */
+ s = round_page(s);
+ addr = uvm_km_zalloc(kernel_map, s);
+ if (addr == 0)
+ panic("pmap_init: can't allocate data structures");
+
+ Segtabzero = (st_entry_t *) addr;
+ (void) pmap_extract(pmap_kernel(), addr, (paddr_t *)&Segtabzeropa);
+ addr += STSIZE;
+
+ pv_table = (struct pv_entry *) addr;
+ addr += page_cnt * sizeof(struct pv_entry);
+
+ pmap_attributes = (char *) addr;
+
+ PMAP_DPRINTF(PDB_INIT, ("pmap_init: %lx bytes: page_cnt %x s0 %p(%p) "
+ "tbl %p atr %p\n",
+ s, page_cnt, Segtabzero, Segtabzeropa,
+ pv_table, pmap_attributes));
+
+ /*
+ * Now that the pv and attribute tables have been allocated,
+ * assign them to the memory segments.
+ */
+ pv = pv_table;
+ attr = pmap_attributes;
+ for (bank = 0; bank < vm_nphysseg; bank++) {
+ npages = vm_physmem[bank].end - vm_physmem[bank].start;
+ vm_physmem[bank].pmseg.pvent = pv;
+ vm_physmem[bank].pmseg.attrs = attr;
+ pv += npages;
+ attr += npages;
+ }
+
+ /*
+ * Allocate physical memory for kernel PT pages and their management.
+ * We need 1 PT page per possible task plus some slop.
+ */
+ npages = min(atop(MAX_KPTSIZE), maxproc+16);
+ s = ptoa(npages) + round_page(npages * sizeof(struct kpt_page));
+
+ /*
+ * Verify that space will be allocated in region for which
+ * we already have kernel PT pages.
+ */
+ addr = 0;
+ rv = uvm_map(kernel_map, &addr, s, NULL, UVM_UNKNOWN_OFFSET,
+ UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE,
+ UVM_ADV_RANDOM, UVM_FLAG_NOMERGE));
+ if (rv != KERN_SUCCESS || (addr + s) >= (vaddr_t)Sysmap)
+ panic("pmap_init: kernel PT too small");
+ rv = uvm_unmap(kernel_map, addr, addr + s);
+ if (rv != KERN_SUCCESS)
+ panic("pmap_init: uvm_unmap failed");
+
+ /*
+ * Now allocate the space and link the pages together to
+ * form the KPT free list.
+ */
+ addr = uvm_km_zalloc(kernel_map, s);
+ if (addr == 0)
+ panic("pmap_init: cannot allocate KPT free list");
+ s = ptoa(npages);
+ addr2 = addr + s;
+ kpt_pages = &((struct kpt_page *)addr2)[npages];
+ kpt_free_list = (struct kpt_page *) 0;
+ do {
+ addr2 -= NBPG;
+ (--kpt_pages)->kpt_next = kpt_free_list;
+ kpt_free_list = kpt_pages;
+ kpt_pages->kpt_va = addr2;
+ (void) pmap_extract(pmap_kernel(), addr2,
+ (paddr_t *)&kpt_pages->kpt_pa);
+ } while (addr != addr2);
+
+ PMAP_DPRINTF(PDB_INIT, ("pmap_init: KPT: %ld pages from %lx to %lx\n",
+ atop(s), addr, addr + s));
+
+ /*
+ * Allocate the segment table map and the page table map.
+ */
+ s = maxproc * STSIZE;
+ st_map = uvm_km_suballoc(kernel_map, &addr, &addr2, s, 0,
+ FALSE, &st_map_store);
+
+ addr = PTBASE;
+ if ((PTMAXSIZE / MAX_PTSIZE) < maxproc) {
+ s = PTMAXSIZE;
+ /*
+ * XXX We don't want to hang when we run out of
+ * page tables, so we lower maxproc so that fork()
+ * will fail instead. Note that root could still raise
+ * this value via sysctl(2).
+ */
+ maxproc = (PTMAXSIZE / MAX_PTSIZE);
+ } else
+ s = (maxproc * MAX_PTSIZE);
+ pt_map = uvm_km_suballoc(kernel_map, &addr, &addr2, s, VM_MAP_PAGEABLE,
+ TRUE, &pt_map_store);
+
+#if defined(M68040)
+ if (mmutype == MMU_68040) {
+ protostfree = ~l2tobm(0);
+ for (rv = MAXUL2SIZE; rv < sizeof(protostfree)*NBBY; rv++)
+ protostfree &= ~l2tobm(rv);
+ }
+#endif
+
+ /*
+ * Initialize the pmap pools.
+ */
+ pool_init(&pmap_pmap_pool, sizeof(struct pmap), 0, 0, 0, "pmappl",
+ 0, pool_page_alloc_nointr, pool_page_free_nointr, M_VMPMAP);
+
+ /*
+ * Now it is safe to enable pv_table recording.
+ */
+ pmap_initialized = TRUE;
+}
+
+/*
+ * pmap_alloc_pv:
+ *
+ * Allocate a pv_entry.
+ */
+struct pv_entry *
+pmap_alloc_pv()
+{
+ struct pv_page *pvp;
+ struct pv_entry *pv;
+ int i;
+
+ if (pv_nfree == 0) {
+ pvp = (struct pv_page *)uvm_km_zalloc(kernel_map, NBPG);
+ if (pvp == 0)
+ panic("pmap_alloc_pv: uvm_km_zalloc() failed");
+ pvp->pvp_pgi.pgi_freelist = pv = &pvp->pvp_pv[1];
+ for (i = NPVPPG - 2; i; i--, pv++)
+ pv->pv_next = pv + 1;
+ pv->pv_next = 0;
+ pv_nfree += pvp->pvp_pgi.pgi_nfree = NPVPPG - 1;
+ TAILQ_INSERT_HEAD(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
+ pv = &pvp->pvp_pv[0];
+ } else {
+ --pv_nfree;
+ pvp = pv_page_freelist.tqh_first;
+ if (--pvp->pvp_pgi.pgi_nfree == 0) {
+ TAILQ_REMOVE(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
+ }
+ pv = pvp->pvp_pgi.pgi_freelist;
+#ifdef DIAGNOSTIC
+ if (pv == 0)
+ panic("pmap_alloc_pv: pgi_nfree inconsistent");
+#endif
+ pvp->pvp_pgi.pgi_freelist = pv->pv_next;
+ }
+ return pv;
+}
+
+/*
+ * pmap_free_pv:
+ *
+ * Free a pv_entry.
+ */
+void
+pmap_free_pv(pv)
+ struct pv_entry *pv;
+{
+ struct pv_page *pvp;
+
+ pvp = (struct pv_page *) trunc_page(pv);
+ switch (++pvp->pvp_pgi.pgi_nfree) {
+ case 1:
+ TAILQ_INSERT_TAIL(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
+ default:
+ pv->pv_next = pvp->pvp_pgi.pgi_freelist;
+ pvp->pvp_pgi.pgi_freelist = pv;
+ ++pv_nfree;
+ break;
+ case NPVPPG:
+ pv_nfree -= NPVPPG - 1;
+ TAILQ_REMOVE(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
+ uvm_km_free(kernel_map, (vaddr_t)pvp, NBPG);
+ break;
+ }
+}
+
+/*
+ * pmap_collect_pv:
+ *
+ * Perform compaction on the PV list, called via pmap_collect().
+ */
+void
+pmap_collect_pv()
+{
+ struct pv_page_list pv_page_collectlist;
+ struct pv_page *pvp, *npvp;
+ struct pv_entry *ph, *ppv, *pv, *npv;
+ int s;
+
+ TAILQ_INIT(&pv_page_collectlist);
+
+ for (pvp = pv_page_freelist.tqh_first; pvp; pvp = npvp) {
+ if (pv_nfree < NPVPPG)
+ break;
+ npvp = pvp->pvp_pgi.pgi_list.tqe_next;
+ if (pvp->pvp_pgi.pgi_nfree > NPVPPG / 3) {
+ TAILQ_REMOVE(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
+ TAILQ_INSERT_TAIL(&pv_page_collectlist, pvp,
+ pvp_pgi.pgi_list);
+ pv_nfree -= NPVPPG;
+ pvp->pvp_pgi.pgi_nfree = -1;
+ }
+ }
+
+ if (pv_page_collectlist.tqh_first == 0)
+ return;
+
+ for (ph = &pv_table[page_cnt - 1]; ph >= &pv_table[0]; ph--) {
+ if (ph->pv_pmap == 0)
+ continue;
+ s = splimp();
+ for (ppv = ph; (pv = ppv->pv_next) != 0; ) {
+ pvp = (struct pv_page *) trunc_page(pv);
+ if (pvp->pvp_pgi.pgi_nfree == -1) {
+ pvp = pv_page_freelist.tqh_first;
+ if (--pvp->pvp_pgi.pgi_nfree == 0) {
+ TAILQ_REMOVE(&pv_page_freelist, pvp,
+ pvp_pgi.pgi_list);
+ }
+ npv = pvp->pvp_pgi.pgi_freelist;
+#ifdef DIAGNOSTIC
+ if (npv == 0)
+ panic("pmap_collect_pv: pgi_nfree inconsistent");
+#endif
+ pvp->pvp_pgi.pgi_freelist = npv->pv_next;
+ *npv = *pv;
+ ppv->pv_next = npv;
+ ppv = npv;
+ } else
+ ppv = pv;
+ }
+ splx(s);
+ }
+
+ for (pvp = pv_page_collectlist.tqh_first; pvp; pvp = npvp) {
+ npvp = pvp->pvp_pgi.pgi_list.tqe_next;
+ uvm_km_free(kernel_map, (vaddr_t)pvp, NBPG);
+ }
+}
+
+/*
+ * pmap_map:
+ *
+ * Used to map a range of physical addresses into kernel
+ * virtual address space.
+ *
+ * For now, VM is already on, we only need to map the
+ * specified memory.
+ *
+ * Note: THIS FUNCTION IS DEPRECATED, AND SHOULD BE REMOVED!
+ */
+vaddr_t
+pmap_map(va, spa, epa, prot)
+ vaddr_t va;
+ paddr_t spa, epa;
+ int prot;
+{
+
+ PMAP_DPRINTF(PDB_FOLLOW,
+ ("pmap_map(%lx, %lx, %lx, %x)\n", va, spa, epa, prot));
+
+ while (spa < epa) {
+ pmap_enter(pmap_kernel(), va, spa, prot, 0);
+ va += NBPG;
+ spa += NBPG;
+ }
+ return (va);
+}
+
+/*
+ * pmap_create: [ INTERFACE ]
+ *
+ * Create and return a physical map.
+ *
+ * Note: no locking is necessary in this function.
+ */
+pmap_t
+pmap_create()
+{
+ pmap_t pmap;
+
+ PMAP_DPRINTF(PDB_FOLLOW|PDB_CREATE,
+ ("pmap_create\n"));
+
+ pmap = pool_get(&pmap_pmap_pool, PR_WAITOK);
+ bzero(pmap, sizeof(*pmap));
+ pmap_pinit(pmap);
+ return (pmap);
+}
+
+/*
+ * pmap_pinit:
+ *
+ * Initialize a preallocated and zeroed pmap structure.
+ *
+ * Note: THIS FUNCTION SHOULD BE MOVED INTO pmap_create()!
+ */
+void
+pmap_pinit(pmap)
+ struct pmap *pmap;
+{
+
+ PMAP_DPRINTF(PDB_FOLLOW|PDB_CREATE,
+ ("pmap_pinit(%p)\n", pmap));
+
+ /*
+ * No need to allocate page table space yet but we do need a
+ * valid segment table. Initially, we point everyone at the
+ * "null" segment table. On the first pmap_enter, a real
+ * segment table will be allocated.
+ */
+ pmap->pm_stab = Segtabzero;
+ pmap->pm_stpa = Segtabzeropa;
+#if defined(M68040)
+ if (mmutype == MMU_68040)
+ pmap->pm_stfree = protostfree;
+#endif
+ pmap->pm_count = 1;
+ simple_lock_init(&pmap->pm_lock);
+}
+
+/*
+ * pmap_destroy: [ INTERFACE ]
+ *
+ * Drop the reference count on the specified pmap, releasing
+ * all resources if the reference count drops to zero.
+ */
+void
+pmap_destroy(pmap)
+ pmap_t pmap;
+{
+ int count;
+
+ if (pmap == NULL)
+ return;
+
+ PMAP_DPRINTF(PDB_FOLLOW, ("pmap_destroy(%p)\n", pmap));
+
+ simple_lock(&pmap->pm_lock);
+ count = --pmap->pm_count;
+ simple_unlock(&pmap->pm_lock);
+ if (count == 0) {
+ pmap_release(pmap);
+ pool_put(&pmap_pmap_pool, pmap);
+ }
+}
+
+/*
+ * pmap_release:
+ *
+ * Relese the resources held by a pmap.
+ *
+ * Note: THIS FUNCTION SHOULD BE MOVED INTO pmap_destroy().
+ */
+void
+pmap_release(pmap)
+ struct pmap *pmap;
+{
+
+ PMAP_DPRINTF(PDB_FOLLOW, ("pmap_release(%p)\n", pmap));
+
+#ifdef notdef /* DIAGNOSTIC */
+ /* count would be 0 from pmap_destroy... */
+ simple_lock(&pmap->pm_lock);
+ if (pmap->pm_count != 1)
+ panic("pmap_release count");
+#endif
+
+ if (pmap->pm_ptab)
+ uvm_km_free_wakeup(pt_map, (vaddr_t)pmap->pm_ptab,
+ MAX_PTSIZE);
+ if (pmap->pm_stab != Segtabzero)
+ uvm_km_free_wakeup(st_map, (vaddr_t)pmap->pm_stab,
+ STSIZE);
+}
+
+/*
+ * pmap_reference: [ INTERFACE ]
+ *
+ * Add a reference to the specified pmap.
+ */
+void
+pmap_reference(pmap)
+ pmap_t pmap;
+{
+
+ if (pmap == NULL)
+ return;
+
+ PMAP_DPRINTF(PDB_FOLLOW, ("pmap_reference(%p)\n", pmap));
+
+ simple_lock(&pmap->pm_lock);
+ pmap->pm_count++;
+ simple_unlock(&pmap->pm_lock);
+}
+
+/*
+ * pmap_activate: [ INTERFACE ]
+ *
+ * Activate the pmap used by the specified process. This includes
+ * reloading the MMU context if the current process, and marking
+ * the pmap in use by the processor.
+ *
+ * Note: we may only use spin locks here, since we are called
+ * by a critical section in cpu_switch()!
+ */
+void
+pmap_activate(p)
+ struct proc *p;
+{
+ pmap_t pmap = p->p_vmspace->vm_map.pmap;
+
+ PMAP_DPRINTF(PDB_FOLLOW|PDB_SEGTAB,
+ ("pmap_activate(%p)\n", p));
+
+ PMAP_ACTIVATE(pmap, p == curproc);
+}
+
+/*
+ * pmap_deactivate: [ INTERFACE ]
+ *
+ * Mark that the pmap used by the specified process is no longer
+ * in use by the processor.
+ *
+ * The comment above pmap_activate() wrt. locking applies here,
+ * as well.
+ */
+void
+pmap_deactivate(p)
+ struct proc *p;
+{
+
+ /* No action necessary in this pmap implementation. */
+}
+
+/*
+ * pmap_remove: [ INTERFACE ]
+ *
+ * Remove the given range of addresses from the specified map.
+ *
+ * It is assumed that the start and end are properly
+ * rounded to the page size.
+ */
+void
+pmap_remove(pmap, sva, eva)
+ pmap_t pmap;
+ vaddr_t sva, eva;
+{
+ vaddr_t nssva;
+ pt_entry_t *pte;
+ int flags;
+
+ PMAP_DPRINTF(PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT,
+ ("pmap_remove(%p, %lx, %lx)\n", pmap, sva, eva));
+
+ if (pmap == NULL)
+ return;
+
+ flags = active_pmap(pmap) ? PRM_TFLUSH : 0;
+ while (sva < eva) {
+ nssva = m68k_trunc_seg(sva) + NBSEG;
+ if (nssva == 0 || nssva > eva)
+ nssva = eva;
+ /*
+ * If VA belongs to an unallocated segment,
+ * skip to the next segment boundary.
+ */
+ if (!pmap_ste_v(pmap, sva)) {
+ sva = nssva;
+ continue;
+ }
+ /*
+ * Invalidate every valid mapping within this segment.
+ */
+ pte = pmap_pte(pmap, sva);
+ while (sva < nssva) {
+ if (pmap_pte_v(pte)) {
+ pmap_remove_mapping(pmap, sva, pte, flags);
+ }
+ pte++;
+ sva += NBPG;
+ }
+ }
+}
+
+/*
+ * pmap_page_protect: [ INTERFACE ]
+ *
+ * Lower the permission for all mappings to a given page to
+ * the permissions specified.
+ */
+void
+pmap_page_protect(pg, prot)
+ struct vm_page *pg;
+ vm_prot_t prot;
+{
+ paddr_t pa = VM_PAGE_TO_PHYS(pg);
+ struct pv_entry *pv;
+ int s;
+
+#ifdef DEBUG
+ if ((pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) ||
+ (prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE)))
+ printf("pmap_page_protect(%lx, %x)\n", pa, prot);
+#endif
+ if (PAGE_IS_MANAGED(pa) == 0)
+ return;
+
+ switch (prot) {
+ case VM_PROT_READ|VM_PROT_WRITE:
+ case VM_PROT_ALL:
+ return;
+ /* copy_on_write */
+ case VM_PROT_READ:
+ case VM_PROT_READ|VM_PROT_EXECUTE:
+ pmap_changebit(pa, PG_RO, ~0);
+ return;
+ /* remove_all */
+ default:
+ break;
+ }
+ pv = pa_to_pvh(pa);
+ s = splimp();
+ while (pv->pv_pmap != NULL) {
+ pt_entry_t *pte;
+
+ pte = pmap_pte(pv->pv_pmap, pv->pv_va);
+#ifdef DEBUG
+ if (!pmap_ste_v(pv->pv_pmap, pv->pv_va) ||
+ pmap_pte_pa(pte) != pa)
+ panic("pmap_page_protect: bad mapping");
+#endif
+ if (!pmap_pte_w(pte))
+ pmap_remove_mapping(pv->pv_pmap, pv->pv_va,
+ pte, PRM_TFLUSH|PRM_CFLUSH);
+ else {
+ pv = pv->pv_next;
+#ifdef DEBUG
+ if (pmapdebug & PDB_PARANOIA)
+ printf("%s wired mapping for %lx not removed\n",
+ "pmap_page_protect:", pa);
+#endif
+ if (pv == NULL)
+ break;
+ }
+ }
+ splx(s);
+}
+
+/*
+ * pmap_protect: [ INTERFACE ]
+ *
+ * Set the physical protectoin on the specified range of this map
+ * as requested.
+ */
+void
+pmap_protect(pmap, sva, eva, prot)
+ pmap_t pmap;
+ vaddr_t sva, eva;
+ vm_prot_t prot;
+{
+ vaddr_t nssva;
+ pt_entry_t *pte;
+ boolean_t firstpage, needtflush;
+ int isro;
+
+ PMAP_DPRINTF(PDB_FOLLOW|PDB_PROTECT,
+ ("pmap_protect(%p, %lx, %lx, %x)\n",
+ pmap, sva, eva, prot));
+
+ if (pmap == NULL)
+ return;
+
+#ifdef PMAPSTATS
+ protect_stats.calls++;
+#endif
+ if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
+ pmap_remove(pmap, sva, eva);
+ return;
+ }
+ if (prot & VM_PROT_WRITE)
+ return;
+
+ isro = pte_prot(pmap, prot);
+ needtflush = active_pmap(pmap);
+ firstpage = TRUE;
+ while (sva < eva) {
+ nssva = m68k_trunc_seg(sva) + NBSEG;
+ if (nssva == 0 || nssva > eva)
+ nssva = eva;
+ /*
+ * If VA belongs to an unallocated segment,
+ * skip to the next segment boundary.
+ */
+ if (!pmap_ste_v(pmap, sva)) {
+ sva = nssva;
+ continue;
+ }
+ /*
+ * Change protection on mapping if it is valid and doesn't
+ * already have the correct protection.
+ */
+ pte = pmap_pte(pmap, sva);
+ while (sva < nssva) {
+ if (pmap_pte_v(pte) && pmap_pte_prot_chg(pte, isro)) {
+#if defined(M68040)
+ /*
+ * Clear caches if making RO (see section
+ * "7.3 Cache Coherency" in the manual).
+ */
+ if (isro && mmutype == MMU_68040) {
+ paddr_t pa = pmap_pte_pa(pte);
+
+ DCFP(pa);
+ ICPP(pa);
+ }
+#endif
+ pmap_pte_set_prot(pte, isro);
+ if (needtflush)
+ TBIS(sva);
+ firstpage = FALSE;
+ }
+ pte++;
+ sva += NBPG;
+ }
+ }
+}
+
+/*
+ * pmap_enter: [ INTERFACE ]
+ *
+ * Insert the given physical page (pa) at
+ * the specified virtual address (va) in the
+ * target physical map with the protection requested.
+ *
+ * If specified, the page will be wired down, meaning
+ * that the related pte cannot be reclaimed.
+ *
+ * Note: This is the only routine which MAY NOT lazy-evaluate
+ * or lose information. Thatis, this routine must actually
+ * insert this page into the given map NOW.
+ */
+int
+pmap_enter(pmap, va, pa, prot, flags)
+ pmap_t pmap;
+ vaddr_t va;
+ paddr_t pa;
+ vm_prot_t prot;
+ int flags;
+{
+ pt_entry_t *pte;
+ int npte;
+ paddr_t opa;
+ boolean_t cacheable = TRUE;
+ boolean_t checkpv = TRUE;
+ boolean_t wired = (flags & PMAP_WIRED) != 0;
+
+ PMAP_DPRINTF(PDB_FOLLOW|PDB_ENTER,
+ ("pmap_enter(%p, %lx, %lx, %x, %x)\n",
+ pmap, va, pa, prot, wired));
+
+ if (pmap == NULL)
+ return (KERN_SUCCESS);
+
+#ifdef DIAGNOSTIC
+ /*
+ * pmap_enter() should never be used for CADDR1 and CADDR2.
+ */
+ if (pmap == pmap_kernel() &&
+ (va == (vaddr_t)CADDR1 || va == (vaddr_t)CADDR2))
+ panic("pmap_enter: used for CADDR1 or CADDR2");
+#endif
+
+ /*
+ * For user mapping, allocate kernel VM resources if necessary.
+ */
+ if (pmap->pm_ptab == NULL)
+ pmap->pm_ptab = (pt_entry_t *)
+ uvm_km_valloc_wait(pt_map, MAX_PTSIZE);
+
+ /*
+ * Segment table entry not valid, we need a new PT page
+ */
+ if (!pmap_ste_v(pmap, va))
+ pmap_enter_ptpage(pmap, va);
+
+ pa = m68k_trunc_page(pa);
+ pte = pmap_pte(pmap, va);
+ opa = pmap_pte_pa(pte);
+
+ PMAP_DPRINTF(PDB_ENTER, ("enter: pte %p, *pte %x\n", pte, *pte));
+
+ /*
+ * Mapping has not changed, must be protection or wiring change.
+ */
+ if (opa == pa) {
+ /*
+ * Wiring change, just update stats.
+ * We don't worry about wiring PT pages as they remain
+ * resident as long as there are valid mappings in them.
+ * Hence, if a user page is wired, the PT page will be also.
+ */
+ if (pmap_pte_w_chg(pte, wired ? PG_W : 0)) {
+ PMAP_DPRINTF(PDB_ENTER,
+ ("enter: wiring change -> %x\n", wired));
+ if (wired)
+ pmap->pm_stats.wired_count++;
+ else
+ pmap->pm_stats.wired_count--;
+ }
+ /*
+ * Retain cache inhibition status
+ */
+ checkpv = FALSE;
+ if (pmap_pte_ci(pte))
+ cacheable = FALSE;
+ goto validate;
+ }
+
+ /*
+ * Mapping has changed, invalidate old range and fall through to
+ * handle validating new mapping.
+ */
+ if (opa) {
+ PMAP_DPRINTF(PDB_ENTER,
+ ("enter: removing old mapping %lx\n", va));
+ pmap_remove_mapping(pmap, va, pte,
+ PRM_TFLUSH|PRM_CFLUSH|PRM_KEEPPTPAGE);
+ }
+
+ /*
+ * If this is a new user mapping, increment the wiring count
+ * on this PT page. PT pages are wired down as long as there
+ * is a valid mapping in the page.
+ */
+ if (pmap != pmap_kernel())
+ pmap_ptpage_addref(trunc_page(pte));
+
+ /*
+ * Enter on the PV list if part of our managed memory
+ * Note that we raise IPL while manipulating pv_table
+ * since pmap_enter can be called at interrupt time.
+ */
+ if (PAGE_IS_MANAGED(pa)) {
+ struct pv_entry *pv, *npv;
+ int s;
+
+ pv = pa_to_pvh(pa);
+ s = splimp();
+
+ PMAP_DPRINTF(PDB_ENTER,
+ ("enter: pv at %p: %lx/%p/%p\n",
+ pv, pv->pv_va, pv->pv_pmap, pv->pv_next));
+ /*
+ * No entries yet, use header as the first entry
+ */
+ if (pv->pv_pmap == NULL) {
+ pv->pv_va = va;
+ pv->pv_pmap = pmap;
+ pv->pv_next = NULL;
+ pv->pv_ptste = NULL;
+ pv->pv_ptpmap = NULL;
+ pv->pv_flags = 0;
+ }
+ /*
+ * There is at least one other VA mapping this page.
+ * Place this entry after the header.
+ */
+ else {
+#ifdef DEBUG
+ for (npv = pv; npv; npv = npv->pv_next)
+ if (pmap == npv->pv_pmap && va == npv->pv_va)
+ panic("pmap_enter: already in pv_tab");
+#endif
+ npv = pmap_alloc_pv();
+ npv->pv_va = va;
+ npv->pv_pmap = pmap;
+ npv->pv_next = pv->pv_next;
+ npv->pv_ptste = NULL;
+ npv->pv_ptpmap = NULL;
+ npv->pv_flags = 0;
+ pv->pv_next = npv;
+ }
+
+ /*
+ * Speed pmap_is_referenced() or pmap_is_modified() based
+ * on the hint provided in access_type.
+ */
+#ifdef DIAGNOSTIC
+ if ((flags & VM_PROT_ALL) & ~prot)
+ panic("pmap_enter: access_type exceeds prot");
+#endif
+ if (flags & VM_PROT_WRITE)
+ *pa_to_attribute(pa) |= (PG_U|PG_M);
+ else if (flags & VM_PROT_ALL)
+ *pa_to_attribute(pa) |= PG_U;
+
+ splx(s);
+ }
+ /*
+ * Assumption: if it is not part of our managed memory
+ * then it must be device memory which may be volitile.
+ */
+ else if (pmap_initialized) {
+ checkpv = cacheable = FALSE;
+ }
+
+ /*
+ * Increment counters
+ */
+ pmap->pm_stats.resident_count++;
+ if (wired)
+ pmap->pm_stats.wired_count++;
+
+validate:
+ /*
+ * Build the new PTE.
+ */
+ npte = pa | pte_prot(pmap, prot) | (*pte & (PG_M|PG_U)) | PG_V;
+ if (wired)
+ npte |= PG_W;
+ if (!checkpv && !cacheable)
+ npte |= PG_CI;
+#if defined(M68040)
+ if (mmutype == MMU_68040 && (npte & (PG_PROT|PG_CI)) == PG_RW)
+#ifdef DEBUG
+ if (dowriteback && (dokwriteback || pmap != pmap_kernel()))
+#endif
+ npte |= PG_CCB;
+#endif
+
+ PMAP_DPRINTF(PDB_ENTER, ("enter: new pte value %x\n", npte));
+
+ /*
+ * Remember if this was a wiring-only change.
+ * If so, we need not flush the TLB and caches.
+ */
+ wired = ((*pte ^ npte) == PG_W);
+#if defined(M68040)
+ if (mmutype == MMU_68040 && !wired) {
+ DCFP(pa);
+ ICPP(pa);
+ }
+#endif
+ *pte = npte;
+ if (!wired && active_pmap(pmap))
+ TBIS(va);
+#ifdef DEBUG
+ if ((pmapdebug & PDB_WIRING) && pmap != pmap_kernel())
+ pmap_check_wiring("enter", trunc_page(pte));
+#endif
+
+ return (KERN_SUCCESS);
+}
+
+void
+pmap_kenter_pa(va, pa, prot)
+ vaddr_t va;
+ paddr_t pa;
+ vm_prot_t prot;
+{
+ pmap_enter(pmap_kernel(), va, pa, prot, PMAP_WIRED);
+}
+
+void
+pmap_kenter_pgs(va, pgs, npgs)
+ vaddr_t va;
+ struct vm_page **pgs;
+ int npgs;
+{
+ int i;
+
+ for (i = 0; i < npgs; i++, va += PAGE_SIZE) {
+ pmap_enter(pmap_kernel(), va, VM_PAGE_TO_PHYS(pgs[i]),
+ VM_PROT_READ|VM_PROT_WRITE, PMAP_WIRED);
+ }
+}
+
+void
+pmap_kremove(va, len)
+ vaddr_t va;
+ vsize_t len;
+{
+ for (len >>= PAGE_SHIFT; len > 0; len--, va += PAGE_SIZE) {
+ pmap_remove(pmap_kernel(), va, va + PAGE_SIZE);
+ }
+}
+
+/*
+ * pmap_unwire: [ INTERFACE ]
+ *
+ * Clear the wired attribute for a map/virtual-address pair.
+ *
+ * The mapping must already exist in the pmap.
+ */
+void
+pmap_unwire(pmap, va)
+ pmap_t pmap;
+ vaddr_t va;
+{
+ pt_entry_t *pte;
+
+ PMAP_DPRINTF(PDB_FOLLOW,
+ ("pmap_unwire(%p, %lx)\n", pmap, va));
+
+ if (pmap == NULL)
+ return;
+
+ pte = pmap_pte(pmap, va);
+#ifdef DEBUG
+ /*
+ * Page table page is not allocated.
+ * Should this ever happen? Ignore it for now,
+ * we don't want to force allocation of unnecessary PTE pages.
+ */
+ if (!pmap_ste_v(pmap, va)) {
+ if (pmapdebug & PDB_PARANOIA)
+ printf("pmap_unwire: invalid STE for %lx\n", va);
+ return;
+ }
+ /*
+ * Page not valid. Should this ever happen?
+ * Just continue and change wiring anyway.
+ */
+ if (!pmap_pte_v(pte)) {
+ if (pmapdebug & PDB_PARANOIA)
+ printf("pmap_unwire: invalid PTE for %lx\n", va);
+ }
+#endif
+ /*
+ * If wiring actually changed (always?) clear the wire bit and
+ * update the wire count. Note that wiring is not a hardware
+ * characteristic so there is no need to invalidate the TLB.
+ */
+ if (pmap_pte_w_chg(pte, 0)) {
+ pmap_pte_set_w(pte, FALSE);
+ pmap->pm_stats.wired_count--;
+ }
+#ifdef DIAGNOSTIC
+ else {
+ printf("pmap_unwire: wiring for pmap %p va 0x%lx "
+ "didn't change!\n", pmap, va);
+ }
+#endif
+}
+
+/*
+ * pmap_extract: [ INTERFACE ]
+ *
+ * Extract the physical address associated with the given
+ * pmap/virtual address pair.
+ */
+boolean_t
+pmap_extract(pmap, va, pap)
+ pmap_t pmap;
+ vaddr_t va;
+ paddr_t *pap;
+{
+ boolean_t rv = FALSE;
+ paddr_t pa;
+ u_int pte;
+
+ PMAP_DPRINTF(PDB_FOLLOW,
+ ("pmap_extract(%p, %lx) -> ", pmap, va));
+
+ if (pmap && pmap_ste_v(pmap, va)) {
+ pte = *(u_int *)pmap_pte(pmap, va);
+ if (pte) {
+ pa = (pte & PG_FRAME) | (va & ~PG_FRAME);
+ if (pap != NULL)
+ *pap = pa;
+ rv = TRUE;
+ }
+ }
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW) {
+ if (rv)
+ printf("%lx\n", pa);
+ else
+ printf("failed\n");
+ }
+#endif
+ return (rv);
+}
+
+/*
+ * pmap_copy: [ INTERFACE ]
+ *
+ * Copy the mapping range specified by src_addr/len
+ * from the source map to the range dst_addr/len
+ * in the destination map.
+ *
+ * This routine is only advisory and need not do anything.
+ */
+void
+pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
+ pmap_t dst_pmap;
+ pmap_t src_pmap;
+ vaddr_t dst_addr;
+ vsize_t len;
+ vaddr_t src_addr;
+{
+
+ PMAP_DPRINTF(PDB_FOLLOW,
+ ("pmap_copy(%p, %p, %lx, %lx, %lx)\n",
+ dst_pmap, src_pmap, dst_addr, len, src_addr));
+}
+
+/*
+ * pmap_update:
+ *
+ * Require that all active physical maps contain no
+ * incorrect entires NOW, by processing any deferred
+ * pmap operations.
+ */
+void
+pmap_update()
+{
+
+ PMAP_DPRINTF(PDB_FOLLOW, ("pmap_update()\n"));
+
+#if (defined(M68020)||defined(M68040)||defined(M68060))
+ TBIA();
+#endif
+}
+
+/*
+ * pmap_collect: [ INTERFACE ]
+ *
+ * Garbage collects the physical map system for pages which are no
+ * longer used. Success need not be guaranteed -- that is, there
+ * may well be pages which are not referenced, but others may be
+ * collected.
+ *
+ * Called by the pageout daemon when pages are scarce.
+ */
+void
+pmap_collect(pmap)
+ pmap_t pmap;
+{
+
+ PMAP_DPRINTF(PDB_FOLLOW, ("pmap_collect(%p)\n", pmap));
+
+ if (pmap == pmap_kernel()) {
+ int bank, s;
+
+ /*
+ * XXX This is very bogus. We should handle kernel PT
+ * XXX pages much differently.
+ */
+
+ s = splimp();
+ for (bank = 0; bank < vm_nphysseg; bank++)
+ pmap_collect1(pmap, ptoa(vm_physmem[bank].start),
+ ptoa(vm_physmem[bank].end));
+ splx(s);
+ } else {
+ /*
+ * This process is about to be swapped out; free all of
+ * the PT pages by removing the physical mappings for its
+ * entire address space. Note: pmap_remove() performs
+ * all necessary locking.
+ */
+ pmap_remove(pmap, VM_MIN_ADDRESS, VM_MAX_ADDRESS);
+ }
+
+#ifdef notyet
+ /* Go compact and garbage-collect the pv_table. */
+ pmap_collect_pv();
+#endif
+}
+
+/*
+ * pmap_collect1():
+ *
+ * Garbage-collect KPT pages. Helper for the above (bogus)
+ * pmap_collect().
+ *
+ * Note: THIS SHOULD GO AWAY, AND BE REPLACED WITH A BETTER
+ * WAY OF HANDLING PT PAGES!
+ */
+void
+pmap_collect1(pmap, startpa, endpa)
+ pmap_t pmap;
+ paddr_t startpa, endpa;
+{
+ paddr_t pa;
+ struct pv_entry *pv;
+ pt_entry_t *pte;
+ paddr_t kpa;
+#ifdef DEBUG
+ st_entry_t *ste;
+ int opmapdebug = 0 /* XXX initialize to quiet gcc -Wall */;
+#endif
+
+ for (pa = startpa; pa < endpa; pa += NBPG) {
+ struct kpt_page *kpt, **pkpt;
+
+ /*
+ * Locate physical pages which are being used as kernel
+ * page table pages.
+ */
+ pv = pa_to_pvh(pa);
+ if (pv->pv_pmap != pmap_kernel() || !(pv->pv_flags & PV_PTPAGE))
+ continue;
+ do {
+ if (pv->pv_ptste && pv->pv_ptpmap == pmap_kernel())
+ break;
+ } while ((pv = pv->pv_next));
+ if (pv == NULL)
+ continue;
+#ifdef DEBUG
+ if (pv->pv_va < (vaddr_t)Sysmap ||
+ pv->pv_va >= (vaddr_t)Sysmap + MAX_PTSIZE)
+ printf("collect: kernel PT VA out of range\n");
+ else
+ goto ok;
+ pmap_pvdump(pa);
+ continue;
+ok:
+#endif
+ pte = (pt_entry_t *)(pv->pv_va + NBPG);
+ while (--pte >= (pt_entry_t *)pv->pv_va && *pte == PG_NV)
+ ;
+ if (pte >= (pt_entry_t *)pv->pv_va)
+ continue;
+
+#ifdef DEBUG
+ if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT)) {
+ printf("collect: freeing KPT page at %lx (ste %x@%p)\n",
+ pv->pv_va, *pv->pv_ptste, pv->pv_ptste);
+ opmapdebug = pmapdebug;
+ pmapdebug |= PDB_PTPAGE;
+ }
+
+ ste = pv->pv_ptste;
+#endif
+ /*
+ * If all entries were invalid we can remove the page.
+ * We call pmap_remove_entry to take care of invalidating
+ * ST and Sysptmap entries.
+ */
+ (void) pmap_extract(pmap, pv->pv_va, (paddr_t *)&kpa);
+ pmap_remove_mapping(pmap, pv->pv_va, PT_ENTRY_NULL,
+ PRM_TFLUSH|PRM_CFLUSH);
+ /*
+ * Use the physical address to locate the original
+ * (kmem_alloc assigned) address for the page and put
+ * that page back on the free list.
+ */
+ for (pkpt = &kpt_used_list, kpt = *pkpt;
+ kpt != (struct kpt_page *)0;
+ pkpt = &kpt->kpt_next, kpt = *pkpt)
+ if (kpt->kpt_pa == kpa)
+ break;
+#ifdef DEBUG
+ if (kpt == (struct kpt_page *)0)
+ panic("pmap_collect: lost a KPT page");
+ if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT))
+ printf("collect: %lx (%lx) to free list\n",
+ kpt->kpt_va, kpa);
+#endif
+ *pkpt = kpt->kpt_next;
+ kpt->kpt_next = kpt_free_list;
+ kpt_free_list = kpt;
+#ifdef DEBUG
+ if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT))
+ pmapdebug = opmapdebug;
+
+ if (*ste != SG_NV)
+ printf("collect: kernel STE at %p still valid (%x)\n",
+ ste, *ste);
+ ste = &Sysptmap[ste - pmap_ste(pmap_kernel(), 0)];
+ if (*ste != SG_NV)
+ printf("collect: kernel PTmap at %p still valid (%x)\n",
+ ste, *ste);
+#endif
+ }
+}
+
+/*
+ * pmap_zero_page: [ INTERFACE ]
+ *
+ * Zero the specified (machine independent) page by mapping the page
+ * into virtual memory and using bzero to clear its contents, one
+ * machine dependent page at a time.
+ *
+ * Note: WE DO NOT CURRENTLY LOCK THE TEMPORARY ADDRESSES!
+ * (Actually, we go to splimp(), and since we don't
+ * support multiple processors, this is sufficient.)
+ */
+void
+pmap_zero_page(phys)
+ paddr_t phys;
+{
+ int s, npte;
+
+ PMAP_DPRINTF(PDB_FOLLOW, ("pmap_zero_page(%lx)\n", phys));
+
+ npte = phys | PG_V;
+
+#if defined(M68040) || defined(M68060)
+ if (mmutype == MMU_68040) {
+ /*
+ * Set copyback caching on the page; this is required
+ * for cache consistency (since regular mappings are
+ * copyback as well).
+ */
+ npte |= PG_CCB;
+ }
+#endif
+
+ s = splimp();
+
+ *caddr1_pte = npte;
+ TBIS((vaddr_t)CADDR1);
+
+ zeropage(CADDR1);
+
+#ifdef DEBUG
+ *caddr1_pte = PG_NV;
+ TBIS((vaddr_t)CADDR1);
+#endif
+
+ splx(s);
+}
+
+/*
+ * pmap_copy_page: [ INTERFACE ]
+ *
+ * Copy the specified (machine independent) page by mapping the page
+ * into virtual memory and using bcopy to copy the page, one machine
+ * dependent page at a time.
+ *
+ * Note: WE DO NOT CURRENTLY LOCK THE TEMPORARY ADDRESSES!
+ * (Actually, we go to splimp(), and since we don't
+ * support multiple processors, this is sufficient.)
+ */
+void
+pmap_copy_page(src, dst)
+ paddr_t src, dst;
+{
+ int s, npte1, npte2;
+
+ PMAP_DPRINTF(PDB_FOLLOW, ("pmap_copy_page(%lx, %lx)\n", src, dst));
+
+ npte1 = src | PG_RO | PG_V;
+ npte2 = dst | PG_V;
+
+#if defined(M68040) || defined(M68060)
+ if (mmutype == MMU_68040) {
+ /*
+ * Set copyback caching on the pages; this is required
+ * for cache consistency (since regular mappings are
+ * copyback as well).
+ */
+ npte1 |= PG_CCB;
+ npte2 |= PG_CCB;
+ }
+#endif
+
+ s = splimp();
+
+ *caddr1_pte = npte1;
+ TBIS((vaddr_t)CADDR1);
+
+ *caddr2_pte = npte2;
+ TBIS((vaddr_t)CADDR2);
+
+ copypage(CADDR1, CADDR2);
+
+#ifdef DEBUG
+ *caddr1_pte = PG_NV;
+ TBIS((vaddr_t)CADDR1);
+
+ *caddr2_pte = PG_NV;
+ TBIS((vaddr_t)CADDR2);
+#endif
+
+ splx(s);
+}
+
+/*
+ * pmap_clear_modify: [ INTERFACE ]
+ *
+ * Clear the modify bits on the specified physical page.
+ */
+boolean_t
+pmap_clear_modify(pg)
+ struct vm_page *pg;
+{
+ paddr_t pa = VM_PAGE_TO_PHYS(pg);
+ boolean_t rv;
+
+ PMAP_DPRINTF(PDB_FOLLOW, ("pmap_clear_modify(%lx)\n", pa));
+
+ rv = pmap_testbit(pa, PG_M);
+ pmap_changebit(pa, 0, ~PG_M);
+ return rv;
+}
+
+/*
+ * pmap_clear_reference: [ INTERFACE ]
+ *
+ * Clear the reference bit on the specified physical page.
+ */
+boolean_t
+pmap_clear_reference(pg)
+ struct vm_page *pg;
+{
+ paddr_t pa = VM_PAGE_TO_PHYS(pg);
+ boolean_t rv;
+
+ PMAP_DPRINTF(PDB_FOLLOW, ("pmap_clear_reference(%lx)\n", pa));
+
+ rv = pmap_testbit(pa, PG_U);
+ pmap_changebit(pa, 0, ~PG_U);
+ return rv;
+}
+
+/*
+ * pmap_is_referenced: [ INTERFACE ]
+ *
+ * Return whether or not the specified physical page is referenced
+ * by any physical maps.
+ */
+boolean_t
+pmap_is_referenced(pg)
+ struct vm_page *pg;
+{
+ paddr_t pa = VM_PAGE_TO_PHYS(pg);
+
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW) {
+ boolean_t rv = pmap_testbit(pa, PG_U);
+ printf("pmap_is_referenced(%lx) -> %c\n", pa, "FT"[rv]);
+ return(rv);
+ }
+#endif
+ return(pmap_testbit(pa, PG_U));
+}
+
+/*
+ * pmap_is_modified: [ INTERFACE ]
+ *
+ * Return whether or not the specified physical page is modified
+ * by any physical maps.
+ */
+boolean_t
+pmap_is_modified(pg)
+ struct vm_page *pg;
+{
+ paddr_t pa = VM_PAGE_TO_PHYS(pg);
+
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW) {
+ boolean_t rv = pmap_testbit(pa, PG_M);
+ printf("pmap_is_modified(%lx) -> %c\n", pa, "FT"[rv]);
+ return(rv);
+ }
+#endif
+ return(pmap_testbit(pa, PG_M));
+}
+
+/*
+ * pmap_phys_address: [ INTERFACE ]
+ *
+ * Return the physical address corresponding to the specified
+ * cookie. Used by the device pager to decode a device driver's
+ * mmap entry point return value.
+ *
+ * Note: no locking is necessary in this function.
+ */
+paddr_t
+pmap_phys_address(ppn)
+ int ppn;
+{
+ return(m68k_ptob(ppn));
+}
+
+/*
+ * Miscellaneous support routines follow
+ */
+
+/*
+ * pmap_remove_mapping:
+ *
+ * Invalidate a single page denoted by pmap/va.
+ *
+ * If (pte != NULL), it is the already computed PTE for the page.
+ *
+ * If (flags & PRM_TFLUSH), we must invalidate any TLB information.
+ *
+ * If (flags & PRM_CFLUSH), we must flush/invalidate any cache
+ * information.
+ *
+ * If (flags & PRM_KEEPPTPAGE), we don't free the page table page
+ * if the reference drops to zero.
+ */
+/* static */
+void
+pmap_remove_mapping(pmap, va, pte, flags)
+ pmap_t pmap;
+ vaddr_t va;
+ pt_entry_t *pte;
+ int flags;
+{
+ paddr_t pa;
+ struct pv_entry *pv, *npv;
+ pmap_t ptpmap;
+ st_entry_t *ste;
+ int s, bits;
+#ifdef DEBUG
+ pt_entry_t opte;
+#endif
+
+ PMAP_DPRINTF(PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT,
+ ("pmap_remove_mapping(%p, %lx, %p, %x)\n",
+ pmap, va, pte, flags));
+
+ /*
+ * PTE not provided, compute it from pmap and va.
+ */
+ if (pte == PT_ENTRY_NULL) {
+ pte = pmap_pte(pmap, va);
+ if (*pte == PG_NV)
+ return;
+ }
+
+ pa = pmap_pte_pa(pte);
+#ifdef DEBUG
+ opte = *pte;
+#endif
+ /*
+ * Update statistics
+ */
+ if (pmap_pte_w(pte))
+ pmap->pm_stats.wired_count--;
+ pmap->pm_stats.resident_count--;
+
+ /*
+ * Invalidate the PTE after saving the reference modify info.
+ */
+ PMAP_DPRINTF(PDB_REMOVE, ("remove: invalidating pte at %p\n", pte));
+ bits = *pte & (PG_U|PG_M);
+ *pte = PG_NV;
+ if ((flags & PRM_TFLUSH) && active_pmap(pmap))
+ TBIS(va);
+ /*
+ * For user mappings decrement the wiring count on
+ * the PT page.
+ */
+ if (pmap != pmap_kernel()) {
+ vaddr_t ptpva = trunc_page(pte);
+ int refs = pmap_ptpage_delref(ptpva);
+#ifdef DEBUG
+ if (pmapdebug & PDB_WIRING)
+ pmap_check_wiring("remove", ptpva);
+#endif
+ /*
+ * If reference count drops to 1, and we're not instructed
+ * to keep it around, free the PT page.
+ *
+ * Note: refcnt == 1 comes from the fact that we allocate
+ * the page with uvm_fault_wire(), which initially wires
+ * the page. The first reference we actually add causes
+ * the refcnt to be 2.
+ */
+ if (refs == 1 && (flags & PRM_KEEPPTPAGE) == 0) {
+ struct pv_entry *pv;
+ paddr_t pa;
+
+ pa = pmap_pte_pa(pmap_pte(pmap_kernel(), ptpva));
+#ifdef DIAGNOSTIC
+ if (PAGE_IS_MANAGED(pa) == 0)
+ panic("pmap_remove_mapping: unmanaged PT page");
+#endif
+ pv = pa_to_pvh(pa);
+#ifdef DIAGNOSTIC
+ if (pv->pv_ptste == NULL)
+ panic("pmap_remove_mapping: ptste == NULL");
+ if (pv->pv_pmap != pmap_kernel() ||
+ pv->pv_va != ptpva ||
+ pv->pv_next != NULL)
+ panic("pmap_remove_mapping: "
+ "bad PT page pmap %p, va 0x%lx, next %p",
+ pv->pv_pmap, pv->pv_va, pv->pv_next);
+#endif
+ pmap_remove_mapping(pv->pv_pmap, pv->pv_va,
+ NULL, PRM_TFLUSH|PRM_CFLUSH);
+ uvm_pagefree(PHYS_TO_VM_PAGE(pa));
+ PMAP_DPRINTF(PDB_REMOVE|PDB_PTPAGE,
+ ("remove: PT page 0x%lx (0x%lx) freed\n",
+ ptpva, pa));
+ }
+ }
+ /*
+ * If this isn't a managed page, we are all done.
+ */
+ if (PAGE_IS_MANAGED(pa) == 0)
+ return;
+ /*
+ * Otherwise remove it from the PV table
+ * (raise IPL since we may be called at interrupt time).
+ */
+ pv = pa_to_pvh(pa);
+ ste = ST_ENTRY_NULL;
+ s = splimp();
+ /*
+ * If it is the first entry on the list, it is actually
+ * in the header and we must copy the following entry up
+ * to the header. Otherwise we must search the list for
+ * the entry. In either case we free the now unused entry.
+ */
+ if (pmap == pv->pv_pmap && va == pv->pv_va) {
+ ste = pv->pv_ptste;
+ ptpmap = pv->pv_ptpmap;
+ npv = pv->pv_next;
+ if (npv) {
+ npv->pv_flags = pv->pv_flags;
+ *pv = *npv;
+ pmap_free_pv(npv);
+ } else
+ pv->pv_pmap = NULL;
+ } else {
+ for (npv = pv->pv_next; npv; npv = npv->pv_next) {
+ if (pmap == npv->pv_pmap && va == npv->pv_va)
+ break;
+ pv = npv;
+ }
+#ifdef DEBUG
+ if (npv == NULL)
+ panic("pmap_remove: PA not in pv_tab");
+#endif
+ ste = npv->pv_ptste;
+ ptpmap = npv->pv_ptpmap;
+ pv->pv_next = npv->pv_next;
+ pmap_free_pv(npv);
+ pv = pa_to_pvh(pa);
+ }
+ /*
+ * If this was a PT page we must also remove the
+ * mapping from the associated segment table.
+ */
+ if (ste) {
+ PMAP_DPRINTF(PDB_REMOVE|PDB_PTPAGE,
+ ("remove: ste was %x@%p pte was %x@%p\n",
+ *ste, ste, opte, pmap_pte(pmap, va)));
+#if defined(M68040)
+ if (mmutype == MMU_68040) {
+ st_entry_t *este = &ste[NPTEPG/SG4_LEV3SIZE];
+
+ while (ste < este)
+ *ste++ = SG_NV;
+#ifdef DEBUG
+ ste -= NPTEPG/SG4_LEV3SIZE;
+#endif
+ } else
+#endif
+ *ste = SG_NV;
+ /*
+ * If it was a user PT page, we decrement the
+ * reference count on the segment table as well,
+ * freeing it if it is now empty.
+ */
+ if (ptpmap != pmap_kernel()) {
+ PMAP_DPRINTF(PDB_REMOVE|PDB_SEGTAB,
+ ("remove: stab %p, refcnt %d\n",
+ ptpmap->pm_stab, ptpmap->pm_sref - 1));
+#ifdef DEBUG
+ if ((pmapdebug & PDB_PARANOIA) &&
+ ptpmap->pm_stab != (st_entry_t *)trunc_page(ste))
+ panic("remove: bogus ste");
+#endif
+ if (--(ptpmap->pm_sref) == 0) {
+ PMAP_DPRINTF(PDB_REMOVE|PDB_SEGTAB,
+ ("remove: free stab %p\n",
+ ptpmap->pm_stab));
+ uvm_km_free_wakeup(st_map,
+ (vaddr_t)ptpmap->pm_stab,
+ STSIZE);
+ ptpmap->pm_stab = Segtabzero;
+ ptpmap->pm_stpa = Segtabzeropa;
+#if defined(M68040)
+ if (mmutype == MMU_68040)
+ ptpmap->pm_stfree = protostfree;
+#endif
+ /*
+ * XXX may have changed segment table
+ * pointer for current process so
+ * update now to reload hardware.
+ */
+ if (active_user_pmap(ptpmap))
+ PMAP_ACTIVATE(ptpmap, 1);
+ }
+#ifdef DEBUG
+ else if (ptpmap->pm_sref < 0)
+ panic("remove: sref < 0");
+#endif
+ }
+#if 0
+ /*
+ * XXX this should be unnecessary as we have been
+ * flushing individual mappings as we go.
+ */
+ if (ptpmap == pmap_kernel())
+ TBIAS();
+ else
+ TBIAU();
+#endif
+ pv->pv_flags &= ~PV_PTPAGE;
+ ptpmap->pm_ptpages--;
+ }
+ /*
+ * Update saved attributes for managed page
+ */
+ *pa_to_attribute(pa) |= bits;
+ splx(s);
+}
+
+/*
+ * pmap_testbit:
+ *
+ * Test the modified/referenced bits of a physical page.
+ */
+/* static */
+boolean_t
+pmap_testbit(pa, bit)
+ paddr_t pa;
+ int bit;
+{
+ struct pv_entry *pv;
+ pt_entry_t *pte;
+ int s;
+
+ if (PAGE_IS_MANAGED(pa) == 0)
+ return(FALSE);
+
+ pv = pa_to_pvh(pa);
+ s = splimp();
+ /*
+ * Check saved info first
+ */
+ if (*pa_to_attribute(pa) & bit) {
+ splx(s);
+ return(TRUE);
+ }
+
+ /*
+ * Not found. Check current mappings, returning immediately if
+ * found. Cache a hit to speed future lookups.
+ */
+ if (pv->pv_pmap != NULL) {
+ for (; pv; pv = pv->pv_next) {
+ pte = pmap_pte(pv->pv_pmap, pv->pv_va);
+ if (*pte & bit) {
+ *pa_to_attribute(pa) |= bit;
+ splx(s);
+ return(TRUE);
+ }
+ }
+ }
+ splx(s);
+ return(FALSE);
+}
+
+/*
+ * pmap_changebit:
+ *
+ * Change the modified/referenced bits, or other PTE bits,
+ * for a physical page.
+ */
+/* static */
+void
+pmap_changebit(pa, set, mask)
+ paddr_t pa;
+ int set, mask;
+{
+ struct pv_entry *pv;
+ pt_entry_t *pte, npte;
+ vaddr_t va;
+ int s;
+#if defined(M68040)
+ boolean_t firstpage = TRUE;
+#endif
+
+ PMAP_DPRINTF(PDB_BITS,
+ ("pmap_changebit(%lx, %x, %x)\n", pa, set, mask));
+
+ if (PAGE_IS_MANAGED(pa) == 0)
+ return;
+
+ pv = pa_to_pvh(pa);
+ s = splimp();
+
+ /*
+ * Clear saved attributes (modify, reference)
+ */
+ *pa_to_attribute(pa) &= mask;
+
+ /*
+ * Loop over all current mappings setting/clearing as appropos
+ * If setting RO do we need to clear the VAC?
+ */
+ if (pv->pv_pmap != NULL) {
+#ifdef DEBUG
+ int toflush = 0;
+#endif
+ for (; pv; pv = pv->pv_next) {
+#ifdef DEBUG
+ toflush |= (pv->pv_pmap == pmap_kernel()) ? 2 : 1;
+#endif
+ va = pv->pv_va;
+
+ /*
+ * XXX don't write protect pager mappings
+ */
+ if (set == PG_RO) {
+ if (va >= uvm.pager_sva && va < uvm.pager_eva)
+ continue;
+ }
+
+ pte = pmap_pte(pv->pv_pmap, va);
+ npte = (*pte | set) & mask;
+ if (*pte != npte) {
+#if defined(M68040)
+ /*
+ * If we are changing caching status or
+ * protection make sure the caches are
+ * flushed (but only once).
+ */
+ if (firstpage && (mmutype == MMU_68040) &&
+ ((set == PG_RO) ||
+ (set & PG_CMASK) ||
+ (mask & PG_CMASK) == 0)) {
+ firstpage = FALSE;
+ DCFP(pa);
+ ICPP(pa);
+ }
+#endif
+ *pte = npte;
+ if (active_pmap(pv->pv_pmap))
+ TBIS(va);
+ }
+ }
+ }
+ splx(s);
+}
+
+/*
+ * pmap_enter_ptpage:
+ *
+ * Allocate and map a PT page for the specified pmap/va pair.
+ */
+/* static */
+void
+pmap_enter_ptpage(pmap, va)
+ pmap_t pmap;
+ vaddr_t va;
+{
+ paddr_t ptpa;
+ struct pv_entry *pv;
+ st_entry_t *ste;
+ int s;
+
+ PMAP_DPRINTF(PDB_FOLLOW|PDB_ENTER|PDB_PTPAGE,
+ ("pmap_enter_ptpage: pmap %p, va %lx\n", pmap, va));
+
+ /*
+ * Allocate a segment table if necessary. Note that it is allocated
+ * from a private map and not pt_map. This keeps user page tables
+ * aligned on segment boundaries in the kernel address space.
+ * The segment table is wired down. It will be freed whenever the
+ * reference count drops to zero.
+ */
+ if (pmap->pm_stab == Segtabzero) {
+ pmap->pm_stab = (st_entry_t *)
+ uvm_km_zalloc(st_map, STSIZE);
+ (void) pmap_extract(pmap_kernel(), (vaddr_t)pmap->pm_stab,
+ (paddr_t *)&pmap->pm_stpa);
+#if defined(M68040)
+ if (mmutype == MMU_68040) {
+#ifdef DEBUG
+ if (dowriteback && dokwriteback)
+#endif
+ pmap_changebit((paddr_t)pmap->pm_stpa, 0, ~PG_CCB);
+ pmap->pm_stfree = protostfree;
+ }
+#endif
+ /*
+ * XXX may have changed segment table pointer for current
+ * process so update now to reload hardware.
+ */
+ if (active_user_pmap(pmap))
+ PMAP_ACTIVATE(pmap, 1);
+
+ PMAP_DPRINTF(PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB,
+ ("enter: pmap %p stab %p(%p)\n",
+ pmap, pmap->pm_stab, pmap->pm_stpa));
+ }
+
+ ste = pmap_ste(pmap, va);
+#if defined(M68040)
+ /*
+ * Allocate level 2 descriptor block if necessary
+ */
+ if (mmutype == MMU_68040) {
+ if (*ste == SG_NV) {
+ int ix;
+ caddr_t addr;
+
+ ix = bmtol2(pmap->pm_stfree);
+ if (ix == -1)
+ panic("enter: out of address space"); /* XXX */
+ pmap->pm_stfree &= ~l2tobm(ix);
+ addr = (caddr_t)&pmap->pm_stab[ix*SG4_LEV2SIZE];
+ bzero(addr, SG4_LEV2SIZE*sizeof(st_entry_t));
+ addr = (caddr_t)&pmap->pm_stpa[ix*SG4_LEV2SIZE];
+ *ste = (u_int)addr | SG_RW | SG_U | SG_V;
+
+ PMAP_DPRINTF(PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB,
+ ("enter: alloc ste2 %d(%p)\n", ix, addr));
+ }
+ ste = pmap_ste2(pmap, va);
+ /*
+ * Since a level 2 descriptor maps a block of SG4_LEV3SIZE
+ * level 3 descriptors, we need a chunk of NPTEPG/SG4_LEV3SIZE
+ * (16) such descriptors (NBPG/SG4_LEV3SIZE bytes) to map a
+ * PT page--the unit of allocation. We set `ste' to point
+ * to the first entry of that chunk which is validated in its
+ * entirety below.
+ */
+ ste = (st_entry_t *)((int)ste & ~(NBPG/SG4_LEV3SIZE-1));
+
+ PMAP_DPRINTF(PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB,
+ ("enter: ste2 %p (%p)\n", pmap_ste2(pmap, va), ste));
+ }
+#endif
+ va = trunc_page((vaddr_t)pmap_pte(pmap, va));
+
+ /*
+ * In the kernel we allocate a page from the kernel PT page
+ * free list and map it into the kernel page table map (via
+ * pmap_enter).
+ */
+ if (pmap == pmap_kernel()) {
+ struct kpt_page *kpt;
+
+ s = splimp();
+ if ((kpt = kpt_free_list) == (struct kpt_page *)0) {
+ /*
+ * No PT pages available.
+ * Try once to free up unused ones.
+ */
+ PMAP_DPRINTF(PDB_COLLECT,
+ ("enter: no KPT pages, collecting...\n"));
+ pmap_collect(pmap_kernel());
+ if ((kpt = kpt_free_list) == (struct kpt_page *)0)
+ panic("pmap_enter_ptpage: can't get KPT page");
+ }
+ kpt_free_list = kpt->kpt_next;
+ kpt->kpt_next = kpt_used_list;
+ kpt_used_list = kpt;
+ ptpa = kpt->kpt_pa;
+ bzero((caddr_t)kpt->kpt_va, NBPG);
+ pmap_enter(pmap, va, ptpa, VM_PROT_DEFAULT,
+ VM_PROT_DEFAULT|PMAP_WIRED);
+#ifdef DEBUG
+ if (pmapdebug & (PDB_ENTER|PDB_PTPAGE)) {
+ int ix = pmap_ste(pmap, va) - pmap_ste(pmap, 0);
+
+ printf("enter: add &Sysptmap[%d]: %x (KPT page %lx)\n",
+ ix, Sysptmap[ix], kpt->kpt_va);
+ }
+#endif
+ splx(s);
+ }
+ /*
+ * For user processes we just simulate a fault on that location
+ * letting the VM system allocate a zero-filled page.
+ *
+ * Note we use a wire-fault to keep the page off the paging
+ * queues. This sets our PT page's reference (wire) count to
+ * 1, which is what we use to check if the page can be freed.
+ * See pmap_remove_mapping().
+ */
+ else {
+ /*
+ * Count the segment table reference now so that we won't
+ * lose the segment table when low on memory.
+ */
+ pmap->pm_sref++;
+ PMAP_DPRINTF(PDB_ENTER|PDB_PTPAGE,
+ ("enter: about to fault UPT pg at %lx\n", va));
+ s = uvm_fault_wire(pt_map, va, va + PAGE_SIZE,
+ VM_PROT_READ|VM_PROT_WRITE);
+ if (s != KERN_SUCCESS) {
+ printf("uvm_fault_wire(pt_map, 0x%lx, 0x%lx, RW) "
+ "-> %d\n", va, va + PAGE_SIZE, s);
+ panic("pmap_enter: uvm_fault_wire failed");
+ }
+ ptpa = pmap_pte_pa(pmap_pte(pmap_kernel(), va));
+ }
+#if defined(M68040)
+ /*
+ * Turn off copyback caching of page table pages,
+ * could get ugly otherwise.
+ */
+#ifdef DEBUG
+ if (dowriteback && dokwriteback)
+#endif
+ if (mmutype == MMU_68040) {
+#ifdef DEBUG
+ pt_entry_t *pte = pmap_pte(pmap_kernel(), va);
+ if ((pmapdebug & PDB_PARANOIA) && (*pte & PG_CCB) == 0)
+ printf("%s PT no CCB: kva=%lx ptpa=%lx pte@%p=%x\n",
+ pmap == pmap_kernel() ? "Kernel" : "User",
+ va, ptpa, pte, *pte);
+#endif
+ pmap_changebit(ptpa, 0, ~PG_CCB);
+ }
+#endif
+ /*
+ * Locate the PV entry in the kernel for this PT page and
+ * record the STE address. This is so that we can invalidate
+ * the STE when we remove the mapping for the page.
+ */
+ pv = pa_to_pvh(ptpa);
+ s = splimp();
+ if (pv) {
+ pv->pv_flags |= PV_PTPAGE;
+ do {
+ if (pv->pv_pmap == pmap_kernel() && pv->pv_va == va)
+ break;
+ } while ((pv = pv->pv_next));
+ }
+#ifdef DEBUG
+ if (pv == NULL)
+ panic("pmap_enter_ptpage: PT page not entered");
+#endif
+ pv->pv_ptste = ste;
+ pv->pv_ptpmap = pmap;
+
+ PMAP_DPRINTF(PDB_ENTER|PDB_PTPAGE,
+ ("enter: new PT page at PA %lx, ste at %p\n", ptpa, ste));
+
+ /*
+ * Map the new PT page into the segment table.
+ * Also increment the reference count on the segment table if this
+ * was a user page table page. Note that we don't use vm_map_pageable
+ * to keep the count like we do for PT pages, this is mostly because
+ * it would be difficult to identify ST pages in pmap_pageable to
+ * release them. We also avoid the overhead of vm_map_pageable.
+ */
+#if defined(M68040)
+ if (mmutype == MMU_68040) {
+ st_entry_t *este;
+
+ for (este = &ste[NPTEPG/SG4_LEV3SIZE]; ste < este; ste++) {
+ *ste = ptpa | SG_U | SG_RW | SG_V;
+ ptpa += SG4_LEV3SIZE * sizeof(st_entry_t);
+ }
+ } else
+#endif
+ *ste = (ptpa & SG_FRAME) | SG_RW | SG_V;
+ if (pmap != pmap_kernel()) {
+ PMAP_DPRINTF(PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB,
+ ("enter: stab %p refcnt %d\n",
+ pmap->pm_stab, pmap->pm_sref));
+ }
+#if 0
+ /*
+ * Flush stale TLB info.
+ */
+ if (pmap == pmap_kernel())
+ TBIAS();
+ else
+ TBIAU();
+#endif
+ pmap->pm_ptpages++;
+ splx(s);
+}
+
+/*
+ * pmap_ptpage_addref:
+ *
+ * Add a reference to the specified PT page.
+ */
+void
+pmap_ptpage_addref(ptpva)
+ vaddr_t ptpva;
+{
+ vm_page_t m;
+
+ simple_lock(&uvm.kernel_object->vmobjlock);
+ m = uvm_pagelookup(uvm.kernel_object, ptpva - vm_map_min(kernel_map));
+ m->wire_count++;
+ simple_unlock(&uvm.kernel_object->vmobjlock);
+}
+
+/*
+ * pmap_ptpage_delref:
+ *
+ * Delete a reference to the specified PT page.
+ */
+int
+pmap_ptpage_delref(ptpva)
+ vaddr_t ptpva;
+{
+ vm_page_t m;
+ int rv;
+
+ simple_lock(&uvm.kernel_object->vmobjlock);
+ m = uvm_pagelookup(uvm.kernel_object, ptpva - vm_map_min(kernel_map));
+ rv = --m->wire_count;
+ simple_unlock(&uvm.kernel_object->vmobjlock);
+ return (rv);
+}
+
+/*
+ * Routine: pmap_procwr
+ *
+ * Function:
+ * Synchronize caches corresponding to [addr, addr+len) in p.
+ */
+void
+pmap_procwr(p, va, len)
+ struct proc *p;
+ vaddr_t va;
+ size_t len;
+{
+ (void)cachectl1(0x80000004, va, len, p);
+}
+
+
+#ifdef DEBUG
+/*
+ * pmap_pvdump:
+ *
+ * Dump the contents of the PV list for the specified physical page.
+ */
+/* static */
+void
+pmap_pvdump(pa)
+ paddr_t pa;
+{
+ struct pv_entry *pv;
+
+ printf("pa %lx", pa);
+ for (pv = pa_to_pvh(pa); pv; pv = pv->pv_next)
+ printf(" -> pmap %p, va %lx, ptste %p, ptpmap %p, flags %x",
+ pv->pv_pmap, pv->pv_va, pv->pv_ptste, pv->pv_ptpmap,
+ pv->pv_flags);
+ printf("\n");
+}
+
+/*
+ * pmap_check_wiring:
+ *
+ * Count the number of valid mappings in the specified PT page,
+ * and ensure that it is consistent with the number of wirings
+ * to that page that the VM system has.
+ */
+/* static */
+void
+pmap_check_wiring(str, va)
+ char *str;
+ vaddr_t va;
+{
+ pt_entry_t *pte;
+ paddr_t pa;
+ vm_page_t m;
+ int count;
+
+ if (!pmap_ste_v(pmap_kernel(), va) ||
+ !pmap_pte_v(pmap_pte(pmap_kernel(), va)))
+ return;
+
+ pa = pmap_pte_pa(pmap_pte(pmap_kernel(), va));
+ m = PHYS_TO_VM_PAGE(pa);
+ if (m->wire_count < 1) {
+ printf("*%s*: 0x%lx: wire count %d\n", str, va, m->wire_count);
+ return;
+ }
+
+ count = 0;
+ for (pte = (pt_entry_t *)va; pte < (pt_entry_t *)(va + NBPG); pte++)
+ if (*pte)
+ count++;
+ if ((m->wire_count - 1) != count)
+ printf("*%s*: 0x%lx: w%d/a%d\n",
+ str, va, (m->wire_count - 1), count);
+}
+#endif /* DEBUG */
diff --git a/sys/arch/luna68k/luna68k/pmap_bootstrap.c b/sys/arch/luna68k/luna68k/pmap_bootstrap.c
new file mode 100644
index 00000000000..2cc66df11a0
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/pmap_bootstrap.c
@@ -0,0 +1,474 @@
+/* $NetBSD: pmap_bootstrap.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $ */
+/* $NetBSD: pmap_bootstrap.c,v 1.1 2000/01/05 08:49:03 nisimura Exp $ */
+
+/*
+ * Copyright (c) 1991, 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.
+ *
+ * @(#)pmap_bootstrap.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/proc.h>
+
+#include <machine/frame.h>
+#include <machine/cpu.h>
+#include <machine/vmparam.h>
+#include <machine/pte.h>
+
+#include <vm/vm.h>
+
+#define RELOC(v, t) *((t*)((u_int)&(v) + firstpa))
+
+extern char *etext;
+extern int Sysptsize;
+extern char *proc0paddr;
+extern st_entry_t *Sysseg;
+extern pt_entry_t *Sysptmap, *Sysmap;
+
+extern int maxmem, physmem;
+extern paddr_t avail_start, avail_end;
+extern vaddr_t virtual_avail, virtual_end;
+extern vsize_t mem_size;
+extern int protection_codes[];
+
+void pmap_bootstrap __P((paddr_t, paddr_t));
+
+/*
+ * Special purpose kernel virtual addresses, used for mapping
+ * physical pages for a variety of temporary or permanent purposes:
+ *
+ * CADDR1, CADDR2: pmap zero/copy operations
+ * vmmap: /dev/mem, crash dumps, parity error checking
+ * msgbufaddr: kernel message buffer
+ */
+caddr_t CADDR1, CADDR2, vmmap;
+extern caddr_t msgbufaddr;
+
+/*
+ * Bootstrap the VM system.
+ *
+ * Called with MMU off so we must relocate all global references by `firstpa'
+ * (don't call any functions here!) `nextpa' is the first available physical
+ * memory address. Returns an updated first PA reflecting the memory we
+ * have allocated. MMU is still off when we return.
+ *
+ * XXX assumes sizeof(u_int) == sizeof(pt_entry_t)
+ * XXX a PIC compiler would make this much easier.
+ */
+void
+pmap_bootstrap(nextpa, firstpa)
+ paddr_t nextpa;
+ paddr_t firstpa;
+{
+ paddr_t kstpa, kptpa, eiiopa, iiopa, kptmpa, lkptpa, p0upa;
+ u_int nptpages, kstsize;
+ st_entry_t protoste, *ste;
+ pt_entry_t protopte, *pte, *epte;
+ u_int iiomapsize;
+
+ /*
+ * Calculate important physical addresses:
+ *
+ * kstpa kernel segment table 1 page (!040)
+ * N pages (040)
+ *
+ * kptpa statically allocated
+ * kernel PT pages Sysptsize+ pages
+ *
+ * iiopa internal IO space
+ * PT pages iiomapsize pages
+ *
+ * eiiopa page following
+ * internal IO space
+ *
+ * [ Sysptsize is the number of pages of PT, and iiomapsize
+ * is the number of PTEs, hence we need to round
+ * the total to a page boundary with IO maps at the end. ]
+ *
+ * kptmpa kernel PT map 1 page
+ *
+ * lkptpa last kernel PT page 1 page
+ *
+ * p0upa proc 0 u-area UPAGES pages
+ *
+ * The KVA corresponding to any of these PAs is:
+ * (PA - firstpa + KERNBASE).
+ */
+ iiomapsize = m68k_btop(RELOC(intiotop_phys, u_int) -
+ RELOC(intiobase_phys, u_int));
+
+ if (RELOC(mmutype, int) == MMU_68040)
+ kstsize = MAXKL2SIZE / (NPTEPG/SG4_LEV2SIZE);
+ else
+ kstsize = 1;
+ kstpa = nextpa;
+ nextpa += kstsize * NBPG;
+ kptpa = nextpa;
+ nptpages = RELOC(Sysptsize, int) +
+ (iiomapsize + NPTEPG - 1) / NPTEPG;
+ nextpa += nptpages * NBPG;
+ eiiopa = nextpa; /* just a reference for later */
+ iiopa = nextpa - iiomapsize * sizeof(pt_entry_t);
+ kptmpa = nextpa;
+ nextpa += NBPG;
+ lkptpa = nextpa;
+ nextpa += NBPG;
+ p0upa = nextpa;
+ nextpa += USPACE;
+
+ /*
+ * Clear all PTEs to zero
+ */
+ for (pte = (pt_entry_t *)kstpa; pte < (pt_entry_t *)nextpa; pte++)
+ *pte = 0;
+
+ /*
+ * Initialize segment table and kernel page table map.
+ *
+ * On 68030s and earlier MMUs the two are identical except for
+ * the valid bits so both are initialized with essentially the
+ * same values. On the 68040, which has a mandatory 3-level
+ * structure, the segment table holds the level 1 table and part
+ * (or all) of the level 2 table and hence is considerably
+ * different. Here the first level consists of 128 descriptors
+ * (512 bytes) each mapping 32mb of address space. Each of these
+ * points to blocks of 128 second level descriptors (512 bytes)
+ * each mapping 256kb. Note that there may be additional "segment
+ * table" pages depending on how large MAXKL2SIZE is.
+ *
+ * Portions of the last segment of KVA space (0xFFF00000 -
+ * 0xFFFFFFFF) are mapped for a couple of purposes. 0xFFF00000
+ * for UPAGES is used for mapping the current process u-area
+ * (u + kernel stack). The very last page (0xFFFFF000) is mapped
+ * to the last physical page of RAM to give us a region in which
+ * PA == VA. We use the first part of this page for enabling
+ * and disabling mapping. The last part of this page also contains
+ * info left by the boot ROM.
+ *
+ * XXX cramming two levels of mapping into the single "segment"
+ * table on the 68040 is intended as a temporary hack to get things
+ * working. The 224mb of address space that this allows will most
+ * likely be insufficient in the future (at least for the kernel).
+ */
+ if (RELOC(mmutype, int) == MMU_68040) {
+ int num;
+
+ /*
+ * First invalidate the entire "segment table" pages
+ * (levels 1 and 2 have the same "invalid" value).
+ */
+ pte = (u_int *)kstpa;
+ epte = &pte[kstsize * NPTEPG];
+ while (pte < epte)
+ *pte++ = SG_NV;
+ /*
+ * Initialize level 2 descriptors (which immediately
+ * follow the level 1 table). We need:
+ * NPTEPG / SG4_LEV3SIZE
+ * level 2 descriptors to map each of the nptpages+1
+ * pages of PTEs. Note that we set the "used" bit
+ * now to save the HW the expense of doing it.
+ */
+ num = (nptpages + 1) * (NPTEPG / SG4_LEV3SIZE);
+ pte = &((u_int *)kstpa)[SG4_LEV1SIZE];
+ epte = &pte[num];
+ protoste = kptpa | SG_U | SG_RW | SG_V;
+ while (pte < epte) {
+ *pte++ = protoste;
+ protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
+ }
+ /*
+ * Initialize level 1 descriptors. We need:
+ * roundup(num, SG4_LEV2SIZE) / SG4_LEV2SIZE
+ * level 1 descriptors to map the `num' level 2's.
+ */
+ pte = (u_int *)kstpa;
+ epte = &pte[roundup(num, SG4_LEV2SIZE) / SG4_LEV2SIZE];
+ protoste = (u_int)&pte[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V;
+ while (pte < epte) {
+ *pte++ = protoste;
+ protoste += (SG4_LEV2SIZE * sizeof(st_entry_t));
+ }
+ /*
+ * Initialize the final level 1 descriptor to map the last
+ * block of level 2 descriptors.
+ */
+ ste = &((u_int *)kstpa)[SG4_LEV1SIZE-1];
+ pte = &((u_int *)kstpa)[kstsize*NPTEPG - SG4_LEV2SIZE];
+ *ste = (u_int)pte | SG_U | SG_RW | SG_V;
+ /*
+ * Now initialize the final portion of that block of
+ * descriptors to map the "last PT page".
+ */
+ pte = &((u_int *)kstpa)[kstsize*NPTEPG - NPTEPG/SG4_LEV3SIZE];
+ epte = &pte[NPTEPG/SG4_LEV3SIZE];
+ protoste = lkptpa | SG_U | SG_RW | SG_V;
+ while (pte < epte) {
+ *pte++ = protoste;
+ protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
+ }
+ /*
+ * Initialize Sysptmap
+ */
+ pte = (u_int *)kptmpa;
+ epte = &pte[nptpages+1];
+ protopte = kptpa | PG_RW | PG_CI | PG_V;
+ while (pte < epte) {
+ *pte++ = protopte;
+ protopte += NBPG;
+ }
+ /*
+ * Invalidate all but the last remaining entry.
+ */
+ epte = &((u_int *)kptmpa)[NPTEPG-1];
+ while (pte < epte) {
+ *pte++ = PG_NV;
+ }
+ *pte = lkptpa | PG_RW | PG_CI | PG_V;
+ } else {
+ /*
+ * Map the page table pages in both the HW segment table
+ * and the software Sysptmap. Note that Sysptmap is also
+ * considered a PT page hence the +1.
+ */
+ ste = (u_int *)kstpa;
+ pte = (u_int *)kptmpa;
+ epte = &pte[nptpages+1];
+ protoste = kptpa | SG_RW | SG_V;
+ protopte = kptpa | PG_RW | PG_CI | PG_V;
+ while (pte < epte) {
+ *ste++ = protoste;
+ *pte++ = protopte;
+ protoste += NBPG;
+ protopte += NBPG;
+ }
+ /*
+ * Invalidate all but the last remaining entries in both.
+ */
+ epte = &((u_int *)kptmpa)[NPTEPG-1];
+ while (pte < epte) {
+ *ste++ = SG_NV;
+ *pte++ = PG_NV;
+ }
+ /*
+ * Initialize the last to point to point to the page
+ * table page allocated earlier.
+ */
+ *ste = lkptpa | SG_RW | SG_V;
+ *pte = lkptpa | PG_RW | PG_CI | PG_V;
+ }
+ /*
+ * Invalidate all but the final entry in the last kernel PT page
+ * (u-area PTEs will be validated later). The final entry maps
+ * the last page of physical memory.
+ */
+ pte = (u_int *)lkptpa;
+ epte = &pte[NPTEPG-1];
+ while (pte < epte)
+ *pte++ = PG_NV;
+
+ /*
+ * Initialize kernel page table.
+ * Start by invalidating the `nptpages' that we have allocated.
+ */
+ pte = (u_int *)kptpa;
+ epte = &pte[nptpages * NPTEPG];
+ while (pte < epte)
+ *pte++ = PG_NV;
+ /*
+ * Validate PTEs for kernel text (RO)
+ */
+ pte = &((u_int *)kptpa)[m68k_btop(KERNBASE)];
+ epte = &pte[m68k_btop(m68k_trunc_page(&etext))];
+ protopte = firstpa | PG_RO | PG_V;
+ while (pte < epte) {
+ *pte++ = protopte;
+ protopte += NBPG;
+ }
+ /*
+ * Validate PTEs for kernel data/bss, dynamic data allocated
+ * by us so far (nextpa - firstpa bytes), and pages for proc0
+ * u-area and page table allocated below (RW).
+ */
+ epte = &((u_int *)kptpa)[m68k_btop(nextpa - firstpa)];
+ protopte = (protopte & ~PG_PROT) | PG_RW;
+ /*
+ * Enable copy-back caching of data pages
+ */
+ if (RELOC(mmutype, int) == MMU_68040)
+ protopte |= PG_CCB;
+ while (pte < epte) {
+ *pte++ = protopte;
+ protopte += NBPG;
+ }
+
+ /*
+ * Finally, validate the internal IO space PTEs (RW+CI).
+ */
+ pte = (u_int *)iiopa;
+ epte = (u_int *)eiiopa;
+ protopte = RELOC(intiobase_phys, u_int) | PG_RW | PG_CI | PG_V;
+ while (pte < epte) {
+ *pte++ = protopte;
+ protopte += NBPG;
+ }
+
+ /*
+ * Calculate important exported kernel virtual addresses
+ */
+ /*
+ * Sysseg: base of kernel segment table
+ */
+ RELOC(Sysseg, st_entry_t *) =
+ (st_entry_t *)(kstpa - firstpa);
+ /*
+ * Sysptmap: base of kernel page table map
+ */
+ RELOC(Sysptmap, pt_entry_t *) =
+ (pt_entry_t *)(kptmpa - firstpa);
+ /*
+ * Sysmap: kernel page table (as mapped through Sysptmap)
+ * Immediately follows `nptpages' of static kernel page table.
+ */
+ RELOC(Sysmap, pt_entry_t *) =
+ (pt_entry_t *)m68k_ptob(nptpages * NPTEPG);
+ /*
+ * intiobase, intiolimit: base and end of internal IO space.
+ * iiomapsize pages prior to external IO space at end of static
+ * kernel page table.
+ */
+ RELOC(intiobase, char *) =
+ (char *)m68k_ptob(nptpages*NPTEPG - iiomapsize);
+ RELOC(intiolimit, char *) =
+ (char *)m68k_ptob(nptpages*NPTEPG);
+
+ /*
+ * Setup u-area for process 0.
+ */
+ /*
+ * Zero the u-area.
+ * NOTE: `pte' and `epte' aren't PTEs here.
+ */
+ pte = (u_int *)p0upa;
+ epte = (u_int *)(p0upa + USPACE);
+ while (pte < epte)
+ *pte++ = 0;
+ /*
+ * Remember the u-area address so it can be loaded in the
+ * proc struct p_addr field later.
+ */
+ RELOC(proc0paddr, char *) = (char *)(p0upa - firstpa);
+
+ RELOC(avail_start, paddr_t) = nextpa;
+ RELOC(avail_end, paddr_t) = m68k_ptob(RELOC(maxmem, int)) -
+ (m68k_round_page(MSGBUFSIZE));
+ RELOC(mem_size, vsize_t) = m68k_ptob(RELOC(physmem, int));
+
+ RELOC(virtual_avail, vaddr_t) =
+ VM_MIN_KERNEL_ADDRESS + (vaddr_t)(nextpa - firstpa);
+ RELOC(virtual_end, vaddr_t) = VM_MAX_KERNEL_ADDRESS;
+
+ /*
+ * Initialize protection array.
+ * XXX don't use a switch statement, it might produce an
+ * absolute "jmp" table.
+ */
+ {
+ int *kp;
+
+ kp = &RELOC(protection_codes, int);
+ kp[VM_PROT_NONE|VM_PROT_NONE|VM_PROT_NONE] = 0;
+ kp[VM_PROT_READ|VM_PROT_NONE|VM_PROT_NONE] = PG_RO;
+ kp[VM_PROT_READ|VM_PROT_NONE|VM_PROT_EXECUTE] = PG_RO;
+ kp[VM_PROT_NONE|VM_PROT_NONE|VM_PROT_EXECUTE] = PG_RO;
+ kp[VM_PROT_NONE|VM_PROT_WRITE|VM_PROT_NONE] = PG_RW;
+ kp[VM_PROT_NONE|VM_PROT_WRITE|VM_PROT_EXECUTE] = PG_RW;
+ kp[VM_PROT_READ|VM_PROT_WRITE|VM_PROT_NONE] = PG_RW;
+ kp[VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE] = PG_RW;
+ }
+
+ /*
+ * Kernel page/segment table allocated above,
+ * just initialize pointers.
+ */
+ {
+ struct pmap *kpm = &RELOC(kernel_pmap_store, struct pmap);
+
+ kpm->pm_stab = RELOC(Sysseg, st_entry_t *);
+ kpm->pm_ptab = RELOC(Sysmap, pt_entry_t *);
+ simple_lock_init(&kpm->pm_lock);
+ kpm->pm_count = 1;
+ kpm->pm_stpa = (st_entry_t *)kstpa;
+ /*
+ * For the 040 we also initialize the free level 2
+ * descriptor mask noting that we have used:
+ * 0: level 1 table
+ * 1 to `num': map page tables
+ * MAXKL2SIZE-1: maps last-page page table
+ */
+ if (RELOC(mmutype, int) == MMU_68040) {
+ int num;
+
+ kpm->pm_stfree = ~l2tobm(0);
+ num = roundup((nptpages + 1) * (NPTEPG / SG4_LEV3SIZE),
+ SG4_LEV2SIZE) / SG4_LEV2SIZE;
+ while (num)
+ kpm->pm_stfree &= ~l2tobm(num--);
+ kpm->pm_stfree &= ~l2tobm(MAXKL2SIZE-1);
+ for (num = MAXKL2SIZE;
+ num < sizeof(kpm->pm_stfree)*NBBY;
+ num++)
+ kpm->pm_stfree &= ~l2tobm(num);
+ }
+ }
+
+ /*
+ * Allocate some fixed, special purpose kernel virtual addresses
+ */
+ {
+ vaddr_t va = RELOC(virtual_avail, vaddr_t);
+
+ RELOC(CADDR1, caddr_t) = (caddr_t)va;
+ va += NBPG;
+ RELOC(CADDR2, caddr_t) = (caddr_t)va;
+ va += NBPG;
+ RELOC(vmmap, caddr_t) = (caddr_t)va;
+ va += NBPG;
+ RELOC(msgbufaddr, caddr_t) = (caddr_t)va;
+ va += m68k_round_page(MSGBUFSIZE);
+ RELOC(virtual_avail, vaddr_t) = va;
+ }
+}
diff --git a/sys/arch/luna68k/luna68k/sys_machdep.c b/sys/arch/luna68k/luna68k/sys_machdep.c
new file mode 100644
index 00000000000..c456d7b88d2
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/sys_machdep.c
@@ -0,0 +1,310 @@
+/* $NetBSD: sys_machdep.c,v 1.1 2000/01/05 08:49:04 nisimura Exp $ */
+/* $NetBSD: sys_machdep.c,v 1.1 2000/01/05 08:49:04 nisimura Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 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.
+ *
+ * @(#)sys_machdep.c 8.2 (Berkeley) 1/13/94
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.1 2000/01/05 08:49:04 nisimura Exp $");
+
+#include "opt_compat_hpux.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/uio.h>
+#include <sys/kernel.h>
+#include <sys/buf.h>
+#include <sys/trace.h>
+#include <sys/mount.h>
+
+#include <vm/vm.h>
+
+#include <sys/syscallargs.h>
+
+#include <machine/cpu.h>
+#include <m68k/cacheops.h>
+
+#ifdef TRACE
+int nvualarm;
+
+sys_vtrace(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct sys_vtrace_args /* {
+ syscallarg(int) request;
+ syscallarg(int) value;
+ } */ *uap = v;
+ int vdoualarm();
+
+ switch (SCARG(uap, request)) {
+
+ case VTR_DISABLE: /* disable a trace point */
+ case VTR_ENABLE: /* enable a trace point */
+ if (SCARG(uap, value) < 0 || SCARG(uap, value) >= TR_NFLAGS)
+ return (EINVAL);
+ *retval = traceflags[SCARG(uap, value)];
+ traceflags[SCARG(uap, value)] = SCARG(uap, request);
+ break;
+
+ case VTR_VALUE: /* return a trace point setting */
+ if (SCARG(uap, value) < 0 || SCARG(uap, value) >= TR_NFLAGS)
+ return (EINVAL);
+ *retval = traceflags[SCARG(uap, value)];
+ break;
+
+ case VTR_UALARM: /* set a real-time ualarm, less than 1 min */
+ if (SCARG(uap, value) <= 0 || SCARG(uap, value) > 60 * hz ||
+ nvualarm > 5)
+ return (EINVAL);
+ nvualarm++;
+ timeout(vdoualarm, (void *)p->p_pid, SCARG(uap, value));
+ break;
+
+ case VTR_STAMP:
+ trace(TR_STAMP, SCARG(uap, value), p->p_pid);
+ break;
+ }
+ return (0);
+}
+
+vdoualarm(arg)
+ void *arg;
+{
+ int pid = (int)arg;
+ struct proc *p;
+
+ p = pfind(pid);
+ if (p)
+ psignal(p, 16);
+ nvualarm--;
+}
+#endif
+
+#include <machine/cpu.h>
+
+/* XXX should be in an include file somewhere */
+#define CC_PURGE 1
+#define CC_FLUSH 2
+#define CC_IPURGE 4
+#define CC_EXTPURGE 0x80000000
+/* XXX end should be */
+
+/*
+ * Note that what we do here for a 68040 is different than HP-UX.
+ *
+ * In 'pux they either act on a line (len == 16), a page (len == NBPG)
+ * or the whole cache (len == anything else).
+ *
+ * In BSD we attempt to be more optimal when acting on "odd" sizes.
+ * For lengths up to 1024 we do all affected lines, up to 2*NBPG we
+ * do pages, above that we do the entire cache.
+ */
+/*ARGSUSED1*/
+int
+cachectl1(req, addr, len, p)
+ unsigned long req;
+ vaddr_t addr;
+ size_t len;
+ struct proc *p;
+{
+ int error = 0;
+
+#if defined(M68040)
+ if (mmutype == MMU_68040) {
+ int inc = 0, doall = 0;
+ paddr_t pa = 0
+ vaddr_t end;
+
+ if (addr == 0 ||
+ (req & ~CC_EXTPURGE) != CC_PURGE && len > 2*NBPG)
+ doall = 1;
+
+ if (!doall) {
+ end = addr + len;
+ if (len <= 1024) {
+ addr = addr & ~0xF;
+ inc = 16;
+ } else {
+ addr = addr & ~PGOFSET;
+ inc = NBPG;
+ }
+ }
+ do {
+ /*
+ * Convert to physical address if needed.
+ * If translation fails, we perform operation on
+ * entire cache (XXX is this a rational thing to do?)
+ */
+ if (!doall &&
+ (pa == 0 || ((int)addr & PGOFSET) == 0)) {
+ if (pmap_extract(p->p_vmspace->vm_map.pmap,
+ addr, &pa) == FALSE)
+ doall = 1;
+ }
+ switch (req) {
+ case CC_EXTPURGE|CC_IPURGE:
+ case CC_IPURGE:
+ if (doall) {
+ DCFA();
+ ICPA();
+ } else if (inc == 16) {
+ DCFL(pa);
+ ICPL(pa);
+ } else if (inc == NBPG) {
+ DCFP(pa);
+ ICPP(pa);
+ }
+ break;
+
+ case CC_EXTPURGE|CC_PURGE:
+ case CC_PURGE:
+ if (doall)
+ DCFA(); /* note: flush not purge */
+ else if (inc == 16)
+ DCPL(pa);
+ else if (inc == NBPG)
+ DCPP(pa);
+ break;
+
+ case CC_EXTPURGE|CC_FLUSH:
+ case CC_FLUSH:
+ if (doall)
+ DCFA();
+ else if (inc == 16)
+ DCFL(pa);
+ else if (inc == NBPG)
+ DCFP(pa);
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+ if (doall)
+ break;
+ pa += inc;
+ addr += inc;
+ } while (addr < end);
+ return(error);
+ }
+#endif
+ switch (req) {
+ case CC_EXTPURGE|CC_PURGE:
+ case CC_EXTPURGE|CC_FLUSH:
+ case CC_PURGE:
+ case CC_FLUSH:
+ DCIU();
+ break;
+ case CC_EXTPURGE|CC_IPURGE:
+ DCIU();
+ /* fall into... */
+ case CC_IPURGE:
+ ICIA();
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ return(error);
+}
+
+/*
+ * DMA cache control
+ */
+
+/*ARGSUSED1*/
+int
+dma_cachectl(addr, len)
+ caddr_t addr;
+ int len;
+{
+#if defined(M68040)
+ if (mmutype == MMU_68040) {
+ int inc = 0;
+ int pa = 0;
+ caddr_t end;
+
+ end = addr + len;
+ if (len <= 1024) {
+ addr = (caddr_t)((int)addr & ~0xF);
+ inc = 16;
+ } else {
+ addr = (caddr_t)((int)addr & ~PGOFSET);
+ inc = NBPG;
+ }
+ do {
+ /*
+ * Convert to physical address.
+ */
+ if (pa == 0 || ((int)addr & PGOFSET) == 0) {
+ pa = kvtop(addr);
+ }
+ if (inc == 16) {
+ DCFL(pa);
+ ICPL(pa);
+ } else {
+ DCFP(pa);
+ ICPP(pa);
+ }
+ pa += inc;
+ addr += inc;
+ } while (addr < end);
+ }
+#endif /* M68040 */
+ return(0);
+}
+
+int
+sys_sysarch(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+#if 0 /* unused */
+ struct sys_sysarch_args /* {
+ syscallarg(int) op;
+ syscallarg(void *) parms;
+ } */ *uap = v;
+#endif
+
+ return (ENOSYS);
+}
diff --git a/sys/arch/luna68k/luna68k/trap.c b/sys/arch/luna68k/luna68k/trap.c
new file mode 100644
index 00000000000..801026466c6
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/trap.c
@@ -0,0 +1,1062 @@
+/* $NetBSD: trap.c,v 1.1 2000/01/05 08:49:04 nisimura Exp $ */
+/* $NetBSD: trap.c,v 1.1 2000/01/05 08:49:04 nisimura 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.
+ *
+ * from: Utah $Hdr: trap.c 1.37 92/12/20$
+ *
+ * @(#)trap.c 8.5 (Berkeley) 1/4/94
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.1 2000/01/05 08:49:04 nisimura Exp $");
+
+#include "opt_ddb.h"
+#include "opt_execfmt.h"
+#include "opt_ktrace.h"
+#include "opt_compat_netbsd.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/acct.h>
+#include <sys/kernel.h>
+#include <sys/signalvar.h>
+#include <sys/resourcevar.h>
+#include <sys/syscall.h>
+#include <sys/syslog.h>
+#include <sys/user.h>
+#ifdef KTRACE
+#include <sys/ktrace.h>
+#endif
+
+#include <machine/psl.h>
+#include <machine/trap.h>
+#include <machine/cpu.h>
+#include <machine/reg.h>
+#include <machine/db_machdep.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <uvm/uvm_extern.h>
+
+#include <dev/cons.h>
+
+int writeback __P((struct frame *fp, int docachepush));
+void trap __P((int type, u_int code, u_int v, struct frame frame));
+void syscall __P((register_t code, struct frame frame));
+
+#if defined(M68040)
+#ifdef DEBUG
+static void dumpssw __P((u_short));
+static void dumpwb __P((int, u_short, u_int, u_int));
+#endif
+#endif
+
+static inline void userret __P((struct proc *p, struct frame *fp,
+ u_quad_t oticks, u_int faultaddr, int fromtrap));
+
+int astpending;
+
+char *trap_type[] = {
+ "Bus error",
+ "Address error",
+ "Illegal instruction",
+ "Zero divide",
+ "CHK instruction",
+ "TRAPV instruction",
+ "Privilege violation",
+ "Trace trap",
+ "MMU fault",
+ "SSIR trap",
+ "Format error",
+ "68881 exception",
+ "Coprocessor violation",
+ "Async system trap"
+};
+int trap_types = sizeof trap_type / sizeof trap_type[0];
+
+/*
+ * Size of various exception stack frames (minus the standard 8 bytes)
+ */
+short exframesize[] = {
+ FMT0SIZE, /* type 0 - normal (68020/030/040) */
+ FMT1SIZE, /* type 1 - throwaway (68020/030/040) */
+ FMT2SIZE, /* type 2 - normal 6-word (68020/030/040) */
+ FMT3SIZE, /* type 3 - FP post-instruction (68040) */
+ -1, -1, -1, /* type 4-6 - undefined */
+ FMT7SIZE, /* type 7 - access error (68040) */
+ 58, /* type 8 - bus fault (68010) */
+ FMT9SIZE, /* type 9 - coprocessor mid-instruction (68020/030) */
+ FMTASIZE, /* type A - short bus fault (68020/030) */
+ FMTBSIZE, /* type B - long bus fault (68020/030) */
+ -1, -1, -1, -1 /* type C-F - undefined */
+};
+
+#ifdef M68040
+#define KDFAULT(c) (mmutype == MMU_68040 ? \
+ ((c) & SSW4_TMMASK) == SSW4_TMKD : \
+ ((c) & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD))
+#define WRFAULT(c) (mmutype == MMU_68040 ? \
+ ((c) & SSW4_RW) == 0 : \
+ ((c) & (SSW_DF|SSW_RW)) == SSW_DF)
+#else
+#define KDFAULT(c) (((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
+#define WRFAULT(c) (((c) & (SSW_DF|SSW_RW)) == SSW_DF)
+#endif
+
+#ifdef DEBUG
+int mmudebug = 0;
+int mmupid = -1;
+#define MDB_FOLLOW 1
+#define MDB_WBFOLLOW 2
+#define MDB_WBFAILED 4
+#define MDB_ISPID(p) ((p) == mmupid)
+#endif
+
+/*
+ * trap and syscall both need the following work done before returning
+ * to user mode.
+ */
+static inline void
+userret(p, fp, oticks, faultaddr, fromtrap)
+ struct proc *p;
+ struct frame *fp;
+ u_quad_t oticks;
+ u_int faultaddr;
+ int fromtrap;
+{
+ int sig, s;
+#ifdef M68040
+ int beenhere = 0;
+
+again:
+#endif
+ /* take pending signals */
+ while ((sig = CURSIG(p)) != 0)
+ postsig(sig);
+ p->p_priority = p->p_usrpri;
+ if (want_resched) {
+ /*
+ * Since we are curproc, clock will normally just change
+ * our priority without moving us from one queue to another
+ * (since the running process is not on a queue.)
+ * If that happened after we put ourselves on the run queue
+ * but before we mi_switch()'ed, we might not be on the queue
+ * indicated by our priority.
+ */
+ s = splstatclock();
+ setrunqueue(p);
+ p->p_stats->p_ru.ru_nivcsw++;
+ mi_switch();
+ splx(s);
+ while ((sig = CURSIG(p)) != 0)
+ postsig(sig);
+ }
+
+ /*
+ * If profiling, charge system time to the trapped pc.
+ */
+ if (p->p_flag & P_PROFIL) {
+ extern int psratio;
+
+ addupc_task(p, fp->f_pc,
+ (int)(p->p_sticks - oticks) * psratio);
+ }
+#ifdef M68040
+ /*
+ * Deal with user mode writebacks (from trap, or from sigreturn).
+ * If any writeback fails, go back and attempt signal delivery.
+ * unless we have already been here and attempted the writeback
+ * (e.g. bad address with user ignoring SIGSEGV). In that case
+ * we just return to the user without sucessfully completing
+ * the writebacks. Maybe we should just drop the sucker?
+ */
+ if (cputype == CPU_68040 && fp->f_format == FMT7) {
+ if (beenhere) {
+#ifdef DEBUG
+ if (mmudebug & MDB_WBFAILED)
+ printf(fromtrap ?
+ "pid %d(%s): writeback aborted, pc=%x, fa=%x\n" :
+ "pid %d(%s): writeback aborted in sigreturn, pc=%x\n",
+ p->p_pid, p->p_comm, fp->f_pc, faultaddr);
+#endif
+ } else if ((sig = writeback(fp, fromtrap))) {
+ beenhere = 1;
+ oticks = p->p_sticks;
+ trapsignal(p, sig, faultaddr);
+ goto again;
+ }
+ }
+#endif
+ curpriority = p->p_priority;
+}
+
+/*
+ * Trap is called from locore to handle most types of processor traps,
+ * including events such as simulated software interrupts/AST's.
+ * System calls are broken out for efficiency.
+ */
+/*ARGSUSED*/
+void
+trap(type, code, v, frame)
+ int type;
+ unsigned code;
+ unsigned v;
+ struct frame frame;
+{
+ extern char fubail[], subail[];
+#ifdef DDB
+ extern char trap0[], trap1[], trap2[], trap12[], trap15[], illinst[];
+#endif
+ struct proc *p;
+ int i;
+ u_int ucode;
+ u_quad_t sticks = 0 /* XXX initializer works around compiler bug */;
+
+ uvmexp.traps++;
+ p = curproc;
+ ucode = 0;
+
+ /* I have verified that this DOES happen! -gwr */
+ if (p == NULL)
+ p = &proc0;
+#ifdef DIAGNOSTIC
+ if (p->p_addr == NULL)
+ panic("trap: no pcb");
+#endif
+
+ if (USERMODE(frame.f_sr)) {
+ type |= T_USER;
+ sticks = p->p_sticks;
+ p->p_md.md_regs = frame.f_regs;
+ }
+ switch (type) {
+
+ default:
+ dopanic:
+ printf("trap type %d, code = 0x%x, v = 0x%x\n", type, code, v);
+#ifdef DDB
+ if (kdb_trap(type, (db_regs_t *)&frame))
+ return;
+#endif
+ printf("%s program counter = 0x%x\n",
+ (type & T_USER) ? "user" : "kernel", frame.f_pc);
+ regdump((struct trapframe *)&frame, 128);
+ type &= ~T_USER;
+ if ((u_int)type < trap_types)
+ panic(trap_type[type]);
+ panic("trap");
+
+ case T_BUSERR: /* kernel bus error */
+ if (p->p_addr->u_pcb.pcb_onfault == 0)
+ goto dopanic;
+ /* FALLTHROUGH */
+
+ copyfault:
+ /*
+ * If we have arranged to catch this fault in any of the
+ * copy to/from user space routines, set PC to return to
+ * indicated location and set flag informing buserror code
+ * that it may need to clean up stack frame.
+ */
+ frame.f_stackadj = exframesize[frame.f_format];
+ frame.f_format = frame.f_vector = 0;
+ frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault;
+ return;
+
+ case T_BUSERR|T_USER: /* bus error */
+ case T_ADDRERR|T_USER: /* address error */
+ ucode = v;
+ i = SIGBUS;
+ break;
+
+ case T_COPERR: /* kernel coprocessor violation */
+ case T_FMTERR|T_USER: /* do all RTE errors come in as T_USER? */
+ case T_FMTERR: /* ...just in case... */
+ /*
+ * The user has most likely trashed the RTE or FP state info
+ * in the stack frame of a signal handler.
+ */
+ printf("pid %d: kernel %s exception\n", p->p_pid,
+ type==T_COPERR ? "coprocessor" : "format");
+ type |= T_USER;
+ p->p_sigacts->ps_sigact[SIGILL].sa_handler = SIG_DFL;
+ sigdelset(&p->p_sigignore, SIGILL);
+ sigdelset(&p->p_sigcatch, SIGILL);
+ sigdelset(&p->p_sigmask, SIGILL);
+ i = SIGILL;
+ ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */
+ break;
+
+ case T_COPERR|T_USER: /* user coprocessor violation */
+ /* What is a proper response here? */
+ ucode = 0;
+ i = SIGFPE;
+ break;
+
+ case T_FPERR|T_USER: /* 68881 exceptions */
+ /*
+ * We pass along the 68881 status register which locore stashed
+ * in code for us. Note that there is a possibility that the
+ * bit pattern of this register will conflict with one of the
+ * FPE_* codes defined in signal.h. Fortunately for us, the
+ * only such codes we use are all in the range 1-7 and the low
+ * 3 bits of the status register are defined as 0 so there is
+ * no clash.
+ */
+ ucode = code;
+ i = SIGFPE;
+ break;
+
+#ifdef M68040
+ case T_FPEMULI|T_USER: /* unimplemented FP instuction */
+ case T_FPEMULD|T_USER: /* unimplemented FP data type */
+ /* XXX need to FSAVE */
+ printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n",
+ p->p_pid, p->p_comm,
+ frame.f_format == 2 ? "instruction" : "data type",
+ frame.f_pc, frame.f_fmt2.f_iaddr);
+ /* XXX need to FRESTORE */
+ i = SIGFPE;
+ break;
+#endif
+
+ case T_ILLINST|T_USER: /* illegal instruction fault */
+#ifdef COMPAT_HPUX
+ if (p->p_emul == &emul_hpux) {
+ ucode = HPUX_ILL_ILLINST_TRAP;
+ i = SIGILL;
+ break;
+ }
+ /* fall through */
+#endif
+ case T_PRIVINST|T_USER: /* privileged instruction fault */
+#ifdef COMPAT_HPUX
+ if (p->p_emul == &emul_hpux)
+ ucode = HPUX_ILL_PRIV_TRAP;
+ else
+#endif
+ ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */
+ i = SIGILL;
+ break;
+
+ case T_ZERODIV|T_USER: /* Divide by zero */
+ ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */
+ i = SIGFPE;
+ break;
+
+ case T_CHKINST|T_USER: /* CHK instruction trap */
+ ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */
+ i = SIGFPE;
+ break;
+
+ case T_TRAPVINST|T_USER: /* TRAPV instruction trap */
+ ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */
+ i = SIGFPE;
+ break;
+
+ /*
+ * XXX: Trace traps are a nightmare.
+ *
+ * HP-UX uses trap #1 for breakpoints,
+ * HPBSD uses trap #2,
+ * SUN 3.x uses trap #15,
+ * KGDB uses trap #15 (for kernel breakpoints; handled elsewhere).
+ *
+ * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
+ * SUN 3.x traps get passed through as T_TRAP15 and are not really
+ * supported yet.
+ */
+ case T_TRACE: /* kernel trace trap */
+ case T_TRAP15: /* SUN trace trap */
+#ifdef DDB
+ if (type == T_TRAP15 ||
+ ((caddr_t)frame.f_pc != trap0 &&
+ (caddr_t)frame.f_pc != trap1 &&
+ (caddr_t)frame.f_pc != trap2 &&
+ (caddr_t)frame.f_pc != trap12 &&
+ (caddr_t)frame.f_pc != trap15 &&
+ (caddr_t)frame.f_pc != illinst)) {
+ if (kdb_trap(type, (db_regs_t *)&frame))
+ return;
+ }
+#endif
+ frame.f_sr &= ~PSL_T;
+ i = SIGTRAP;
+ break;
+
+ case T_TRACE|T_USER: /* user trace trap */
+ case T_TRAP15|T_USER: /* SUN user trace trap */
+ frame.f_sr &= ~PSL_T;
+ i = SIGTRAP;
+ break;
+
+ case T_ASTFLT: /* system async trap, cannot happen */
+ goto dopanic;
+
+ case T_ASTFLT|T_USER: /* user async trap */
+ astpending = 0;
+ /*
+ * We check for software interrupts first. This is because
+ * they are at a higher level than ASTs, and on a VAX would
+ * interrupt the AST. We assume that if we are processing
+ * an AST that we must be at IPL0 so we don't bother to
+ * check. Note that we ensure that we are at least at SIR
+ * IPL while processing the SIR.
+ */
+ spl1();
+ /* fall into... */
+
+ case T_SSIR: /* software interrupt */
+ case T_SSIR|T_USER:
+ if (ssir & SIR_NET) {
+ void netintr __P((void));
+ siroff(SIR_NET);
+ uvmexp.softs++;
+ netintr();
+ }
+ if (ssir & SIR_CLOCK) {
+ siroff(SIR_CLOCK);
+ uvmexp.softs++;
+ softclock();
+ }
+ /*
+ * If this was not an AST trap, we are all done.
+ */
+ if (type != (T_ASTFLT|T_USER)) {
+ uvmexp.traps--;
+ return;
+ }
+ spl0();
+ if (p->p_flag & P_OWEUPC) {
+ p->p_flag &= ~P_OWEUPC;
+ ADDUPROF(p);
+ }
+ goto out;
+
+ case T_MMUFLT: /* kernel mode page fault */
+ /*
+ * If we were doing profiling ticks or other user mode
+ * stuff from interrupt code, Just Say No.
+ */
+ if (p->p_addr->u_pcb.pcb_onfault == fubail ||
+ p->p_addr->u_pcb.pcb_onfault == subail)
+ goto copyfault;
+ /* fall into ... */
+
+ case T_MMUFLT|T_USER: /* page fault */
+ {
+ vaddr_t va;
+ struct vmspace *vm = p->p_vmspace;
+ vm_map_t map;
+ int rv;
+ vm_prot_t ftype;
+ extern vm_map_t kernel_map;
+
+#ifdef DEBUG
+ if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
+ printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n",
+ p->p_pid, code, v, frame.f_pc, frame.f_sr);
+#endif
+ /*
+ * It is only a kernel address space fault iff:
+ * 1. (type & T_USER) == 0 and
+ * 2. pcb_onfault not set or
+ * 3. pcb_onfault set but supervisor space data fault
+ * The last can occur during an exec() copyin where the
+ * argument space is lazy-allocated.
+ */
+ if ((type & T_USER) == 0 &&
+ ((p->p_addr->u_pcb.pcb_onfault == 0) || KDFAULT(code)))
+ map = kernel_map;
+ else
+ map = vm ? &vm->vm_map : kernel_map;
+
+ if (WRFAULT(code))
+ ftype = VM_PROT_READ | VM_PROT_WRITE;
+ else
+ ftype = VM_PROT_READ;
+
+ va = trunc_page((vaddr_t)v);
+
+ if (map == kernel_map && va == 0) {
+ printf("trap: bad kernel %s access at 0x%x\n",
+ (ftype & VM_PROT_WRITE) ? "read/write" :
+ "read", v);
+ goto dopanic;
+ }
+
+ rv = uvm_fault(map, va, 0, ftype);
+#ifdef DEBUG
+ if (rv && MDB_ISPID(p->p_pid))
+ printf("uvm_fault(%p, 0x%lx, 0, 0x%x) -> 0x%x\n",
+ map, va, ftype, rv);
+#endif
+ /*
+ * If this was a stack access we keep track of the maximum
+ * accessed stack size. Also, if vm_fault gets a protection
+ * failure it is due to accessing the stack region outside
+ * the current limit and we need to reflect that as an access
+ * error.
+ */
+ if ((vm != NULL && (caddr_t)va >= vm->vm_maxsaddr)
+ && map != kernel_map) {
+ if (rv == KERN_SUCCESS) {
+ unsigned nss;
+
+ nss = btoc(USRSTACK-(unsigned)va);
+ if (nss > vm->vm_ssize)
+ vm->vm_ssize = nss;
+ } else if (rv == KERN_PROTECTION_FAILURE)
+ rv = KERN_INVALID_ADDRESS;
+ }
+ if (rv == KERN_SUCCESS) {
+ if (type == T_MMUFLT) {
+#ifdef M68040
+ if (cputype == CPU_68040)
+ (void) writeback(&frame, 1);
+#endif
+ return;
+ }
+ goto out;
+ }
+ if (type == T_MMUFLT) {
+ if (p->p_addr->u_pcb.pcb_onfault)
+ goto copyfault;
+ printf("uvm_fault(%p, 0x%lx, 0, 0x%x) -> 0x%x\n",
+ map, va, ftype, rv);
+ printf(" type %x, code [mmu,,ssw]: %x\n",
+ type, code);
+ goto dopanic;
+ }
+ ucode = v;
+ if (rv == KERN_RESOURCE_SHORTAGE) {
+ printf("UVM: pid %d (%s), uid %d killed: out of swap\n",
+ p->p_pid, p->p_comm,
+ p->p_cred && p->p_ucred ?
+ p->p_ucred->cr_uid : -1);
+ i = SIGKILL;
+ } else {
+ i = SIGSEGV;
+ }
+ break;
+ }
+ }
+ if (i)
+ trapsignal(p, i, ucode);
+ if ((type & T_USER) == 0)
+ return;
+out:
+ userret(p, &frame, sticks, v, 1);
+}
+
+#ifdef M68040
+#ifdef DEBUG
+struct writebackstats {
+ int calls;
+ int cpushes;
+ int move16s;
+ int wb1s, wb2s, wb3s;
+ int wbsize[4];
+} wbstats;
+
+char *f7sz[] = { "longword", "byte", "word", "line" };
+char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK" };
+char *f7tm[] = { "d-push", "u-data", "u-code", "M-data",
+ "M-code", "k-data", "k-code", "RES" };
+char wberrstr[] =
+ "WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n";
+#endif
+
+int
+writeback(fp, docachepush)
+ struct frame *fp;
+ int docachepush;
+{
+ struct fmt7 *f = &fp->f_fmt7;
+ struct proc *p = curproc;
+ int err = 0;
+ u_int fa;
+ caddr_t oonfault = p->p_addr->u_pcb.pcb_onfault;
+
+#ifdef DEBUG
+ if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) {
+ printf(" pid=%d, fa=%x,", p->p_pid, f->f_fa);
+ dumpssw(f->f_ssw);
+ }
+ wbstats.calls++;
+#endif
+ /*
+ * Deal with special cases first.
+ */
+ if ((f->f_ssw & SSW4_TMMASK) == SSW4_TMDCP) {
+ /*
+ * Dcache push fault.
+ * Line-align the address and write out the push data to
+ * the indicated physical address.
+ */
+#ifdef DEBUG
+ if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) {
+ printf(" pushing %s to PA %x, data %x",
+ f7sz[(f->f_ssw & SSW4_SZMASK) >> 5],
+ f->f_fa, f->f_pd0);
+ if ((f->f_ssw & SSW4_SZMASK) == SSW4_SZLN)
+ printf("/%x/%x/%x",
+ f->f_pd1, f->f_pd2, f->f_pd3);
+ printf("\n");
+ }
+ if (f->f_wb1s & SSW4_WBSV)
+ panic("writeback: cache push with WB1S valid");
+ wbstats.cpushes++;
+#endif
+ /*
+ * XXX there are security problems if we attempt to do a
+ * cache push after a signal handler has been called.
+ */
+ if (docachepush) {
+ pmap_enter(pmap_kernel(), (vaddr_t)vmmap,
+ trunc_page(f->f_fa), VM_PROT_WRITE, TRUE,
+ VM_PROT_WRITE);
+ fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF];
+ bcopy((caddr_t)&f->f_pd0, (caddr_t)fa, 16);
+ DCFL(pmap_extract(pmap_kernel(), (paddr_t)fa));
+ pmap_remove(pmap_kernel(), (vaddr_t)vmmap,
+ (vaddr_t)&vmmap[NBPG]);
+ } else
+ printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n",
+ p->p_pid, p->p_comm, p->p_ucred->cr_uid);
+ } else if ((f->f_ssw & (SSW4_RW|SSW4_TTMASK)) == SSW4_TTM16) {
+ /*
+ * MOVE16 fault.
+ * Line-align the address and write out the push data to
+ * the indicated virtual address.
+ */
+#ifdef DEBUG
+ if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
+ printf(" MOVE16 to VA %x(%x), data %x/%x/%x/%x\n",
+ f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1,
+ f->f_pd2, f->f_pd3);
+ if (f->f_wb1s & SSW4_WBSV)
+ panic("writeback: MOVE16 with WB1S valid");
+ wbstats.move16s++;
+#endif
+ if (KDFAULT(f->f_wb1s))
+ bcopy((caddr_t)&f->f_pd0, (caddr_t)(f->f_fa & ~0xF), 16);
+ else
+ err = suline((caddr_t)(f->f_fa & ~0xF), (caddr_t)&f->f_pd0);
+ if (err) {
+ fa = f->f_fa & ~0xF;
+#ifdef DEBUG
+ if (mmudebug & MDB_WBFAILED)
+ printf(wberrstr, p->p_pid, p->p_comm,
+ "MOVE16", fp->f_pc, f->f_fa,
+ f->f_fa & ~0xF, f->f_pd0);
+#endif
+ }
+ } else if (f->f_wb1s & SSW4_WBSV) {
+ /*
+ * Writeback #1.
+ * Position the "memory-aligned" data and write it out.
+ */
+ u_int wb1d = f->f_wb1d;
+ int off;
+
+#ifdef DEBUG
+ if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
+ dumpwb(1, f->f_wb1s, f->f_wb1a, f->f_wb1d);
+ wbstats.wb1s++;
+ wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++;
+#endif
+ off = (f->f_wb1a & 3) * 8;
+ switch (f->f_wb1s & SSW4_SZMASK) {
+ case SSW4_SZLW:
+ if (off)
+ wb1d = (wb1d >> (32 - off)) | (wb1d << off);
+ if (KDFAULT(f->f_wb1s))
+ *(long *)f->f_wb1a = wb1d;
+ else
+ err = suword((caddr_t)f->f_wb1a, wb1d);
+ break;
+ case SSW4_SZB:
+ off = 24 - off;
+ if (off)
+ wb1d >>= off;
+ if (KDFAULT(f->f_wb1s))
+ *(char *)f->f_wb1a = wb1d;
+ else
+ err = subyte((caddr_t)f->f_wb1a, wb1d);
+ break;
+ case SSW4_SZW:
+ off = (off + 16) % 32;
+ if (off)
+ wb1d = (wb1d >> (32 - off)) | (wb1d << off);
+ if (KDFAULT(f->f_wb1s))
+ *(short *)f->f_wb1a = wb1d;
+ else
+ err = susword((caddr_t)f->f_wb1a, wb1d);
+ break;
+ }
+ if (err) {
+ fa = f->f_wb1a;
+#ifdef DEBUG
+ if (mmudebug & MDB_WBFAILED)
+ printf(wberrstr, p->p_pid, p->p_comm,
+ "#1", fp->f_pc, f->f_fa,
+ f->f_wb1a, f->f_wb1d);
+#endif
+ }
+ }
+ /*
+ * Deal with the "normal" writebacks.
+ *
+ * XXX writeback2 is known to reflect a LINE size writeback after
+ * a MOVE16 was already dealt with above. Ignore it.
+ */
+ if (err == 0 && (f->f_wb2s & SSW4_WBSV) &&
+ (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) {
+#ifdef DEBUG
+ if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
+ dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d);
+ wbstats.wb2s++;
+ wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++;
+#endif
+ switch (f->f_wb2s & SSW4_SZMASK) {
+ case SSW4_SZLW:
+ if (KDFAULT(f->f_wb2s))
+ *(long *)f->f_wb2a = f->f_wb2d;
+ else
+ err = suword((caddr_t)f->f_wb2a, f->f_wb2d);
+ break;
+ case SSW4_SZB:
+ if (KDFAULT(f->f_wb2s))
+ *(char *)f->f_wb2a = f->f_wb2d;
+ else
+ err = subyte((caddr_t)f->f_wb2a, f->f_wb2d);
+ break;
+ case SSW4_SZW:
+ if (KDFAULT(f->f_wb2s))
+ *(short *)f->f_wb2a = f->f_wb2d;
+ else
+ err = susword((caddr_t)f->f_wb2a, f->f_wb2d);
+ break;
+ }
+ if (err) {
+ fa = f->f_wb2a;
+#ifdef DEBUG
+ if (mmudebug & MDB_WBFAILED) {
+ printf(wberrstr, p->p_pid, p->p_comm,
+ "#2", fp->f_pc, f->f_fa,
+ f->f_wb2a, f->f_wb2d);
+ dumpssw(f->f_ssw);
+ dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d);
+ }
+#endif
+ }
+ }
+ if (err == 0 && (f->f_wb3s & SSW4_WBSV)) {
+#ifdef DEBUG
+ if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
+ dumpwb(3, f->f_wb3s, f->f_wb3a, f->f_wb3d);
+ wbstats.wb3s++;
+ wbstats.wbsize[(f->f_wb3s&SSW4_SZMASK)>>5]++;
+#endif
+ switch (f->f_wb3s & SSW4_SZMASK) {
+ case SSW4_SZLW:
+ if (KDFAULT(f->f_wb3s))
+ *(long *)f->f_wb3a = f->f_wb3d;
+ else
+ err = suword((caddr_t)f->f_wb3a, f->f_wb3d);
+ break;
+ case SSW4_SZB:
+ if (KDFAULT(f->f_wb3s))
+ *(char *)f->f_wb3a = f->f_wb3d;
+ else
+ err = subyte((caddr_t)f->f_wb3a, f->f_wb3d);
+ break;
+ case SSW4_SZW:
+ if (KDFAULT(f->f_wb3s))
+ *(short *)f->f_wb3a = f->f_wb3d;
+ else
+ err = susword((caddr_t)f->f_wb3a, f->f_wb3d);
+ break;
+#ifdef DEBUG
+ case SSW4_SZLN:
+ panic("writeback: wb3s indicates LINE write");
+#endif
+ }
+ if (err) {
+ fa = f->f_wb3a;
+#ifdef DEBUG
+ if (mmudebug & MDB_WBFAILED)
+ printf(wberrstr, p->p_pid, p->p_comm,
+ "#3", fp->f_pc, f->f_fa,
+ f->f_wb3a, f->f_wb3d);
+#endif
+ }
+ }
+ p->p_addr->u_pcb.pcb_onfault = oonfault;
+ if (err)
+ err = SIGSEGV;
+ return (err);
+}
+
+#ifdef DEBUG
+static void
+dumpssw(ssw)
+ u_short ssw;
+{
+ printf(" SSW: %x: ", ssw);
+ if (ssw & SSW4_CP)
+ printf("CP,");
+ if (ssw & SSW4_CU)
+ printf("CU,");
+ if (ssw & SSW4_CT)
+ printf("CT,");
+ if (ssw & SSW4_CM)
+ printf("CM,");
+ if (ssw & SSW4_MA)
+ printf("MA,");
+ if (ssw & SSW4_ATC)
+ printf("ATC,");
+ if (ssw & SSW4_LK)
+ printf("LK,");
+ if (ssw & SSW4_RW)
+ printf("RW,");
+ printf(" SZ=%s, TT=%s, TM=%s\n",
+ f7sz[(ssw & SSW4_SZMASK) >> 5],
+ f7tt[(ssw & SSW4_TTMASK) >> 3],
+ f7tm[ssw & SSW4_TMMASK]);
+}
+
+static void
+dumpwb(num, s, a, d)
+ int num;
+ u_short s;
+ u_int a, d;
+{
+ struct proc *p = curproc;
+ paddr_t pa;
+
+ printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n",
+ num, a, d, f7sz[(s & SSW4_SZMASK) >> 5],
+ f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]);
+ printf(" PA ");
+ pa = pmap_extract(p->p_vmspace->vm_map.pmap, (paddr_t)a);
+ if (pa == 0)
+ printf("<invalid address>");
+ else
+ printf("%lx, current value %lx", pa, fuword((caddr_t)a));
+ printf("\n");
+}
+#endif
+#endif
+
+/*
+ * Process a system call.
+ */
+void
+syscall(code, frame)
+ register_t code;
+ struct frame frame;
+{
+ caddr_t params;
+ struct sysent *callp;
+ struct proc *p;
+ int error, opc, nsys;
+ size_t argsize;
+ register_t args[8], rval[2];
+ u_quad_t sticks;
+
+ uvmexp.syscalls++;
+ if (!USERMODE(frame.f_sr))
+ panic("syscall");
+ p = curproc;
+ sticks = p->p_sticks;
+ p->p_md.md_regs = frame.f_regs;
+ opc = frame.f_pc;
+
+ nsys = p->p_emul->e_nsysent;
+ callp = p->p_emul->e_sysent;
+
+#ifdef COMPAT_SUNOS
+ if (p->p_emul == &emul_sunos) {
+ /*
+ * SunOS passes the syscall-number on the stack, whereas
+ * BSD passes it in D0. So, we have to get the real "code"
+ * from the stack, and clean up the stack, as SunOS glue
+ * code assumes the kernel pops the syscall argument the
+ * glue pushed on the stack. Sigh...
+ */
+ code = fuword((caddr_t)frame.f_regs[SP]);
+
+ /*
+ * XXX
+ * Don't do this for sunos_sigreturn, as there's no stored pc
+ * on the stack to skip, the argument follows the syscall
+ * number without a gap.
+ */
+ if (code != SUNOS_SYS_sigreturn) {
+ frame.f_regs[SP] += sizeof (int);
+ /*
+ * remember that we adjusted the SP,
+ * might have to undo this if the system call
+ * returns ERESTART.
+ */
+ p->p_md.md_flags |= MDP_STACKADJ;
+ } else
+ p->p_md.md_flags &= ~MDP_STACKADJ;
+ }
+#endif
+
+ params = (caddr_t)frame.f_regs[SP] + sizeof(int);
+
+ switch (code) {
+ case SYS_syscall:
+ /*
+ * Code is first argument, followed by actual args.
+ */
+ code = fuword(params);
+ params += sizeof(int);
+ /*
+ * XXX sigreturn requires special stack manipulation
+ * that is only done if entered via the sigreturn
+ * trap. Cannot allow it here so make sure we fail.
+ */
+ switch (code) {
+#ifdef COMPAT_13
+ case SYS_compat_13_sigreturn13:
+#endif
+ case SYS___sigreturn14:
+ code = nsys;
+ break;
+ }
+ break;
+ case SYS___syscall:
+ /*
+ * Like syscall, but code is a quad, so as to maintain
+ * quad alignment for the rest of the arguments.
+ */
+ if (callp != sysent)
+ break;
+ code = fuword(params + _QUAD_LOWWORD * sizeof(int));
+ params += sizeof(quad_t);
+ break;
+ default:
+ break;
+ }
+ if (code < 0 || code >= nsys)
+ callp += p->p_emul->e_nosys; /* illegal */
+ else
+ callp += code;
+ argsize = callp->sy_argsize;
+ if (argsize)
+ error = copyin(params, (caddr_t)args, argsize);
+ else
+ error = 0;
+#ifdef SYSCALL_DEBUG
+ scdebug_call(p, code, args);
+#endif
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSCALL))
+ ktrsyscall(p->p_tracep, code, argsize, args);
+#endif
+ if (error)
+ goto bad;
+ rval[0] = 0;
+ rval[1] = frame.f_regs[D1];
+ error = (*callp->sy_call)(p, args, rval);
+ switch (error) {
+ case 0:
+ frame.f_regs[D0] = rval[0];
+ frame.f_regs[D1] = rval[1];
+ frame.f_sr &= ~PSL_C; /* carry bit */
+ break;
+ case ERESTART:
+ /*
+ * We always enter through a `trap' instruction, which is 2
+ * bytes, so adjust the pc by that amount.
+ */
+ frame.f_pc = opc - 2;
+ break;
+ case EJUSTRETURN:
+ /* nothing to do */
+ break;
+ default:
+ bad:
+ if (p->p_emul->e_errno)
+ error = p->p_emul->e_errno[error];
+ frame.f_regs[D0] = error;
+ frame.f_sr |= PSL_C; /* carry bit */
+ break;
+ }
+
+#ifdef SYSCALL_DEBUG
+ scdebug_ret(p, code, error, rval);
+#endif
+#ifdef COMPAT_SUNOS
+ /* need new p-value for this */
+ if (error == ERESTART && (p->p_md.md_flags & MDP_STACKADJ))
+ frame.f_regs[SP] -= sizeof (int);
+#endif
+ userret(p, &frame, sticks, (u_int)0, 0);
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSRET))
+ ktrsysret(p->p_tracep, code, error, rval[0]);
+#endif
+}
+
+void
+child_return(arg)
+ void *arg;
+{
+ struct proc *p = arg;
+ /* See cpu_fork() */
+ struct frame *f = (struct frame *)p->p_md.md_regs;
+
+ f->f_regs[D0] = 0;
+ f->f_sr &= ~PSL_C;
+ f->f_format = FMT0;
+
+ userret(p, f, 0, (u_int)0, 0);
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSRET))
+ ktrsysret(p->p_tracep, SYS_fork, 0, 0);
+#endif
+}
diff --git a/sys/arch/luna68k/luna68k/vectors.s b/sys/arch/luna68k/luna68k/vectors.s
new file mode 100644
index 00000000000..7f4ccabb894
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/vectors.s
@@ -0,0 +1,134 @@
+| $NetBSD: vectors.s,v 1.1 2000/01/05 08:49:04 nisimura Exp $
+
+| Copyright (c) 1997 Jason R. Thorpe. All rights reserved.
+| Copyright (c) 1988 University of Utah
+| 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.
+|
+| @(#)vectors.s 8.2 (Berkeley) 1/21/94
+|
+
+#define BADTRAP16 \
+ VECTOR(badtrap) ; VECTOR(badtrap) ; \
+ VECTOR(badtrap) ; VECTOR(badtrap) ; \
+ VECTOR(badtrap) ; VECTOR(badtrap) ; \
+ VECTOR(badtrap) ; VECTOR(badtrap) ; \
+ VECTOR(badtrap) ; VECTOR(badtrap) ; \
+ VECTOR(badtrap) ; VECTOR(badtrap) ; \
+ VECTOR(badtrap) ; VECTOR(badtrap) ; \
+ VECTOR(badtrap) ; VECTOR(badtrap)
+
+ /*
+ * bus error and address error vectors are initialized
+ * in locore.s once we know our CPU type.
+ */
+
+ .data
+GLOBAL(vectab)
+ VECTOR_UNUSED /* 0: (unused reset SSP) */
+ VECTOR_UNUSED /* 1: NOT USED (reset PC) */
+ VECTOR_UNUSED /* 2: bus error */
+ VECTOR_UNUSED /* 3: address error */
+ VECTOR(illinst) /* 4: illegal instruction */
+ VECTOR(zerodiv) /* 5: zero divide */
+ VECTOR(chkinst) /* 6: CHK instruction */
+ VECTOR(trapvinst) /* 7: TRAPV instruction */
+ VECTOR(privinst) /* 8: privilege violation */
+ VECTOR(trace) /* 9: trace */
+ VECTOR(illinst) /* 10: line 1010 emulator */
+ VECTOR(fpfline) /* 11: line 1111 emulator */
+ VECTOR(badtrap) /* 12: unassigned, reserved */
+ VECTOR(coperr) /* 13: coprocessor protocol violation */
+ VECTOR(fmterr) /* 14: format error */
+ VECTOR(badtrap) /* 15: uninitialized interrupt vector */
+ VECTOR(badtrap) /* 16: unassigned, reserved */
+ VECTOR(badtrap) /* 17: unassigned, reserved */
+ VECTOR(badtrap) /* 18: unassigned, reserved */
+ VECTOR(badtrap) /* 19: unassigned, reserved */
+ VECTOR(badtrap) /* 20: unassigned, reserved */
+ VECTOR(badtrap) /* 21: unassigned, reserved */
+ VECTOR(badtrap) /* 22: unassigned, reserved */
+ VECTOR(badtrap) /* 23: unassigned, reserved */
+ VECTOR(spurintr) /* 24: spurious interrupt */
+ VECTOR(intrhand_autovec)/* 25: level 1 interrupt autovector */
+ VECTOR(intrhand_autovec)/* 26: level 2 interrupt autovector */
+ VECTOR(intrhand_autovec)/* 27: level 3 interrupt autovector */
+ VECTOR(intrhand_autovec)/* 28: level 4 interrupt autovector */
+ VECTOR(lev5intr) /* 29: level 5 interrupt hardwired */
+ VECTOR(intrhand_autovec)/* 30: level 6 interrupt autovector */
+ VECTOR(lev7intr) /* 31: level 7 interrupt hardwired */
+ VECTOR(trap0) /* 32: syscalls */
+#ifdef COMPAT_13
+ VECTOR(trap1) /* 33: compat_13_sigreturn */
+#else
+ VECTOR(illinst)
+#endif
+ VECTOR(trap2) /* 34: trace */
+ VECTOR(trap3) /* 35: sigreturn special syscall */
+ VECTOR(illinst) /* 36: TRAP instruction vector */
+ VECTOR(illinst) /* 37: TRAP instruction vector */
+ VECTOR(illinst) /* 38: TRAP instruction vector */
+ VECTOR(illinst) /* 39: TRAP instruction vector */
+ VECTOR(illinst) /* 40: TRAP instruction vector */
+ VECTOR(illinst) /* 41: TRAP instruction vector */
+ VECTOR(illinst) /* 42: TRAP instruction vector */
+ VECTOR(illinst) /* 43: TRAP instruction vector */
+ VECTOR(trap12) /* 44: TRAP instruction vector */
+ VECTOR(illinst) /* 45: TRAP instruction vector */
+ VECTOR(illinst) /* 46: TRAP instruction vector */
+ VECTOR(trap15) /* 47: TRAP instruction vector */
+#ifdef FPSP
+ ASVECTOR(bsun) /* 48: FPCP branch/set on unordered cond */
+ ASVECTOR(inex) /* 49: FPCP inexact result */
+ ASVECTOR(dz) /* 50: FPCP divide by zero */
+ ASVECTOR(unfl) /* 51: FPCP underflow */
+ ASVECTOR(operr) /* 52: FPCP operand error */
+ ASVECTOR(ovfl) /* 53: FPCP overflow */
+ ASVECTOR(snan) /* 54: FPCP signalling NAN */
+#else
+ VECTOR(fpfault) /* 48: FPCP branch/set on unordered cond */
+ VECTOR(fpfault) /* 49: FPCP inexact result */
+ VECTOR(fpfault) /* 50: FPCP divide by zero */
+ VECTOR(fpfault) /* 51: FPCP underflow */
+ VECTOR(fpfault) /* 52: FPCP operand error */
+ VECTOR(fpfault) /* 53: FPCP overflow */
+ VECTOR(fpfault) /* 54: FPCP signalling NAN */
+#endif
+
+ VECTOR(fpunsupp) /* 55: FPCP unimplemented data type */
+ VECTOR(badtrap) /* 56: unassigned, reserved */
+ VECTOR(badtrap) /* 57: unassigned, reserved */
+ VECTOR(badtrap) /* 58: unassigned, reserved */
+ VECTOR(badtrap) /* 59: unassigned, reserved */
+ VECTOR(badtrap) /* 60: unassigned, reserved */
+ VECTOR(badtrap) /* 61: unassigned, reserved */
+ VECTOR(badtrap) /* 62: unassigned, reserved */
+ VECTOR(badtrap) /* 63: unassigned, reserved */
diff --git a/sys/arch/luna68k/luna68k/vm_machdep.c b/sys/arch/luna68k/luna68k/vm_machdep.c
new file mode 100644
index 00000000000..f041e01d3ba
--- /dev/null
+++ b/sys/arch/luna68k/luna68k/vm_machdep.c
@@ -0,0 +1,374 @@
+/* $NetBSD: vm_machdep.c,v 1.1 2000/01/05 08:49:04 nisimura Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.1 2000/01/05 08:49:04 nisimura 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.
+ *
+ * from: Utah $Hdr: vm_machdep.c 1.21 91/04/06$
+ *
+ * @(#)vm_machdep.c 8.6 (Berkeley) 1/12/94
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.1 2000/01/05 08:49:04 nisimura Exp $");
+
+#include "opt_compat_hpux.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/malloc.h>
+#include <sys/buf.h>
+#include <sys/vnode.h>
+#include <sys/user.h>
+#include <sys/core.h>
+#include <sys/exec.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/cpu.h>
+#include <machine/pte.h>
+#include <machine/reg.h>
+#include <m68k/cacheops.h>
+
+/*
+ * Finish a fork operation, with process p2 nearly set up. Copy and
+ * update the kernel stack and pcb, making the child ready to run,
+ * and marking it so that it can return differently than the parent.
+ * When scheduled, child p2 will start from proc_trampoline(). cpu_fork()
+ * returns once for forking parent p1.
+ */
+void
+cpu_fork(p1, p2, stack, stacksize)
+ struct proc *p1, *p2;
+ void *stack;
+ size_t stacksize;
+{
+ struct pcb *pcb = &p2->p_addr->u_pcb;
+ struct trapframe *tf;
+ struct switchframe *sf;
+ extern struct pcb *curpcb;
+
+ p2->p_md.md_flags = p1->p_md.md_flags & ~MDP_HPUXTRACE;
+
+ /* Copy pcb from proc p1 to p2. */
+ if (p1 == curproc) {
+ /* Sync the PCB before we copy it. */
+ savectx(curpcb);
+ }
+#ifdef DIAGNOSTIC
+ else if (p1 != &proc0)
+ panic("cpu_fork: curproc");
+#endif
+ *pcb = p1->p_addr->u_pcb;
+
+ /*
+ * Copy the trap frame, and arrange for the child to return directly
+ * through child_return(). Note the in-line cpu_set_kpc().
+ */
+ tf = (struct trapframe *)((u_int)p2->p_addr + USPACE) - 1;
+ p2->p_md.md_regs = (int *)tf;
+ *tf = *(struct trapframe *)p1->p_md.md_regs;
+
+ /*
+ * If specified, give the child a different stack.
+ */
+ if (stack != NULL)
+ tf->tf_regs[15] = (u_int)stack + stacksize;
+
+ sf = (struct switchframe *)tf - 1;
+ sf->sf_pc = (u_int)proc_trampoline;
+ pcb->pcb_regs[6] = (int)child_return; /* A2 */
+ pcb->pcb_regs[7] = (int)p2; /* A3 */
+ pcb->pcb_regs[11] = (int)sf; /* SSP */
+}
+
+/*
+ * Arrange for in-kernel execution of a process to continue at the
+ * named pc, as if the code at that address were called as a function
+ * with the supplied argument.
+ *
+ * Note that it's assumed that when the named process returns, rei()
+ * should be invoked, to return to user mode.
+ */
+void
+cpu_set_kpc(p, pc, arg)
+ struct proc *p;
+ void (*pc) __P((void *));
+ void *arg;
+{
+
+ p->p_addr->u_pcb.pcb_regs[6] = (u_long) pc; /* A2 */
+ p->p_addr->u_pcb.pcb_regs[7] = (u_long) arg; /* A3 */
+}
+
+/*
+ * cpu_exit is called as the last action during exit.
+ *
+ * Block context switches and then call switch_exit() which will
+ * switch to another process thus we never return.
+ */
+void
+cpu_exit(p)
+ struct proc *p;
+{
+
+ (void) splhigh();
+ uvmexp.swtch++;
+ switch_exit(p);
+ /* NOTREACHED */
+}
+
+/*
+ * Dump the machine specific header information at the start of a core dump.
+ */
+struct md_core {
+ struct reg intreg;
+ struct fpreg freg;
+};
+int
+cpu_coredump(p, vp, cred, chdr)
+ struct proc *p;
+ struct vnode *vp;
+ struct ucred *cred;
+ struct core *chdr;
+{
+ struct md_core md_core;
+ struct coreseg cseg;
+ int error;
+
+#ifdef COMPAT_HPUX
+ extern struct emul emul_hpux;
+
+ /*
+ * If we loaded from an HP-UX format binary file we dump enough
+ * of an HP-UX style user struct so that the HP-UX debuggers can
+ * grok it.
+ */
+ if (p->p_emul == &emul_hpux)
+ return (hpux_dumpu(vp, cred));
+#endif
+
+ CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0);
+ chdr->c_hdrsize = ALIGN(sizeof(*chdr));
+ chdr->c_seghdrsize = ALIGN(sizeof(cseg));
+ chdr->c_cpusize = sizeof(md_core);
+
+ /* Save integer registers. */
+ error = process_read_regs(p, &md_core.intreg);
+ if (error)
+ return error;
+
+ /* Save floating point registers. */
+ error = process_read_fpregs(p, &md_core.freg);
+ if (error)
+ return error;
+
+ CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU);
+ cseg.c_addr = 0;
+ cseg.c_size = chdr->c_cpusize;
+
+ error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize,
+ (off_t)chdr->c_hdrsize, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred,
+ NULL, p);
+ if (error)
+ return error;
+
+ error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&md_core, sizeof(md_core),
+ (off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE,
+ IO_NODELOCKED|IO_UNIT, cred, NULL, p);
+ if (error)
+ return error;
+
+ chdr->c_nseg++;
+ return 0;
+}
+
+/*
+ * Move pages from one kernel virtual address to another.
+ * Both addresses are assumed to reside in the Sysmap,
+ * and size must be a multiple of NBPG.
+ */
+void
+pagemove(from, to, size)
+ caddr_t from, to;
+ size_t size;
+{
+ paddr_t pa;
+ boolean_t rv;
+
+#ifdef DEBUG
+ if (size & PGOFSET)
+ panic("pagemove");
+#endif
+ while (size > 0) {
+ rv = pmap_extract(pmap_kernel(), (vaddr_t)from, &pa);
+#ifdef DEBUG
+ if (rv == FALSE)
+ panic("pagemove 2");
+ if (pmap_extract(pmap_kernel(), (vaddr_t)to, NULL) == TRUE)
+ panic("pagemove 3");
+#endif
+ pmap_remove(pmap_kernel(),
+ (vaddr_t)from, (vaddr_t)from + PAGE_SIZE);
+ pmap_enter(pmap_kernel(),
+ (vaddr_t)to, pa, VM_PROT_READ|VM_PROT_WRITE,
+ VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
+ from += PAGE_SIZE;
+ to += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+}
+
+/*
+ * Map `size' bytes of physical memory starting at `paddr' into
+ * kernel VA space at `vaddr'. Read/write and cache-inhibit status
+ * are specified by `prot'.
+ */
+void
+physaccess(vaddr, paddr, size, prot)
+ caddr_t vaddr, paddr;
+ int size, prot;
+{
+ pt_entry_t *pte;
+ u_int page;
+
+ pte = kvtopte(vaddr);
+ page = (u_int)paddr & PG_FRAME;
+ for (size = btoc(size); size; size--) {
+ *pte++ = PG_V | prot | page;
+ page += NBPG;
+ }
+ TBIAS();
+}
+
+void
+physunaccess(vaddr, size)
+ caddr_t vaddr;
+ int size;
+{
+ pt_entry_t *pte;
+
+ pte = kvtopte(vaddr);
+ for (size = btoc(size); size; size--)
+ *pte++ = PG_NV;
+ TBIAS();
+}
+
+/*
+ * Convert kernel VA to physical address
+ */
+int
+kvtop(addr)
+ caddr_t addr;
+{
+ paddr_t pa;
+
+ if (pmap_extract(pmap_kernel(), (vaddr_t)addr, &pa) == FALSE)
+ panic("kvtop: zero page frame");
+ return((int)pa);
+}
+
+extern vm_map_t phys_map;
+
+/*
+ * Map a user I/O request into kernel virtual address space.
+ * Note: the pages are already locked by uvm_vslock(), so we
+ * do not need to pass an access_type to pmap_enter().
+ */
+void
+vmapbuf(bp, len)
+ struct buf *bp;
+ vsize_t len;
+{
+ struct pmap *upmap, *kpmap;
+ vaddr_t uva; /* User VA (map from) */
+ vaddr_t kva; /* Kernel VA (new to) */
+ paddr_t pa; /* physical address */
+ vsize_t off;
+
+ if ((bp->b_flags & B_PHYS) == 0)
+ panic("vmapbuf");
+
+ uva = m68k_trunc_page(bp->b_saveaddr = bp->b_data);
+ off = (vaddr_t)bp->b_data - uva;
+ len = m68k_round_page(off + len);
+ kva = uvm_km_valloc_wait(phys_map, len);
+ bp->b_data = (caddr_t)(kva + off);
+
+ upmap = vm_map_pmap(&bp->b_proc->p_vmspace->vm_map);
+ kpmap = vm_map_pmap(phys_map);
+ do {
+ if (pmap_extract(upmap, uva, &pa) == FALSE)
+ panic("vmapbuf: null page frame");
+ pmap_enter(kpmap, kva, pa, VM_PROT_READ|VM_PROT_WRITE,
+ PMAP_WIRED);
+ uva += PAGE_SIZE;
+ kva += PAGE_SIZE;
+ len -= PAGE_SIZE;
+ } while (len);
+}
+
+/*
+ * Unmap a previously-mapped user I/O request.
+ */
+void
+vunmapbuf(bp, len)
+ struct buf *bp;
+ vsize_t len;
+{
+ vaddr_t kva;
+ vsize_t off;
+
+ if ((bp->b_flags & B_PHYS) == 0)
+ panic("vunmapbuf");
+
+ kva = m68k_trunc_page(bp->b_data);
+ off = (vaddr_t)bp->b_data - kva;
+ len = m68k_round_page(off + len);
+
+ /*
+ * pmap_remove() is unnecessary here, as kmem_free_wakeup()
+ * will do it for us.
+ */
+ uvm_km_free_wakeup(phys_map, kva, len);
+ bp->b_data = bp->b_saveaddr;
+ bp->b_saveaddr = 0;
+}