Check-in of powerpc kernel support.
authorrahnds <rahnds@openbsd.org>
Sat, 21 Dec 1996 20:35:52 +0000 (20:35 +0000)
committerrahnds <rahnds@openbsd.org>
Sat, 21 Dec 1996 20:35:52 +0000 (20:35 +0000)
NOTE: This will not work until the other pieces are checked in.
This is primarily the NetBSD powerpc port, with modifications
to support ELF.

91 files changed:
sys/arch/powerpc/Makefile [new file with mode: 0644]
sys/arch/powerpc/README [new file with mode: 0644]
sys/arch/powerpc/conf/GENERIC [new file with mode: 0644]
sys/arch/powerpc/conf/Makefile.powerpc [new file with mode: 0644]
sys/arch/powerpc/conf/NFS [new file with mode: 0644]
sys/arch/powerpc/conf/TST [new file with mode: 0644]
sys/arch/powerpc/conf/TST.net [new file with mode: 0644]
sys/arch/powerpc/conf/TST1 [new file with mode: 0644]
sys/arch/powerpc/conf/TSTdbg [new file with mode: 0644]
sys/arch/powerpc/conf/files.powerpc [new file with mode: 0644]
sys/arch/powerpc/include/ansi.h [new file with mode: 0644]
sys/arch/powerpc/include/aout_machdep.h [new file with mode: 0644]
sys/arch/powerpc/include/asm.h [new file with mode: 0644]
sys/arch/powerpc/include/bat.h [new file with mode: 0644]
sys/arch/powerpc/include/cdefs.h [new file with mode: 0644]
sys/arch/powerpc/include/cpu.h [new file with mode: 0644]
sys/arch/powerpc/include/disklabel.h [new file with mode: 0644]
sys/arch/powerpc/include/endian.h [new file with mode: 0644]
sys/arch/powerpc/include/exec.h [new file with mode: 0644]
sys/arch/powerpc/include/float.h [new file with mode: 0644]
sys/arch/powerpc/include/fpu.h [new file with mode: 0644]
sys/arch/powerpc/include/frame.h [new file with mode: 0644]
sys/arch/powerpc/include/ieee.h [new file with mode: 0644]
sys/arch/powerpc/include/ipkdb.h [new file with mode: 0644]
sys/arch/powerpc/include/irq.h [new file with mode: 0644]
sys/arch/powerpc/include/kcore.h [new file with mode: 0644]
sys/arch/powerpc/include/limits.h [new file with mode: 0644]
sys/arch/powerpc/include/param.h [new file with mode: 0644]
sys/arch/powerpc/include/pcb.h [new file with mode: 0644]
sys/arch/powerpc/include/pmap.h [new file with mode: 0644]
sys/arch/powerpc/include/powerpc.h [new file with mode: 0644]
sys/arch/powerpc/include/proc.h [new file with mode: 0644]
sys/arch/powerpc/include/profile.h [new file with mode: 0644]
sys/arch/powerpc/include/psl.h [new file with mode: 0644]
sys/arch/powerpc/include/pte.h [new file with mode: 0644]
sys/arch/powerpc/include/reloc.h [new file with mode: 0644]
sys/arch/powerpc/include/setjmp.h [new file with mode: 0644]
sys/arch/powerpc/include/signal.h [new file with mode: 0644]
sys/arch/powerpc/include/stdarg.h [new file with mode: 0644]
sys/arch/powerpc/include/trap.h [new file with mode: 0644]
sys/arch/powerpc/include/types.h [new file with mode: 0644]
sys/arch/powerpc/include/va-ppc.h [new file with mode: 0644]
sys/arch/powerpc/include/varargs.h [new file with mode: 0644]
sys/arch/powerpc/include/vmparam.h [new file with mode: 0644]
sys/arch/powerpc/powerpc/Locore.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/autoconf.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/bcopy.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/clock.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/conf.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/copyinstr.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/copyoutstr.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/copystr.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/db_disasm.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/db_interface.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/db_memrw.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/db_trace.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/disksubr.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/fpu.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/fubyte.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/fuswintr.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/genassym.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/in_cksum.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/locore.S [new file with mode: 0644]
sys/arch/powerpc/powerpc/machdep.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/mem.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/ofw_machdep.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/ofwreal.S [new file with mode: 0644]
sys/arch/powerpc/powerpc/openfirm.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/pmap.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/process_machdep.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/random.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/setjmp.S [new file with mode: 0644]
sys/arch/powerpc/powerpc/subyte.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/suswintr.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/suword.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/swapgeneric.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/sys_machdep.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/trap.c [new file with mode: 0644]
sys/arch/powerpc/powerpc/trap.c.swp [new file with mode: 0644]
sys/arch/powerpc/powerpc/vm_machdep.c [new file with mode: 0644]
sys/arch/powerpc/stand/Locore.c [new file with mode: 0644]
sys/arch/powerpc/stand/Makefile [new file with mode: 0644]
sys/arch/powerpc/stand/Makefile.inc [new file with mode: 0644]
sys/arch/powerpc/stand/alloc.c [new file with mode: 0644]
sys/arch/powerpc/stand/boot.c [new file with mode: 0644]
sys/arch/powerpc/stand/boot/Makefile [new file with mode: 0644]
sys/arch/powerpc/stand/net.c [new file with mode: 0644]
sys/arch/powerpc/stand/netif_of.c [new file with mode: 0644]
sys/arch/powerpc/stand/ofdev.c [new file with mode: 0644]
sys/arch/powerpc/stand/ofdev.h [new file with mode: 0644]
sys/arch/powerpc/stand/openfirm.h [new file with mode: 0644]

diff --git a/sys/arch/powerpc/Makefile b/sys/arch/powerpc/Makefile
new file mode 100644 (file)
index 0000000..ee2611f
--- /dev/null
@@ -0,0 +1,8 @@
+NOPROG=        noprog
+NOMAN= noman
+
+SUBDIR=        stand
+
+obj:   _SUBDIRUSE
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/powerpc/README b/sys/arch/powerpc/README
new file mode 100644 (file)
index 0000000..834bbee
--- /dev/null
@@ -0,0 +1,16 @@
+NOT YET READY!!!
+
+This port is heavily based on the NetBSD powerpc port by
+Wolfgang Solfrank. All of the kernel code is derived from there.
+Some modifications have been made, primarily to support ELF.
+
+Until this README file states that the port is ready, it is unlikey
+that the port will build correctly.
+
+Currently, dont even try, go ahead and look at the code, but
+nothing has been tried since It was checked in.
+
+I hope to have this ready before Jan 1997
+
+Dale
+rahnds@cvs.openbsd.org
diff --git a/sys/arch/powerpc/conf/GENERIC b/sys/arch/powerpc/conf/GENERIC
new file mode 100644 (file)
index 0000000..7a8afb7
--- /dev/null
@@ -0,0 +1,63 @@
+#
+# First try for PPC GENERIC config file
+#
+
+machine                powerpc
+
+maxusers       32
+
+# Standard system options (should go into std.powerpc?)
+options                SWAPPAGER, VNODEPAGER, DEVPAGER
+options                MACHINE_NONCONTIG
+options                EXEC_AOUT
+options                EXEC_SCRIPT
+
+# various hacks due to bugs in Openfirmware implementation
+options                FIREPOWERBUGS
+
+options                IPKDBUSERHACK
+makeoptions    DEBUG="-g"
+
+options                TCP_COMPAT_42
+options                COMPAT_43
+options                COMPAT_09
+options                COMPAT_10
+options                COMPAT_12
+
+options                FFS
+options                MFS
+
+options                NFSCLIENT
+options                NFSSERVER
+
+options                CD9660
+options                MSDOSFS
+options                FDESC
+options                FIFO
+options                KERNFS
+options                NULLFS
+options                PORTAL
+options                PROCFS
+options                UMAPFS
+options                UNION
+
+options                INET
+options                NMBCLUSTERS=1024
+
+config         netbsd  swap generic
+
+ofroot*                at root
+
+ofbus*         at openfirm?
+
+ofdisk*                at openfirm?
+
+ofnet*         at openfirm?
+ipkdbif0       at ofnet?
+
+ofcons*                at openfirm?
+
+ofrtc*         at openfirm?
+
+pseudo-device  loop
+pseudo-device  pty     64
diff --git a/sys/arch/powerpc/conf/Makefile.powerpc b/sys/arch/powerpc/conf/Makefile.powerpc
new file mode 100644 (file)
index 0000000..aa1bfd4
--- /dev/null
@@ -0,0 +1,186 @@
+#      $NetBSD: Makefile.powerpc,v 1.1 1996/09/30 16:34:18 ws 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/powerpc/conf/``machineid''
+# after which you should do
+#      config machineid
+# Machine generic makefile changes should be made in
+#      /sys/arch/powerpc/conf/Makefile.powerpc
+# 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
+#
+.SUFFIXES:     .S .c .o
+
+# DEBUG is set to -g if debugging.
+# PROF is set to -pg if profiling.
+
+CC?=   cc
+LD?=   ld
+MKDEP?=        mkdep
+STRIP?=        strip
+SIZE?= size
+
+# source tree is located via $S relative to the compilation directory
+#.ifndef       S
+#S!=   cd ../../../..; pwd
+#.endif
+S=     ../../../..
+PPC=   $S/arch/powerpc
+
+INCLUDES=      -I. -I$S/arch -I$S -nostdinc -L${DESTDIR}/usr/include
+CPPFLAGS=      ${INCLUDES} ${IDENT} -D_KERNEL \
+               -Dpowerpc
+CWARNFLAGS=    -Werror -Wreturn-type
+CFLAGS=                ${DEBUG} ${CWARNFLAGS} -O2 -msoft-float
+AFLAGS=                -D_LOCORE
+LINKFLAGS=     -N -Ttext 100000 -e start
+STRIPFLAGS=    -d
+
+HOSTCC?=       ${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
+
+# 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 $<
+
+NORMAL_S=      ${CC} ${AFLAGS} ${CPPFLAGS} -c $<
+
+HOSTED_C=      ${HOSTCC} ${HOSTED_CFLAGS} ${HOSTED_CPPFLAGS} -c $<
+
+#.c.o:
+#      ${NORMAL_C}
+#
+#.S.o:
+#      ${NORMAL_S}
+
+%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 \
+               param.o ioconf.o ${OBJS} ${LIBKERN} ${LIBCOMPAT}
+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 cp $@ $@.gdb; rm -f $@.gdb; cp $@ $@.gdb; \
+               echo ${STRIP} ${STRIPFLAGS} $@; ${STRIP} ${STRIPFLAGS} $@
+.else
+LINKFLAGS+=    -S
+.endif
+
+%LOAD
+
+assym.h: genassym
+       ./genassym > assym.h
+
+genassym: genassym.o
+       ${HOSTCC} -o $@ genassym.o
+
+genassym.o: ${PPC}/powerpc/genassym.c
+       ${HOSTED_C}
+
+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
+
+clean::
+       rm -f eddep *netbsd netbsd.gdb tags *.[io] [a-z]*.s \
+               [Ee]rrs linterrs makelinks genassym genassym.o assym.h
+
+lint:
+       @lint -hbxncez -DGENERIC -Dvolatile= ${CPPFLAGS} -UKGDB \
+               ${PPC}/powerpc/Locore.c ${CFILES} ${PPC}/powerpc/swapgeneric.c \
+               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=  ${PPC}/powerpc/locore.S \
+       param.c ioconf.c ${CFILES} ${SFILES}
+depend:: .depend
+.depend: ${SRCS} assym.h param.c
+       ${MKDEP} ${AFLAGS} ${CPPFLAGS} ${PPC}/powerpc/locore.S
+       ${MKDEP} -a ${CFLAGS} ${CPPFLAGS} param.c ioconf.c ${CFILES}
+.if ${SFILES} != ""
+       ${MKDEP} -a ${AFLAGS} ${CPPFLAGS} ${SFILES}
+.endif
+       ${MKDEP} -a ${HOSTED_CFLAGS} ${HOSTED_CPPFLAGS} \
+           ${PPC}/powerpc/genassym.c
+
+# 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
+genassym.o machdep.o: Makefile
+
+# depend on CPU configuration
+locore.o machdep.o: Makefile
+
+
+locore.o: ${PPC}/powerpc/locore.S assym.h
+       ${NORMAL_S}
+
+%RULES
diff --git a/sys/arch/powerpc/conf/NFS b/sys/arch/powerpc/conf/NFS
new file mode 100644 (file)
index 0000000..412dd99
--- /dev/null
@@ -0,0 +1,69 @@
+#
+# First try for PPC GENERIC config file
+#
+
+machine                powerpc
+
+maxusers       32
+
+# Standard system options (should go into std.powerpc?)
+options                SWAPPAGER, VNODEPAGER, DEVPAGER
+options                MACHINE_NONCONTIG
+options                EXEC_ELF
+options                EXEC_SCRIPT
+
+# various hacks due to bugs in Openfirmware implementation
+options                FIREPOWERBUGS
+
+#options               IPKDBUSERHACK
+#makeoptions   DEBUG="-g"
+
+options                KTRACE
+options                SYSCALL_DEBUG
+options                TCP_COMPAT_42
+options                COMPAT_43
+options                COMPAT_09
+options                COMPAT_10
+options                COMPAT_12
+
+options                FFS
+options                MFS
+
+options                NFSCLIENT
+#options               NFSSERVER
+
+options                CD9660
+options                MSDOSFS
+options                FDESC
+options                FIFO
+options                KERNFS
+options                NULLFS
+options                PORTAL
+options                PROCFS
+options                UMAPFS
+options                UNION
+
+options                INET
+options                NMBCLUSTERS=1024
+
+options                MAXUSERS=20
+options                TARGET_ELF
+
+config         netbsd  swap generic
+
+ofroot*                at root
+
+ofbus*         at openfirm?
+
+ofdisk*                at openfirm?
+
+ofnet*         at openfirm?
+#ipkdbif0      at ofnet?
+
+ofcons*                at openfirm?
+
+ofrtc*         at openfirm?
+
+pseudo-device  loop
+pseudo-device  pty     64
+pseudo-device  random  1
diff --git a/sys/arch/powerpc/conf/TST b/sys/arch/powerpc/conf/TST
new file mode 100644 (file)
index 0000000..b826662
--- /dev/null
@@ -0,0 +1,67 @@
+#
+# First try for PPC GENERIC config file
+#
+
+machine                powerpc
+
+maxusers       32
+
+# Standard system options (should go into std.powerpc?)
+options                SWAPPAGER, VNODEPAGER, DEVPAGER
+options                MACHINE_NONCONTIG
+options                EXEC_ELF
+options                EXEC_SCRIPT
+
+# various hacks due to bugs in Openfirmware implementation
+options                FIREPOWERBUGS
+
+#options               IPKDBUSERHACK
+#makeoptions   DEBUG="-g"
+
+options                TCP_COMPAT_42
+options                COMPAT_43
+options                COMPAT_09
+options                COMPAT_10
+options                COMPAT_12
+
+options                FFS
+options                MFS
+
+#options               NFSCLIENT
+#options               NFSSERVER
+
+options                CD9660
+options                MSDOSFS
+options                FDESC
+options                FIFO
+options                KERNFS
+options                NULLFS
+options                PORTAL
+options                PROCFS
+options                UMAPFS
+options                UNION
+
+options                INET
+options                NMBCLUSTERS=1024
+
+options                MAXUSERS=20
+options                TARGET_ELF
+
+config         netbsd  swap generic
+
+ofroot*                at root
+
+ofbus*         at openfirm?
+
+ofdisk*                at openfirm?
+
+#ofnet*                at openfirm?
+#ipkdbif0      at ofnet?
+
+ofcons*                at openfirm?
+
+ofrtc*         at openfirm?
+
+pseudo-device  loop
+pseudo-device  pty     64
+pseudo-device random  1
diff --git a/sys/arch/powerpc/conf/TST.net b/sys/arch/powerpc/conf/TST.net
new file mode 100644 (file)
index 0000000..31b09a7
--- /dev/null
@@ -0,0 +1,67 @@
+#
+# First try for PPC GENERIC config file
+#
+
+machine                powerpc
+
+maxusers       32
+
+# Standard system options (should go into std.powerpc?)
+options                SWAPPAGER, VNODEPAGER, DEVPAGER
+options                MACHINE_NONCONTIG
+options                EXEC_ELF
+options                EXEC_SCRIPT
+
+# various hacks due to bugs in Openfirmware implementation
+options                FIREPOWERBUGS
+
+#options               IPKDBUSERHACK
+#makeoptions   DEBUG="-g"
+
+options                TCP_COMPAT_42
+options                COMPAT_43
+options                COMPAT_09
+options                COMPAT_10
+options                COMPAT_12
+
+options                FFS
+options                MFS
+
+#options               NFSCLIENT
+#options               NFSSERVER
+
+options                CD9660
+options                MSDOSFS
+options                FDESC
+options                FIFO
+options                KERNFS
+options                NULLFS
+options                PORTAL
+options                PROCFS
+options                UMAPFS
+options                UNION
+
+options                INET
+options                NMBCLUSTERS=1024
+
+options                MAXUSERS=20
+options                TARGET_ELF
+
+config         netbsd  swap generic
+
+ofroot*                at root
+
+ofbus*         at openfirm?
+
+ofdisk*                at openfirm?
+
+ofnet*         at openfirm?
+#ipkdbif0      at ofnet?
+
+ofcons*                at openfirm?
+
+ofrtc*         at openfirm?
+
+pseudo-device  loop
+pseudo-device  pty     64
+pseudo-device  random  1
diff --git a/sys/arch/powerpc/conf/TST1 b/sys/arch/powerpc/conf/TST1
new file mode 100644 (file)
index 0000000..91538d3
--- /dev/null
@@ -0,0 +1,69 @@
+#
+# First try for PPC GENERIC config file
+#
+
+machine                powerpc
+
+maxusers       32
+
+# Standard system options (should go into std.powerpc?)
+options                SWAPPAGER, VNODEPAGER, DEVPAGER
+options                MACHINE_NONCONTIG
+options                EXEC_ELF
+options                EXEC_SCRIPT
+
+# various hacks due to bugs in Openfirmware implementation
+options                FIREPOWERBUGS
+
+#options               IPKDBUSERHACK
+#makeoptions   DEBUG="-g"
+
+options                KTRACE
+options                SYSCALL_DEBUG
+options                TCP_COMPAT_42
+options                COMPAT_43
+options                COMPAT_09
+options                COMPAT_10
+options                COMPAT_12
+
+options                FFS
+options                MFS
+
+#options               NFSCLIENT
+#options               NFSSERVER
+
+options                CD9660
+options                MSDOSFS
+options                FDESC
+options                FIFO
+options                KERNFS
+options                NULLFS
+options                PORTAL
+options                PROCFS
+options                UMAPFS
+options                UNION
+
+options                INET
+options                NMBCLUSTERS=1024
+
+options                MAXUSERS=20
+options                TARGET_ELF
+
+config         netbsd  swap generic
+
+ofroot*                at root
+
+ofbus*         at openfirm?
+
+ofdisk*                at openfirm?
+
+ofnet*         at openfirm?
+#ipkdbif0      at ofnet?
+
+ofcons*                at openfirm?
+
+ofrtc*         at openfirm?
+
+pseudo-device  loop
+pseudo-device  pty     64
+pseudo-device  random  1
diff --git a/sys/arch/powerpc/conf/TSTdbg b/sys/arch/powerpc/conf/TSTdbg
new file mode 100644 (file)
index 0000000..9a92fda
--- /dev/null
@@ -0,0 +1,69 @@
+#
+# First try for PPC GENERIC config file
+#
+
+machine                powerpc
+
+maxusers       32
+
+# Standard system options (should go into std.powerpc?)
+options                SWAPPAGER, VNODEPAGER, DEVPAGER
+options                MACHINE_NONCONTIG
+options                EXEC_ELF
+options                EXEC_SCRIPT
+
+# various hacks due to bugs in Openfirmware implementation
+options                FIREPOWERBUGS
+
+#options               IPKDBUSERHACK
+#makeoptions   DEBUG="-g"
+
+options                TCP_COMPAT_42
+options                COMPAT_43
+options                COMPAT_09
+options                COMPAT_10
+options                COMPAT_12
+
+options                FFS
+options                MFS
+
+#options               NFSCLIENT
+#options               NFSSERVER
+
+options                SYSCALL_DEBUG
+
+options                CD9660
+options                MSDOSFS
+options                FDESC
+options                FIFO
+options                KERNFS
+options                NULLFS
+options                PORTAL
+options                PROCFS
+options                UMAPFS
+options                UNION
+
+options                INET
+options                NMBCLUSTERS=1024
+
+options                MAXUSERS=20
+options                TARGET_ELF
+
+config         netbsd  swap generic
+
+ofroot*                at root
+
+ofbus*         at openfirm?
+
+ofdisk*                at openfirm?
+
+#ofnet*                at openfirm?
+#ipkdbif0      at ofnet?
+
+ofcons*                at openfirm?
+
+ofrtc*         at openfirm?
+
+pseudo-device  loop
+pseudo-device  pty     64
+pseudo-device random  1
diff --git a/sys/arch/powerpc/conf/files.powerpc b/sys/arch/powerpc/conf/files.powerpc
new file mode 100644 (file)
index 0000000..d39c334
--- /dev/null
@@ -0,0 +1,59 @@
+#
+# First try for powerpc-specific configuration info
+#
+maxpartitions 16
+
+maxusers 2 8 64
+
+#
+# Openfirmware support
+#
+include "../../../dev/ofw/files.ofw"
+major  {ofdisk = 0}
+
+file   arch/powerpc/powerpc/Locore.c
+file   arch/powerpc/powerpc/autoconf.c
+file   arch/powerpc/powerpc/bcopy.c
+file   arch/powerpc/powerpc/clock.c
+file   arch/powerpc/powerpc/conf.c
+file   arch/powerpc/powerpc/copyinstr.c
+file   arch/powerpc/powerpc/copyoutstr.c
+file   arch/powerpc/powerpc/copystr.c
+file   arch/powerpc/powerpc/disksubr.c         disk
+file   arch/powerpc/powerpc/fpu.c
+file   arch/powerpc/powerpc/fubyte.c
+file   arch/powerpc/powerpc/fuswintr.c
+file   arch/powerpc/powerpc/in_cksum.c
+file   arch/powerpc/powerpc/ipkdb_glue.c       ipkdb
+file   arch/powerpc/powerpc/machdep.c
+file   arch/powerpc/powerpc/mem.c
+file   arch/powerpc/powerpc/ofw_machdep.c
+file   arch/powerpc/powerpc/openfirm.c
+file   arch/powerpc/powerpc/pmap.c
+file   arch/powerpc/powerpc/process_machdep.c
+file   arch/powerpc/powerpc/subyte.c
+file   arch/powerpc/powerpc/suword.c
+file   arch/powerpc/powerpc/suswintr.c
+file   arch/powerpc/powerpc/sys_machdep.c
+file   arch/powerpc/powerpc/trap.c
+file   arch/powerpc/powerpc/vm_machdep.c
+file   dev/cons.c
+file   dev/cninit.c
+file    arch/ppc/ppc/setjmp.S                   ddb
+file    arch/ppc/ppc/db_memrw.c                 ddb
+file    arch/ppc/ppc/db_disasm.c                ddb
+file    arch/ppc/ppc/db_interface.c             ddb
+file    arch/ppc/ppc/db_trace.c                 ddb
+
+# FirePower specific code
+#device firepower: openfirm
+#attach firepower at root
+
+#file  arch/powerpc/firepower/firedep.c        firepower needs-flag
+#file  arch/powerpc/firepower/fireirq.c        firepower
+
+# FirePower OpenFirmware Bug Workarounds
+file   arch/powerpc/powerpc/ofwreal.S          firepowerbugs
+
+include "../../../scsi/files.scsi"
+
diff --git a/sys/arch/powerpc/include/ansi.h b/sys/arch/powerpc/include/ansi.h
new file mode 100644 (file)
index 0000000..403bc13
--- /dev/null
@@ -0,0 +1,75 @@
+/*     $NetBSD: ansi.h,v 1.1 1996/09/30 16:34:19 ws Exp $      */
+
+/*-
+ * 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.
+ *
+ *     @(#)ansi.h      8.2 (Berkeley) 1/4/94
+ */
+
+#ifndef        _ANSI_H_
+#define        _ANSI_H_
+
+/*
+ * Types which are fundamental to the implementation and may appear in
+ * more than one standard header are defined here.  Standard headers
+ * then use:
+ *     #ifdef  _BSD_SIZE_T_
+ *     typedef _BSD_SIZE_T_ size_t;
+ *     #undef  _BSD_SIZE_T_
+ *     #endif
+ */
+#define        _BSD_CLOCK_T_   unsigned long           /* clock() */
+#define        _BSD_PTRDIFF_T_ int                     /* ptr1 - ptr2 */
+#define        _BSD_SIZE_T_    unsigned int            /* sizeof() */
+#define        _BSD_SSIZE_T_   int                     /* byte count or error */
+#define        _BSD_TIME_T_    long                    /* time() */
+struct __gnuc_va_list__;
+#define        _BSD_VA_LIST_   struct __gnuc_va_list__ * /* va_list */
+
+/*
+ * Runes (wchar_t) is declared to be an ``int'' instead of the more natural
+ * ``unsigned long'' or ``long''.  Two things are happening here.  It is not
+ * unsigned so that EOF (-1) can be naturally assigned to it and used.  Also,
+ * it looks like 10646 will be a 31 bit standard.  This means that if your
+ * ints cannot hold 32 bits, you will be in trouble.  The reason an int was
+ * chosen over a long is that the is*() and to*() routines take ints (says
+ * ANSI C), but they use _RUNE_T_ instead of int.  By changing it here, you
+ * lose a bit of ANSI conformance, but your programs will still work.
+ *    
+ * Note that _WCHAR_T_ and _RUNE_T_ must be of the same type.  When wchar_t
+ * and rune_t are typedef'd, _WCHAR_T_ will be undef'd, but _RUNE_T remains
+ * defined for ctype.h.
+ */
+#define        _BSD_WCHAR_T_   int                     /* wchar_t */
+#define        _BSD_RUNE_T_    int                     /* rune_t */
+
+#endif /* _ANSI_H_ */
diff --git a/sys/arch/powerpc/include/aout_machdep.h b/sys/arch/powerpc/include/aout_machdep.h
new file mode 100644 (file)
index 0000000..b1ea7fa
--- /dev/null
@@ -0,0 +1,54 @@
+/*     $NetBSD: aout_machdep.h,v 1.1 1996/09/30 16:34:23 ws Exp $      */
+
+/*-
+ * Copyright (C) 1995 Wolfgang Solfrank.
+ * Copyright (C) 1995 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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        _MACH_EXEC_H_
+#define        _MACH_EXEC_H_
+
+#include <machine/reloc.h>
+
+/* No special executable format (yet) */
+#define        cpu_exec_aout_makecmds(a, b)    ENOEXEC
+
+/* Relocation format. */
+struct relocation_info_ppc {
+       int r_address;                  /* offset in text or data segment */
+       unsigned int r_symbolnum : 24,  /* ordinal number of add symbol */
+                       r_extern :  1,  /* 1 if need to add symbol to value */
+                                :  2;  /* unused bits */
+       enum reloc_type r_type   :  5;  /* relocation type */
+       long r_addend;                  /* relocation addend */
+};
+#define relocation_info        relocation_info_ppc
+
+#define        __LDPGSZ        4096
+
+#endif /* _MACH_EXEC_H_ */
diff --git a/sys/arch/powerpc/include/asm.h b/sys/arch/powerpc/include/asm.h
new file mode 100644 (file)
index 0000000..36f110d
--- /dev/null
@@ -0,0 +1,89 @@
+/*     $NetBSD: asm.h,v 1.1 1996/09/30 16:34:20 ws Exp $       */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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 _PPC_ASM_H_
+#define _PPC_ASM_H_
+
+/* XXX */
+#define TARGET_ELF
+
+#ifdef PIC
+#define PIC_PROLOGUE   XXX
+#define PIC_EPILOGUE   XXX
+#ifdef __STDC__
+#define PIC_PLT(x)     XXX
+#define PIC_GOT(x)     XXX
+#define PIC_GOTOFF(x)  XXX
+#else  /* not __STDC__ */
+#define PIC_PLT(x)     XXX
+#define PIC_GOT(x)     XXX
+#define PIC_GOTOFF(x)  XXX
+#endif /* __STDC__ */
+#else
+#define PIC_PROLOGUE
+#define PIC_EPILOGUE
+#define PIC_PLT(x)     x
+#define PIC_GOT(x)     x
+#define PIC_GOTOFF(x)  x
+#endif
+
+#ifdef TARGET_AOUT
+#ifdef __STDC__
+# define _C_LABEL(x)   _ ## x
+#else
+# define _C_LABEL(x)   _/**/x
+#endif
+#endif
+
+#ifdef TARGET_ELF
+# define _C_LABEL(x)   x
+#endif
+#define        _ASM_LABEL(x)   x
+
+#define _ENTRY(x) \
+       .text; .align 2; .globl x; .type x,@function; x:
+
+#ifdef PROF
+# define _PROF_PROLOGUE        XXX
+#else
+# define _PROF_PROLOGUE
+#endif
+
+#define        ENTRY(y)        _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
+#define        ASENTRY(y)      _ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
+
+#define        ASMSTR          .asciz
+
+#define RCSID(x)       .text; .asciz x
+
+#endif /* !_PPC_ASM_H_ */
diff --git a/sys/arch/powerpc/include/bat.h b/sys/arch/powerpc/include/bat.h
new file mode 100644 (file)
index 0000000..fc915ee
--- /dev/null
@@ -0,0 +1,54 @@
+/*     $NetBSD: bat.h,v 1.1 1996/09/30 16:34:20 ws Exp $       */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_BAT_H_
+#define        _MACHINE_BAT_H_
+
+struct bat {
+       u_int32_t batu;
+       u_int32_t batl;
+};
+
+#define        BATU(vaddr)             (((vaddr)&0xf0000000)|0x1ffe)
+#define        BATL(raddr,wimg)        (((raddr)&0xf0000000)|(wimg)|0x2)
+
+#define        BAT_W           0x40
+#define        BAT_I           0x20
+#define        BAT_M           0x10
+#define        BAT_G           0x08
+
+#ifdef _KERNEL
+extern struct bat battable[16];
+#endif
+
+#endif /* _MACHINE_BAT_H_ */
diff --git a/sys/arch/powerpc/include/cdefs.h b/sys/arch/powerpc/include/cdefs.h
new file mode 100644 (file)
index 0000000..d8534e0
--- /dev/null
@@ -0,0 +1,42 @@
+/*     $NetBSD: cdefs.h,v 1.1 1996/09/30 16:34:21 ws Exp $     */
+
+/*
+ * Written by J.T. Conklin <jtc@wimsey.com> 01/17/95.
+ * Public domain.
+ */
+
+#ifndef        _MACHINE_CDEFS_H_
+#define        _MACHINE_CDEFS_H_
+
+#ifdef __STDC__
+#define _C_LABEL(x)    _STRING(_ ## x)
+#else
+#define _C_LABEL(x)    _STRING(_/**/x)
+#endif
+
+#if 0
+#ifdef __GNUC__
+#ifdef __STDC__
+#define __indr_reference(sym,alias)    \
+       __asm__(".stabs \"_" #alias "\",11,0,0,0");     \
+       __asm__(".stabs \"_" #sym "\",1,0,0,0")
+#define __warn_references(sym,msg)     \
+       __asm__(".stabs \"" msg "\",30,0,0,0");         \
+       __asm__(".stabs \"_" #sym "\",1,0,0,0")
+#else
+#define __indr_reference(sym,alias)    \
+       __asm__(".stabs \"_/**/alias\",11,0,0,0");      \
+       __asm__(".stabs \"_/**/sym\",1,0,0,0")
+#define __warn_references(sym,msg)     \
+       __asm__(".stabs msg,30,0,0,0");                 \
+       __asm__(".stabs \"_/**/sym\",1,0,0,0")
+#endif
+#endif
+#else
+#define __warn_references(sym,msg)
+/*
+#define __indr_reference(sym,alias)
+*/
+#endif
+
+#endif /* !_MACHINE_CDEFS_H_ */
diff --git a/sys/arch/powerpc/include/cpu.h b/sys/arch/powerpc/include/cpu.h
new file mode 100644 (file)
index 0000000..0ec9d59
--- /dev/null
@@ -0,0 +1,91 @@
+/*     $NetBSD: cpu.h,v 1.1 1996/09/30 16:34:21 ws Exp $       */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_CPU_H_
+#define        _MACHINE_CPU_H_
+
+#include <machine/frame.h>
+
+struct machvec {
+       void (*splx) __P((int));
+       void (*irq_establish) __P((int, int, void (*)(void *), void *));
+};
+extern struct machvec machine_interface;
+
+#include <machine/psl.h>
+
+#define        irq_establish(irq, level, handler, arg) \
+       ((*machine_interface.irq_establish)((irq), (level), (handler), (arg)))
+
+#define        CLKF_USERMODE(frame)    (((frame)->srr1 & PSL_PR) != 0)
+#define        CLKF_BASEPRI(frame)     ((frame)->pri == 0)
+#define        CLKF_PC(frame)          ((frame)->srr0)
+#define        CLKF_INTR(frame)        ((frame)->depth != 0)
+
+#define        cpu_swapout(p)
+#define cpu_wait(p)
+
+extern void delay __P((unsigned));
+#define        DELAY(n)                delay(n)
+
+extern volatile int want_resched;
+extern volatile int astpending;
+
+#define        need_resched()          (want_resched = 1, astpending = 1)
+#define        need_proftick(p)        ((p)->p_flag |= P_OWEUPC, astpending = 1)
+#define        signotify(p)            (astpending = 1)
+
+#define        CACHELINESIZE   32                      /* For now              XXX */
+
+extern __inline void
+syncicache(from, len)
+       void *from;
+       int len;
+{
+       int l = len;
+       void *p = from;
+       
+       do {
+               asm volatile ("dcbst 0,%0" :: "r"(p));
+               p += CACHELINESIZE;
+       } while ((l -= CACHELINESIZE) > 0);
+       asm volatile ("sync");
+       do {
+               asm volatile ("icbi 0,%0" :: "r"(from));
+               from += CACHELINESIZE;
+       } while ((len -= CACHELINESIZE) > 0);
+       asm volatile ("isync");
+}
+
+extern char *bootpath;
+
+#endif /* _MACHINE_CPU_H_ */
diff --git a/sys/arch/powerpc/include/disklabel.h b/sys/arch/powerpc/include/disklabel.h
new file mode 100644 (file)
index 0000000..ffaa67c
--- /dev/null
@@ -0,0 +1,100 @@
+/*     $NetBSD: disklabel.h,v 1.1 1996/09/30 16:34:22 ws Exp $ */
+
+/*-
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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     1               /* sector containing label */
+#define        LABELOFFSET     0               /* offset of label in sector */
+#define        MAXPARTITIONS   16              /* number of partitions */
+#define        RAW_PART        2               /* raw partition: XX?c */
+
+/* MBR partition table */
+#define        MBRSECTOR       0               /* MBR sector number */
+#define        MBRPARTOFF      446             /* Offset of MBR partition table */
+#define        NMBRPART        4               /* # of partitions in MBR */
+#define        MBRMAGICOFF     510             /* Offset of magic number */
+#define        MBRMAGIC        0xaa55          /* Actual magic number */
+
+struct mbr_partition {
+       unsigned char   mbr_flag;       /* default boot flag */
+       unsigned char   mbr_shd;        /* start head, IsN't Always Meaningful */
+       unsigned char   mbr_ssect;      /* start sector, INAM */
+       unsigned char   mbr_scyl;       /* start cylinder, INAM */
+       unsigned char   mbr_type;       /* partition type */
+       unsigned char   mbr_ehd;        /* end head, INAM */
+       unsigned char   mbr_esect;      /* end sector, INAM */
+       unsigned char   mbr_ecyl;       /* end cylinder, INAM */
+       unsigned long   mbr_start;      /* absolute start sector number */
+       unsigned long   mbr_size;       /* partition size in sectors */
+};
+
+/* Known partition types: */
+#define        MBR_EXTENDED    0x05            /* Extended partition */
+#define        MBR_NETBSD_LE   0xa5            /* NetBSD little endian partition */
+#define        MBR_NETBSD_BE   0xa6            /* NetBSD big endian partition */
+#define        MBR_NETBSD      MBR_NETBSD_BE   /* on this machine, we default to BE */
+
+/* For compatibility reasons (mainly for fdisk): */
+#define        dos_partition   mbr_partition
+#define        dp_flag         mbr_flag
+#define        dp_shd          mbr_shd
+#define        dp_ssect        mbr_ssect
+#define        dp_scyl         mbr_scyl
+#define        dp_typ          mbr_type
+#define        dp_ehd          mbr_ehd
+#define        dp_esect        mbr_esect
+#define        dp_ecyl         mbr_ecyl
+#define        dp_start        mbr_start
+#define        dp_size         mbr_size
+
+#define        DOSPARTOFF      MBRPARTOFF
+#define        NDOSPART        NMBRPART
+
+#define        DOSPTYP_386BSD  MBR_NETBSD
+#define DOSPTYP_OPENBSD     0xa6            /* OpenBSD partition type */
+
+struct cpu_disklabel {
+       int cd_start;           /* Offset to NetBSD partition in blocks */
+};
+
+/* Isolate the relevant bits to get sector and cylinder. */
+#define        DPSECT(s)       ((s) & 0x3f)
+#define        DPCYL(c, s)     ((c) + (((s) & 0xc0) << 2))
+
+#ifdef _KERNEL
+struct disklabel;
+int bounds_check_with_label __P((struct buf *bp, struct disklabel *lp, int wlabel));
+#endif /* _KERNEL */
+
+#endif /* _MACHINE_DISKLABEL_H_ */
diff --git a/sys/arch/powerpc/include/endian.h b/sys/arch/powerpc/include/endian.h
new file mode 100644 (file)
index 0000000..6f5c4c6
--- /dev/null
@@ -0,0 +1,84 @@
+/*     $NetBSD: endian.h,v 1.2 1996/10/13 03:16:41 christos Exp $      */
+
+/*-
+ * Copyright (C) 1995 Wolfgang Solfrank.
+ * Copyright (C) 1995 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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        _PPC_ENDIAN_H_
+#define        _PPC_ENDIAN_H_
+
+#ifndef        _POSIX_SOURCE
+
+#define _QUAD_HIGHWORD 0
+#define _QUAD_LOWWORD  1
+
+/*
+ * Definitions for byte order, according to byte significance from low
+ * address to high.
+ */
+#define        LITTLE_ENDIAN   1234    /* LSB first: i386, vax */
+#define        BIG_ENDIAN      4321    /* MSB first: 68000, ibm, net */
+#define        PDP_ENDIAN      3412    /* LSB first in word, MSW first in long */
+
+#define        BYTE_ORDER      BIG_ENDIAN      /* for now */
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+unsigned long htonl __P((unsigned long));
+unsigned short htons __P((unsigned short));
+unsigned long ntohl __P((unsigned long));
+unsigned short ntohs __P((unsigned short));
+__END_DECLS
+
+/*
+ * Macros for network/external number representation conversion.
+ */
+#if BYTE_ORDER == BIG_ENDIAN && !defined(lint)
+#define        ntohl(x)        (x)
+#define        ntohs(x)        (x)
+#define        htonl(x)        (x)
+#define        htons(x)        (x)
+
+#define        NTOHL(x)        (void) (x)
+#define        NTOHS(x)        (void) (x)
+#define        HTONL(x)        (void) (x)
+#define        HTONS(x)        (void) (x)
+
+#else
+
+#define        NTOHL(x)        (x) = ntohl((in_addr_t)x)
+#define        NTOHS(x)        (x) = ntohs((in_port_t)x)
+#define        HTONL(x)        (x) = htonl((in_addr_t)x)
+#define        HTONS(x)        (x) = htons((in_port_t)x)
+#endif
+
+#endif /* _POSIX_SOURCE */
+#endif /* _PPC_ENDIAN_H_ */
diff --git a/sys/arch/powerpc/include/exec.h b/sys/arch/powerpc/include/exec.h
new file mode 100644 (file)
index 0000000..36aa234
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1993 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. 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.
+ *
+ *     $Id: exec.h,v 1.1.1.1 1996/12/21 20:35:54 rahnds Exp $
+ */
+
+#ifndef _PPC_EXEC_H_
+#define _PPC_EXEC_H_
+
+#define __LDPGSZ       4096    /* linker page size */
+
+enum reloc_type {
+  reloc_type_rubbish
+};
+
+/* Relocation format (from PMAX?) */
+struct relocation_info_powerpc {
+  int utter_rubbish;
+};
+#define relocation_info        relocation_info_ppc
+
+/*
+ *  Define what exec "formats" we should handle.
+ */
+#define NATIVE_EXEC_ELF
+
+#define ELF_TARG_CLASS          ELFCLASS32
+#define ELF_TARG_DATA           ELFDATA2MSB
+#define ELF_TARG_MACH           EM_PPC
+
+/*
+ *  This is what we want nlist(3) to handle.
+ */
+#define DO_AOUT                 /* support a.out */
+#define DO_ELF                  /* support ELF */
+
+
+#endif  /* _PPC_EXEC_H_ */
diff --git a/sys/arch/powerpc/include/float.h b/sys/arch/powerpc/include/float.h
new file mode 100644 (file)
index 0000000..62cd9f8
--- /dev/null
@@ -0,0 +1,80 @@
+/*     $NetBSD: float.h,v 1.1 1996/09/30 16:34:24 ws Exp $     */
+
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)float.h     7.1 (Berkeley) 5/8/90
+ */
+
+#ifndef _PPC_FLOAT_H_
+#define _PPC_FLOAT_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern int __flt_rounds();
+__END_DECLS
+
+#define FLT_RADIX      2               /* b */
+#define FLT_ROUNDS     __flt_rounds()
+
+#define FLT_MANT_DIG   24              /* p */
+#define FLT_EPSILON    1.19209290E-07F /* b**(1-p) */
+#define FLT_DIG                6               /* floor((p-1)*log10(b))+(b == 10) */
+#define FLT_MIN_EXP    (-125)          /* emin */
+#define FLT_MIN                1.17549435E-38F /* b**(emin-1) */
+#define FLT_MIN_10_EXP (-37)           /* ceil(log10(b**(emin-1))) */
+#define FLT_MAX_EXP    128             /* emax */
+#define FLT_MAX                3.40282347E+38F /* (1-b**(-p))*b**emax */
+#define FLT_MAX_10_EXP 38              /* floor(log10((1-b**(-p))*b**emax)) */
+
+#define DBL_MANT_DIG   53
+#define DBL_EPSILON    2.2204460492503131E-16
+#define DBL_DIG                15
+#define DBL_MIN_EXP    (-1021)
+#define DBL_MIN                2.2250738585072014E-308
+#define DBL_MIN_10_EXP (-307)
+#define DBL_MAX_EXP    1024
+#define DBL_MAX                1.7976931348623157E+308
+#define DBL_MAX_10_EXP 308
+
+#define LDBL_MANT_DIG  DBL_MANT_DIG
+#define LDBL_EPSILON   DBL_EPSILON
+#define LDBL_DIG       DBL_DIG
+#define LDBL_MIN_EXP   DBL_MIN_EXP
+#define LDBL_MIN       DBL_MIN
+#define LDBL_MIN_10_EXP        DBL_MIN_10_EXP
+#define LDBL_MAX_EXP   DBL_MAX_EXP
+#define LDBL_MAX       DBL_MAX
+#define LDBL_MAX_10_EXP        DBL_MAX_10_EXP
+
+#endif /* _PPC_FLOAT_H_ */
diff --git a/sys/arch/powerpc/include/fpu.h b/sys/arch/powerpc/include/fpu.h
new file mode 100644 (file)
index 0000000..e8cdb9c
--- /dev/null
@@ -0,0 +1,69 @@
+/*     $NetBSD: fpu.h,v 1.1 1996/09/30 16:34:24 ws Exp $       */
+
+/*-
+ * Copyright (C) 1996 Wolfgang Solfrank.
+ * Copyright (C) 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_FPU_H_
+#define        _MACHINE_FPU_H_
+
+#define        FPCSR_FX        0x80000000
+#define        FPCSR_FEX       0x40000000
+#define        FPCSR_VX        0x20000000
+#define        FPCSR_OX        0x10000000
+#define        FPCSR_UX        0x08000000
+#define        FPCSR_ZX        0x04000000
+#define        FPCSR_XX        0x02000000
+#define        FPCSR_VXSNAN    0x01000000
+#define        FPCSR_VXISI     0x00800000
+#define        FPCSR_VXIDI     0x00400000
+#define        FPCSR_VXZDZ     0x00200000
+#define        FPCSR_VXIMZ     0x00100000
+#define        FPCSR_VXVC      0x00080000
+#define        FPCSR_FR        0x00040000
+#define        FPCSR_FI        0x00020000
+#define        FPCSR_FPRF      0x0001f000
+#define        FPCSR_C         0x00010000
+#define        FPCSR_FPCC      0x0000f000
+#define        FPCSR_FL        0x00008000
+#define        FPCSR_FG        0x00004000
+#define        FPCSR_FE        0x00002000
+#define        FPCSR_FU        0x00001000
+#define        FPCSR_VXSOFT    0x00000400
+#define        FPCSR_VXSQRT    0x00000200
+#define        FPCSR_VXCVI     0x00000100
+#define        FPCSR_VE        0x00000080
+#define        FPCSR_OE        0x00000040
+#define        FPCSR_UE        0x00000020
+#define        FPCSR_ZE        0x00000010
+#define        FPCSR_XE        0x00000008
+#define        FPCSR_NI        0x00000004
+#define        FPCSR_RN        0x00000003
+
+#endif /* _MACHINE_FPU_H_ */
diff --git a/sys/arch/powerpc/include/frame.h b/sys/arch/powerpc/include/frame.h
new file mode 100644 (file)
index 0000000..a5b73d5
--- /dev/null
@@ -0,0 +1,92 @@
+/*     $NetBSD: frame.h,v 1.1 1996/09/30 16:34:25 ws Exp $     */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_FRAME_H_
+#define        _MACHINE_FRAME_H_
+
+#include <machine/types.h>
+
+/*
+ * We have to save all registers on every trap, because
+ *     1. user could attach this process every time
+ *     2. we must be able to restore all user registers in case of fork
+ * Actually, we do not save the fp registers on trap, since
+ * these are not used by the kernel. They are saved only when switching
+ * between processes using the FPU.
+ *
+ * Change ordering to cluster together these register_t's.             XXX
+ */
+struct trapframe {
+       register_t fixreg[32];
+       register_t lr;
+       int cr;
+       int xer;
+       register_t ctr;
+       register_t srr0;
+       register_t srr1;
+       register_t dar;                 /* dar & dsisr are only filled on a DSI trap */
+       int dsisr;
+       int exc;
+};
+/*
+ * This is to ensure alignment of the stackpointer
+ */
+#define        FRAMELEN        roundup(sizeof(struct trapframe) + 8, 16)
+#define        trapframe(p)    ((struct trapframe *)((void *)(p)->p_addr + USPACE - FRAMELEN + 8))
+
+struct switchframe {
+       register_t sp;
+       int fill;
+       int user_sr;
+       int cr;
+       register_t fixreg2;
+       register_t fixreg[19];          /* R13-R31 */
+};
+
+struct clockframe {
+       register_t srr1;
+       register_t srr0;
+       int pri;
+       int depth;
+};
+
+/*
+ * Call frame for PowerPC used during fork.
+ */
+struct callframe {
+       register_t sp;
+       register_t lr;
+       register_t r30;
+       register_t r31;
+};
+
+#endif /* _MACHINE_FRAME_H_ */
diff --git a/sys/arch/powerpc/include/ieee.h b/sys/arch/powerpc/include/ieee.h
new file mode 100644 (file)
index 0000000..fe83394
--- /dev/null
@@ -0,0 +1,136 @@
+/*     $NetBSD: ieee.h,v 1.1 1996/09/30 16:34:25 ws Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)ieee.h      8.1 (Berkeley) 6/11/93
+ */
+
+/*
+ * ieee.h defines the machine-dependent layout of the machine's IEEE
+ * floating point.  It does *not* define (yet?) any of the rounding
+ * mode bits, exceptions, and so forth.
+ */
+
+/*
+ * Define the number of bits in each fraction and exponent.
+ *
+ *                  k           k+1
+ * Note that  1.0 x 2  == 0.1 x 2      and that denorms are represented
+ *
+ *                                       (-exp_bias+1)
+ * as fractions that look like 0.fffff x 2             .  This means that
+ *
+ *                      -126
+ * the number 0.10000 x 2    , for instance, is the same as the normalized
+ *
+ *             -127                       -128
+ * float 1.0 x 2    .  Thus, to represent 2    , we need one leading zero
+ *
+ *                               -129
+ * in the fraction; to represent 2    , we need two, and so on.  This
+ *
+ *                                                  (-exp_bias-fracbits+1)
+ * implies that the smallest denormalized number is 2
+ *
+ * for whichever format we are talking about: for single precision, for
+ *
+ *                                             -126            -149
+ * instance, we get .00000000000000000000001 x 2    , or 1.0 x 2    , and
+ *
+ * -149 == -127 - 23 + 1.
+ */
+#define        SNG_EXPBITS     8
+#define        SNG_FRACBITS    23
+
+#define        DBL_EXPBITS     11
+#define        DBL_FRACBITS    52
+
+#define        EXT_EXPBITS     15
+#define        EXT_FRACBITS    112
+
+struct ieee_single {
+       u_int   sng_sign:1;
+       u_int   sng_exp:8;
+       u_int   sng_frac:23;
+};
+
+struct ieee_double {
+       u_int   dbl_sign:1;
+       u_int   dbl_exp:11;
+       u_int   dbl_frach:20;
+       u_int   dbl_fracl;
+};
+
+struct ieee_ext {
+       u_int   ext_sign:1;
+       u_int   ext_exp:15;
+       u_int   ext_frach:16;
+       u_int   ext_frachm;
+       u_int   ext_fraclm;
+       u_int   ext_fracl;
+};
+
+/*
+ * Floats whose exponent is in [1..INFNAN) (of whatever type) are
+ * `normal'.  Floats whose exponent is INFNAN are either Inf or NaN.
+ * Floats whose exponent is zero are either zero (iff all fraction
+ * bits are zero) or subnormal values.
+ *
+ * A NaN is a `signalling NaN' if its QUIETNAN bit is clear in its
+ * high fraction; if the bit is set, it is a `quiet NaN'.
+ */
+#define        SNG_EXP_INFNAN  255
+#define        DBL_EXP_INFNAN  2047
+#define        EXT_EXP_INFNAN  32767
+
+#if 0
+#define        SNG_QUIETNAN    (1 << 22)
+#define        DBL_QUIETNAN    (1 << 19)
+#define        EXT_QUIETNAN    (1 << 15)
+#endif
+
+/*
+ * Exponent biases.
+ */
+#define        SNG_EXP_BIAS    127
+#define        DBL_EXP_BIAS    1023
+#define        EXT_EXP_BIAS    16383
diff --git a/sys/arch/powerpc/include/ipkdb.h b/sys/arch/powerpc/include/ipkdb.h
new file mode 100644 (file)
index 0000000..da5f1a4
--- /dev/null
@@ -0,0 +1,80 @@
+/*     $NetBSD: ipkdb.h,v 1.1 1996/10/16 19:33:04 ws Exp $     */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+/* register array */
+#define        FIX     0
+#define        LR      32
+#define        CR      33
+#define        CTR     34
+#define        XER     35
+#define        PC      36
+#define        MSR     37
+#define        NREG    38
+
+#ifndef _LOCORE
+extern int ipkdbregs[NREG];
+
+/* Doesn't handle overlapping regions */
+__inline extern void
+ipkdbcopy(s,d,n)
+       void *s, *d;
+       int n;
+{
+       char *sp = s, *dp = d;
+       
+       while (--n >= 0)
+               *dp++ = *sp++;
+}
+
+__inline extern void
+ipkdbzero(d,n)
+       void *d;
+       int n;
+{
+       char *dp = d;
+       
+       while (--n >= 0)
+               *dp++ = 0;
+}
+
+__inline extern int
+ipkdbcmp(s,d,n)
+       void *s, *d;
+{
+       char *sp = s, *dp = d;
+       
+       while (--n >= 0)
+               if (*sp++ != *dp++)
+                       return *--dp - *--sp;
+       return 0;
+}
+#endif /* _LOCORE */
diff --git a/sys/arch/powerpc/include/irq.h b/sys/arch/powerpc/include/irq.h
new file mode 100644 (file)
index 0000000..47b2863
--- /dev/null
@@ -0,0 +1,49 @@
+/*     $NetBSD: irq.h,v 1.1 1996/09/30 16:34:26 ws Exp $       */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_IRQ_H_
+#define        _MACHINE_IRQ_H_
+
+#define        NINT    32              /* Maximum number of interrupt handlers */
+
+#ifndef        _LOCORE
+struct intrhand {
+       void (*handler)();      /* established handler */
+       void *arg;              /* established arg */
+       u_long count;           /* statistics */
+};
+
+extern struct intrhand irqvec[NINT];
+#endif /* _LOCORE */
+
+#endif /* _MACHINE_IRQ_H_ */
diff --git a/sys/arch/powerpc/include/kcore.h b/sys/arch/powerpc/include/kcore.h
new file mode 100644 (file)
index 0000000..236ef30
--- /dev/null
@@ -0,0 +1,45 @@
+/*     $NetBSD: kcore.h,v 1.1 1996/09/30 16:34:26 ws Exp $     */
+
+/*-
+ * Copyright (C) 1996 Wolfgang Solfrank.
+ * Copyright (C) 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_KCORE_H_
+#define        _MACHINE_KCORE_H_
+
+#define        NPHYS_RAM_SEGS  4
+
+typedef struct cpu_kcore_hdr {
+       vm_offset_t     ptable;         /* Phys address of page table */
+       vm_offset_t     potable;        /* Phys address of page overflow table */
+       phys_ram_seg_t  ram_segs[NPHYS_RAM_SEGS];
+} cpu_kcore_hdr_t;
+
+#endif /* _MACHINE_KCORE_H_ */
diff --git a/sys/arch/powerpc/include/limits.h b/sys/arch/powerpc/include/limits.h
new file mode 100644 (file)
index 0000000..a19695b
--- /dev/null
@@ -0,0 +1,63 @@
+/*     $NetBSD: limits.h,v 1.1 1996/09/30 16:34:28 ws Exp $    */
+
+/*-
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define        CHAR_BIT        8               /* bits per char                */
+#define        MB_LEN_MAX      1               /* no multibyte characters      */
+#define        CHAR_MIN        0               /* min value in char            */
+#define        CHAR_MAX        0xff            /* max value in char            */
+#define        UCHAR_MAX       0xff            /* max value in unsigned char   */
+#define        SCHAR_MIN       (-0x7f-1)       /* min value for a signed char  */
+#define        SCHAR_MAX       0x7f            /* max value for a signed char  */
+
+#define        SHRT_MIN        (-0x7fff-1)     /* min value in short           */
+#define        SHRT_MAX        0x7fff          /* max value in short           */
+#define        USHRT_MAX       0xffff          /* max value in unsigned short  */
+
+#define        INT_MIN         (-0x7fffffff-1) /* min value in int             */
+#define        INT_MAX         0x7fffffff      /* max value in int             */
+#define        UINT_MAX        0xffffffff      /* max value in unsigned int    */
+
+#define        LONG_MIN        (-0x7fffffff-1) /* min value in long            */
+#define        LONG_MAX        0x7fffffff      /* max value in long            */
+#define        ULONG_MAX       0xffffffff      /* max value in unsigned long   */
+
+#if !defined(_ANSI_SOURCE)
+
+#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE)
+#define        SIZE_T_MAX      UINT_MAX        /* max value for a size_t */
+
+#define        UQUAD_MAX       0xffffffffffffffffULL           /* max unsigned quad */
+#define        QUAD_MAX        0x7fffffffffffffffLL            /* max signed quad */
+#define        QUAD_MIN        (-0x7fffffffffffffffLL-1)       /* min signed quad */
+#endif /* !_POSIX_SOURCE && !_XOPEN_SOURCE */
+#endif /* !_ANSI_SOURCE */
diff --git a/sys/arch/powerpc/include/param.h b/sys/arch/powerpc/include/param.h
new file mode 100644 (file)
index 0000000..7df158c
--- /dev/null
@@ -0,0 +1,141 @@
+/*     $NetBSD: param.h,v 1.1 1996/09/30 16:34:28 ws Exp $     */
+
+/*-
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+
+#ifdef _KERNEL
+#ifndef        _LOCORE
+#include <machine/cpu.h>
+#endif /* _LOCORE */
+#endif
+
+/*
+ * Machine dependent constants for PowerPC (32-bit only currently)
+ */
+#define        MACHINE         "powerpc"
+#define        MACHINE_ARCH    "powerpc"
+#define        MID_MACHINE     MID_POWERPC
+
+#define        ALIGNBYTES      (sizeof(double) - 1)
+#define        ALIGN(p)        (((u_int)(p) + ALIGNBYTES) & ~ALIGNBYTES)
+
+#define        PGSHIFT         12
+#if 0
+#define        NBPG            (1 << PGSHIFT)  /* Page size */
+#endif
+#define        NBPG            4096
+#define        PGOFSET         (NBPG - 1)
+
+#define        DEV_BSHIFT      9               /* log2(DEV_BSIZE) */
+#define        DEV_BSIZE       (1 << DEV_BSHIFT)
+#define        BLKDEV_IOSIZE   NBPG
+#define        MAXPHYS         (64 * 1024)     /* max raw I/O transfer size */
+
+#define        CLSIZELOG2      0
+#define        CLSIZE          (1 << CLSIZELOG2)
+
+#define        UPAGES          4
+#define        USPACE          (UPAGES * NBPG)
+
+#define        KERNBASE        0x100000
+
+/*
+ * Constants related to network buffer management.
+ * MCLBYTES must be no larger than CLBYTES (the software page size), and,
+ * on machines that exchange pages of input or output buffers with mbuf
+ * clusters (MAPPED_MBUFS), MCLBYTES must also be an integral multiple
+ * of the hardware page size.
+ */
+#define        MSIZE           128             /* size of an mbuf */
+#define        MCLSHIFT        11              /* convert bytes to m_buf clusters */
+#define        MCLBYTES        (1 << MCLSHIFT) /* size of a m_buf cluster */
+
+#ifndef NMBCLUSTERS
+#ifdef GATEWAY
+#define        NMBCLUSTERS     512             /* map size, max cluster allocation */
+#else
+#define        NMBCLUSTERS     256             /* map size, max cluster allocation */
+#endif
+#endif
+
+/*
+ * Size of kernel malloc arena in CLBYTES-sized logical pages.
+ */
+#ifndef        NKMEMCLUSTERS
+#define        NKMEMCLUSTERS   (128 * 1024 * 1024 / CLBYTES)
+#endif
+
+/*
+ * pages ("clicks") to disk blocks
+ */
+#define        ctod(x)         ((x) << (PGSHIFT - DEV_BSHIFT))
+#define        dtoc(x)         ((x) >> (PGSHIFT - DEV_BSHIFT))
+/*
+ * bytes to pages
+ */
+#define        ctob(x)         ((x) << PGSHIFT)
+#define        btoc(x)         (((x) + PGOFSET) >> PGSHIFT)
+
+/*
+ * bytes to disk blocks
+ */
+#define        dbtob(x)        ((x) << DEV_BSHIFT)
+#define        btodb(x)        ((x) >> DEV_BSHIFT)
+
+/*
+ * Segment handling stuff
+ */
+#define        SEGMENT_LENGTH  0x10000000
+#define        SEGMENT_MASK    0xf0000000
+
+/*
+ * Fixed segments
+ */
+#define        USER_SR         13
+#define        KERNEL_SR       14
+#define        KERNEL_SEGMENT  (0xfffff0 + KERNEL_SR)
+#define        EMPTY_SEGMENT   0xfffff0
+#define        USER_ADDR       ((void *)(USER_SR << ADDR_SR_SHFT))
+
+/*
+ * Some system constants
+ */
+#ifndef        HTABENTS
+#define        HTABENTS        1024    /* Number of hashslots in HTAB */
+#endif
+#ifndef        NPMAPS
+#define        NPMAPS          32768   /* Number of pmaps in system */
+#endif
+
+/*
+ * Temporary kludge till we do (ov)bcopy in assembler
+ */
+#define        ovbcopy bcopy
diff --git a/sys/arch/powerpc/include/pcb.h b/sys/arch/powerpc/include/pcb.h
new file mode 100644 (file)
index 0000000..58bf6a4
--- /dev/null
@@ -0,0 +1,62 @@
+/*     $NetBSD: pcb.h,v 1.1 1996/09/30 16:34:29 ws Exp $       */
+
+/*-
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_PCB_H_
+#define        _MACHINE_PCB_H_
+
+typedef int faultbuf[24];
+
+struct pcb {
+       struct pmap *pcb_pm;    /* pmap of our vmspace */
+       struct pmap *pcb_pmreal; /* real address of above */
+       register_t pcb_sp;      /* saved SP */
+       int pcb_spl;            /* saved SPL */
+       faultbuf *pcb_onfault;  /* For use during copyin/copyout */
+       int pcb_flags;
+#define        PCB_FPU         1       /* Process had FPU initialized */
+       struct fpu {
+               double fpr[32];
+               double fpcsr;   /* FPCSR stored as double for easier access */
+       } pcb_fpu;              /* Floating point processor */
+};
+
+struct md_coredump {
+       struct trapframe frame;
+       /* Need to add FPU regs here */
+};
+
+#ifdef _KERNEL
+extern struct pcb *curpcb;
+extern struct pmap *curpm;
+extern struct proc *fpuproc;
+#endif
+#endif /* _MACHINE_PCB_H_ */
diff --git a/sys/arch/powerpc/include/pmap.h b/sys/arch/powerpc/include/pmap.h
new file mode 100644 (file)
index 0000000..6452c04
--- /dev/null
@@ -0,0 +1,77 @@
+/*     $NetBSD: pmap.h,v 1.1 1996/09/30 16:34:29 ws Exp $      */
+
+/*-
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_PMAP_H_
+#define        _MACHINE_PMAP_H_
+
+#include <machine/pte.h>
+
+/*
+ * Segment registers
+ */
+#ifndef        _LOCORE
+typedef u_int sr_t;
+#endif /* _LOCORE */
+#define        SR_TYPE         0x80000000
+#define        SR_SUKEY        0x40000000
+#define        SR_PRKEY        0x20000000
+#define        SR_VSID         0x00ffffff
+
+#ifndef _LOCORE
+/*
+ * Pmap stuff
+ */
+struct pmap {
+       sr_t pm_sr[16];         /* segments used in this pmap */
+       int pm_refs;            /* ref count */
+};
+
+typedef        struct pmap *pmap_t;
+
+#ifdef _KERNEL
+extern struct pmap kernel_pmap_;
+#define        pmap_kernel()   (&kernel_pmap_)
+
+#define pmap_clear_modify(pa)          (ptemodify((pa), PTE_CHG, 0))
+#define        pmap_clear_reference(pa)        (ptemodify((pa), PTE_REF, 0))
+#define        pmap_is_modified(pa)            (ptebits((pa), PTE_CHG))
+#define        pmap_is_referenced(pa)          (ptebits((pa), PTE_REF))
+#define        pmap_change_wiring(pm, va, wired)
+
+#define        pmap_phys_address(x)            (x)
+
+void pmap_bootstrap __P((u_int kernelstart, u_int kernelend));
+
+#endif /* _KERNEL */
+#endif /* _LOCORE */
+#endif /* _MACHINE_PMAP_H_ */
diff --git a/sys/arch/powerpc/include/powerpc.h b/sys/arch/powerpc/include/powerpc.h
new file mode 100644 (file)
index 0000000..4276f92
--- /dev/null
@@ -0,0 +1,55 @@
+/*     $NetBSD: powerpc.h,v 1.1 1996/09/30 16:34:30 ws Exp $   */
+
+/*
+ * Copyright (C) 1996 Wolfgang Solfrank.
+ * Copyright (C) 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_POWERPC_H_
+#define        _MACHINE_POWERPC_H_
+
+struct mem_region {
+       vm_offset_t start;
+       vm_size_t size;
+};
+
+void mem_regions __P((struct mem_region **, struct mem_region **));
+
+/*
+ * These two functions get used solely in boot() in machdep.c.
+ *
+ * Not sure whether boot itself should be implementation dependent instead.    XXX
+ */
+void ppc_exit __P((void)) __attribute__((__noreturn__));
+void ppc_boot __P((char *bootspec)) __attribute__((__noreturn__));
+
+int dk_match __P((char *name));
+
+void ofrootfound __P((void));
+
+#endif /* _MACHINE_POWERPC_H_ */
diff --git a/sys/arch/powerpc/include/proc.h b/sys/arch/powerpc/include/proc.h
new file mode 100644 (file)
index 0000000..019cc2a
--- /dev/null
@@ -0,0 +1,39 @@
+/*     $NetBSD: proc.h,v 1.1 1996/09/30 16:34:31 ws Exp $      */
+
+/*-
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+
+/*
+ * Machine-dependent part of the proc structure
+ */
+struct mdproc {
+       int dummy;
+};
diff --git a/sys/arch/powerpc/include/profile.h b/sys/arch/powerpc/include/profile.h
new file mode 100644 (file)
index 0000000..6e695ac
--- /dev/null
@@ -0,0 +1 @@
+#define        MCOUNT
diff --git a/sys/arch/powerpc/include/psl.h b/sys/arch/powerpc/include/psl.h
new file mode 100644 (file)
index 0000000..0868899
--- /dev/null
@@ -0,0 +1,171 @@
+/*     $NetBSD: psl.h,v 1.1 1996/09/30 16:34:32 ws Exp $       */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_PSL_H_
+#define        _MACHINE_PSL_H_
+
+/*
+ * Flags in MSR:
+ */
+#define        PSL_POW         0x00040000
+#define        PSL_ILE         0x00010000
+#define        PSL_EE          0x00008000
+#define        PSL_PR          0x00004000
+#define        PSL_FP          0x00002000
+#define        PSL_ME          0x00001000
+#define        PSL_FE0         0x00000800
+#define        PSL_SE          0x00000400
+#define        PSL_BE          0x00000200
+#define        PSL_FE1         0x00000100
+#define        PSL_IP          0x00000040
+#define        PSL_IR          0x00000020
+#define        PSL_DR          0x00000010
+#define        PSL_RI          0x00000002
+#define        PSL_LE          0x00000001
+
+/*
+ * Floating-point exception modes:
+ */
+#define        PSL_FE_DIS      0
+#define        PSL_FE_NONREC   PSL_FE1
+#define        PSL_FE_REC      PSL_FE0
+#define        PSL_FE_PREC     (PSL_FE0 | PSL_FE1)
+#define        PSL_FE_DFLT     PSL_FE_DIS
+
+/*
+ * Note that PSL_POW and PSL_ILE are not in the saved copy of the MSR
+ */
+#define        PSL_MBO         0
+#define        PSL_MBZ         0
+
+#define        PSL_USERSET     (PSL_EE | PSL_PR | PSL_ME | PSL_IR | PSL_DR | PSL_RI)
+
+#define        PSL_USERSTATIC  (PSL_USERSET | PSL_IP | 0x87c0008c)
+
+
+#ifdef _KERNEL
+/*
+ * Current processor level.
+ */
+#ifndef        _LOCORE
+extern int cpl;
+extern int clockpending, softclockpending, softnetpending;
+#endif
+#define        SPLBIO          0x01
+#define        SPLNET          0x02
+#define        SPLTTY          0x04
+#define        SPLIMP          0x08
+#define        SPLSOFTCLOCK    0x10
+#define        SPLSOFTNET      0x20
+#define        SPLCLOCK        0x80
+#define        SPLMACHINE      0x0f    /* levels handled by machine interface */
+
+#ifndef        _LOCORE
+extern int splx __P((int));
+
+extern int splraise __P((int));
+
+extern __inline int
+splhigh()
+{
+       return splraise(-1);
+}
+
+extern __inline int
+spl0()
+{
+       return splx(0);
+}
+
+extern __inline int
+splbio()
+{
+       return splraise(SPLBIO | SPLSOFTCLOCK | SPLSOFTNET);
+}
+
+extern __inline int
+splnet()
+{
+       return splraise(SPLNET | SPLSOFTCLOCK | SPLSOFTNET);
+}
+
+extern __inline int
+spltty()
+{
+       return splraise(SPLTTY | SPLSOFTCLOCK | SPLSOFTNET);
+}
+
+extern __inline int
+splimp()
+{
+       return splraise(SPLIMP | SPLSOFTCLOCK | SPLSOFTNET);
+}
+extern __inline int
+splclock()
+{
+       return splraise(SPLCLOCK | SPLSOFTCLOCK | SPLSOFTNET);
+}
+
+extern __inline int
+splsoftclock()
+{
+       return splraise(SPLSOFTCLOCK);
+}
+
+extern __inline int
+splsoftnet()
+{
+       return splraise(SPLSOFTNET);
+}
+
+extern __inline void
+setsoftclock()
+{
+       softclockpending = 1;
+       if (!(cpl & SPLSOFTCLOCK))
+               splx(cpl);
+}
+
+extern __inline void
+setsoftnet()
+{
+       softnetpending = 1;
+       if (!(cpl & SPLSOFTNET))
+               splx(cpl);
+}
+
+#endif /* !_LOCORE */
+
+#define        splstatclock()          splclock()
+
+#endif /* _KERNEL */
+#endif /* _MACHINE_PSL_H_ */
diff --git a/sys/arch/powerpc/include/pte.h b/sys/arch/powerpc/include/pte.h
new file mode 100644 (file)
index 0000000..98314ee
--- /dev/null
@@ -0,0 +1,112 @@
+/*     $NetBSD: pte.h,v 1.1 1996/09/30 16:34:32 ws Exp $       */
+
+/*-
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_PTE_H_
+#define        _MACHINE_PTE_H_
+
+#include <sys/queue.h>
+
+/*
+ * Page Table Entries
+ */
+#ifndef        _LOCORE
+struct pte {
+       u_int pte_hi;
+       u_int pte_lo;
+};
+#endif /* _LOCORE */
+/* High word: */
+#define        PTE_VALID       0x80000000
+#define        PTE_VSID_SHFT   7
+#define        PTE_HID         0x00000040
+#define        PTE_API         0x0000003f
+/* Low word: */
+#define        PTE_RPGN        0xfffff000
+#define        PTE_REF         0x00000100
+#define        PTE_CHG         0x00000080
+#define        PTE_WIMG        0x00000078
+#define        PTE_W           0x00000040
+#define        PTE_I           0x00000020
+#define        PTE_M           0x00000010
+#define        PTE_G           0x00000008
+#define        PTE_PP          0x00000003
+#define        PTE_RO          0x00000003
+#define        PTE_RW          0x00000002
+
+#ifndef        _LOCORE
+typedef        struct pte pte_t;
+#endif /* _LOCORE */
+
+/*
+ * Extract bits from address
+ */
+#define        ADDR_SR_SHFT    28
+#define        ADDR_PIDX       0x0ffff000
+#define        ADDR_PIDX_SHFT  12
+#define        ADDR_API_SHFT   22
+#define        ADDR_POFF       0x00000fff
+
+#ifndef        _LOCORE
+#ifdef _KERNEL
+extern pte_t *ptable;
+extern int ptab_cnt;
+#endif /* _KERNEL */
+#endif /* _LOCORE */
+
+/*
+ * Bits in DSISR:
+ */
+#define        DSISR_DIRECT    0x80000000
+#define        DSISR_NOTFOUND  0x40000000
+#define        DSISR_PROTECT   0x08000000
+#define        DSISR_INVRX     0x04000000
+#define        DSISR_STORE     0x02000000
+#define        DSISR_DABR      0x00400000
+#define        DSISR_SEGMENT   0x00200000
+#define        DSISR_EAR       0x00100000
+
+/*
+ * Bits in SRR1 on ISI:
+ */
+#define        ISSRR1_NOTFOUND 0x40000000
+#define        ISSRR1_DIRECT   0x10000000
+#define        ISSRR1_PROTECT  0x08000000
+#define        ISSRR1_SEGMENT  0x00200000
+
+#ifdef _KERNEL
+#ifndef        _LOCORE
+extern u_int dsisr __P((void));
+extern vm_offset_t dar __P((void));
+#endif /* _KERNEL */
+#endif /* _LOCORE */
+#endif /* _MACHINE_PTE_H_ */
diff --git a/sys/arch/powerpc/include/reloc.h b/sys/arch/powerpc/include/reloc.h
new file mode 100644 (file)
index 0000000..210c56c
--- /dev/null
@@ -0,0 +1,77 @@
+/*     $NetBSD: reloc.h,v 1.1 1996/09/30 16:34:33 ws Exp $     */
+
+/*-
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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        _MACH_RELOC_H_
+#define        _MACH_RELOC_H_
+
+/*
+ * Quite a number of relocation types
+ */
+enum reloc_type {
+       RELOC_NONE,
+       RELOC_32,
+       RELOC_24,
+       RELOC_16,
+       RELOC_16_LO,
+       RELOC_16_HI,    /* RELOC_ADDIS = 5 */
+       RELOC_16_HA,
+       RELOC_14,
+       RELOC_14_TAKEN,
+       RELOC_14_NTAKEN,
+       RELOC_REL24,    /* RELOC_BRANCH = 10 */
+       RELOC_REL14,
+       RELOC_REL14_TAKEN,
+       RELOC_REL14_NTAKEN,
+       RELOC_GOT16,
+       RELOC_GOT16_LO,
+       RELOC_GOT16_HI,
+       RELOC_GOT16_HA,
+       RELOC_PLT24,
+       RELOC_COPY,
+       RELOC_GLOB_DAT,
+       RELOC_JMP_SLOT,
+       RELOC_RELATIVE,
+       RELOC_LOCAL24PC,
+       RELOC_U32,
+       RELOC_U16,
+       RELOC_REL32,
+       RELOC_PLT32,
+       RELOC_PLTREL32,
+       RELOC_PLT16_LO,
+       RELOC_PLT16_HI,
+       RELOC_PLT16_HA,
+    /* ABI defines this as 32nd entry, but we ignore this, at least for now */
+       RELOC_SDAREL,
+       RELOC_MAX
+};
+
+#endif /* _MACH_RELOC_H_ */
diff --git a/sys/arch/powerpc/include/setjmp.h b/sys/arch/powerpc/include/setjmp.h
new file mode 100644 (file)
index 0000000..39a1f62
--- /dev/null
@@ -0,0 +1,3 @@
+/*     $NetBSD: setjmp.h,v 1.1 1996/09/30 16:34:34 ws Exp $    */
+
+#define        _JBLEN  100
diff --git a/sys/arch/powerpc/include/signal.h b/sys/arch/powerpc/include/signal.h
new file mode 100644 (file)
index 0000000..7f57320
--- /dev/null
@@ -0,0 +1,51 @@
+/*     $NetBSD: signal.h,v 1.1 1996/09/30 16:34:34 ws Exp $    */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_SIGNAL_H_
+#define        _MACHINE_SIGNAL_H_
+
+#include <machine/frame.h>
+
+typedef int sig_atomic_t;
+
+struct sigcontext {
+       int sc_onstack;                 /* saved onstack flag */
+       int sc_mask;                    /* saved signal mask */
+       struct trapframe sc_frame;      /* saved registers */
+};
+
+struct sigframe {
+       int sf_signum;
+       int sf_code;
+       struct sigcontext sf_sc;
+};
+#endif /* _MACHINE_SIGNAL_H_ */
diff --git a/sys/arch/powerpc/include/stdarg.h b/sys/arch/powerpc/include/stdarg.h
new file mode 100644 (file)
index 0000000..1f88825
--- /dev/null
@@ -0,0 +1,50 @@
+/*     $NetBSD: stdarg.h,v 1.1 1996/09/30 16:34:35 ws 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.
+ *
+ *     @(#)stdarg.h    8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _PPC_STDARG_H_
+#define        _PPC_STDARG_H_
+
+#include <machine/ansi.h>
+
+#ifndef        _STDARG_H
+#define        _STDARG_H
+#endif
+#include <machine/va-ppc.h>
+
+typedef _BSD_VA_LIST_  va_list;
+
+#endif /* !_PPC_STDARG_H_ */
diff --git a/sys/arch/powerpc/include/trap.h b/sys/arch/powerpc/include/trap.h
new file mode 100644 (file)
index 0000000..3087a3f
--- /dev/null
@@ -0,0 +1,67 @@
+/*     $NetBSD: trap.h,v 1.1 1996/09/30 16:34:35 ws Exp $      */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_TRAP_H_
+#define        _MACHINE_TRAP_H_
+
+#define        EXC_RSVD        0x0000          /* Reserved */
+#define        EXC_RST         0x0100          /* Reset */
+#define        EXC_MCHK        0x0200          /* Machine Check */
+#define        EXC_DSI         0x0300          /* Data Storage Interrupt */
+#define        EXC_ISI         0x0400          /* Instruction Storage Interrupt */
+#define        EXC_EXI         0x0500          /* External Interrupt */
+#define        EXC_ALI         0x0600          /* Alignment Interrupt */
+#define        EXC_PGM         0x0700          /* Program Interrupt */
+#define        EXC_FPU         0x0800          /* Floating-point Unavailable */
+#define        EXC_DECR        0x0900          /* Decrementer Interrupt */
+#define        EXC_SC          0x0c00          /* System Call */
+#define        EXC_TRC         0x0d00          /* Trace */
+#define        EXC_FPA         0x0e00          /* Floating-point Assist */
+
+/* The following are only available on 604: */
+#define        EXC_PERF        0x0f00          /* Performance Monitoring */
+#define        EXC_BPT         0x1300          /* Instruction Breakpoint */
+#define        EXC_SMI         0x1400          /* System Managment Interrupt */
+
+/* And these are only on the 603: */
+#define        EXC_IMISS       0x1000          /* Instruction translation miss */
+#define        EXC_DLMISS      0x1100          /* Data load translation miss */
+#define        EXC_DSMISS      0x1200          /* Data store translation miss */
+
+#define        EXC_LAST        0x2f00          /* Last possible exception vector */
+
+#define        EXC_AST         0x3000          /* Fake AST vector */
+
+/* Trap was in user mode */
+#define        EXC_USER        0x10000
+
+#endif /* _MACHINE_TRAP_H_ */
diff --git a/sys/arch/powerpc/include/types.h b/sys/arch/powerpc/include/types.h
new file mode 100644 (file)
index 0000000..0097cc0
--- /dev/null
@@ -0,0 +1,57 @@
+/*     $NetBSD: types.h,v 1.1 1996/09/30 16:34:36 ws Exp $     */
+
+/*-
+ * Copyright (C) 1995 Wolfgang Solfrank.
+ * Copyright (C) 1995 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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        _MACHTYPES_H_
+#define        _MACHTYPES_H_
+
+#include <sys/cdefs.h>
+
+#define        __BIT_TYPES_DEFINED__
+typedef        signed char             int8_t;
+typedef        unsigned char           u_int8_t;
+typedef        short                   int16_t;
+typedef        unsigned short          u_int16_t;
+typedef        int                     int32_t;
+typedef        unsigned int            u_int32_t;
+typedef        long long               int64_t;
+typedef        unsigned long long      u_int64_t;
+
+typedef        int32_t                 register_t;
+
+typedef        unsigned long           vm_size_t;
+typedef        unsigned long           vm_offset_t;
+
+/* This is only to make some unneeded function declaration happy */
+#define        label_t void
+
+#endif /* _MACHTYPES_H_ */
diff --git a/sys/arch/powerpc/include/va-ppc.h b/sys/arch/powerpc/include/va-ppc.h
new file mode 100644 (file)
index 0000000..24bb8de
--- /dev/null
@@ -0,0 +1,145 @@
+/* GNU C varargs support for the PowerPC with V.4 calling sequence */
+
+/* Define __gnuc_va_list.  */
+
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+
+/* Note that the names in this structure are in the user's namespace, but
+   that the V.4 abi explicitly states that these names should be used.  */
+typedef struct __gnuc_va_list__ {
+  char gpr;                    /* index into the array of 8 GPRs stored in the
+                                  register save area gpr=0 corresponds to r3,
+                                  gpr=1 to r4, etc. */
+  char fpr;                    /* index into the array of 8 FPRs stored in the
+                                  register save area fpr=0 corresponds to f1,
+                                  fpr=1 to f2, etc. */
+  char *overflow_arg_area;     /* location on stack that holds the next
+                                  overflow argument */
+  char *reg_save_area;         /* where r3:r10 and f1:f8, if saved are stored */
+} *__gnuc_va_list;
+#endif /* not __GNUC_VA_LIST */
+
+/* If this is for internal libc use, don't define anything but
+   __gnuc_va_list.  */
+#if defined (_STDARG_H) || defined (_VARARGS_H)
+
+/* Register save area located below the frame pointer */
+typedef struct {
+  long   __gp_save[8];         /* save area for GP registers */
+  double __fp_save[8];         /* save area for FP registers */
+} __va_regsave_t;
+
+/* Macros to access the register save area */
+/* We cast to void * and then to TYPE * because this avoids
+   a warning about increasing the alignment requirement.  */
+#define __VA_FP_REGSAVE(AP,TYPE)                                       \
+  ((TYPE *) (void *) (&(((__va_regsave_t *)                            \
+                        (AP)->reg_save_area)->__fp_save[(int)(AP)->fpr])))
+
+#define __VA_GP_REGSAVE(AP,TYPE)                                       \
+  ((TYPE *) (void *) (&(((__va_regsave_t *)                            \
+                        (AP)->reg_save_area)->__gp_save[(int)(AP)->gpr])))
+
+/* Common code for va_start for both varargs and stdarg.  This depends
+   on the format of rs6000_args in rs6000.h.  The fields used are:
+
+   #0  WORDS                   # words used for GP regs/stack values
+   #1  FREGNO                  next available FP register
+   #2  NARGS_PROTOTYPE         # args left in the current prototype
+   #3  ORIG_NARGS              original value of NARGS_PROTOTYPE
+   #4  VARARGS_OFFSET          offset from frame pointer of varargs area */
+
+#define __va_words             __builtin_args_info (0)
+#define __va_fregno            __builtin_args_info (1)
+#define        __va_nargs              __builtin_args_info (2)
+#define __va_orig_nargs                __builtin_args_info (3)
+#define __va_varargs_offset    __builtin_args_info (4)
+
+#define __va_start_common(AP, FAKE)                                    \
+__extension__ ({                                                       \
+   register int __words = __va_words - FAKE;                           \
+   (AP) = (__gnuc_va_list)__builtin_alloca(sizeof(__gnuc_va_list *));  \
+                                                                       \
+   (AP)->gpr = (__words < 8) ? __words : 8;                            \
+   (AP)->fpr = __va_fregno - 33;                                       \
+   (AP)->reg_save_area = (((char *) __builtin_frame_address (0))       \
+                         + __va_varargs_offset);                       \
+   (AP)->overflow_arg_area = ((char *)__builtin_saveregs ()            \
+                             + (((__words >= 8) ? __words - 8 : 0)     \
+                                * sizeof (long)));                     \
+   (void)0;                                                            \
+})
+
+#ifdef _STDARG_H /* stdarg.h support */
+
+/* Calling __builtin_next_arg gives the proper error message if LASTARG is
+   not indeed the last argument.  */
+#define va_start(AP,LASTARG) \
+  (__builtin_next_arg (LASTARG), __va_start_common (AP, 0))
+
+#else /* varargs.h support */
+
+#define va_start(AP) __va_start_common (AP, 1)
+#define va_alist __va_1st_arg
+#define va_dcl register int va_alist; ...
+
+#endif /* _STDARG_H */
+
+#ifdef _SOFT_FLOAT
+#define __va_float_p(TYPE)     0
+#else
+#define __va_float_p(TYPE)     (__builtin_classify_type(*(TYPE *)0) == 8)
+#endif
+
+#define __va_aggregate_p(TYPE) (__builtin_classify_type(*(TYPE *)0) >= 12)
+#define __va_size(TYPE)                ((sizeof(TYPE) + sizeof (long) - 1) / sizeof (long))
+
+#define va_arg(AP,TYPE)                                                        \
+__extension__ (*({                                                     \
+  register TYPE *__ptr;                                                        \
+                                                                       \
+  if (__va_float_p (TYPE) && (AP)->fpr < 8)                            \
+    {                                                                  \
+      __ptr = __VA_FP_REGSAVE (AP, TYPE);                              \
+      (AP)->fpr++;                                                     \
+    }                                                                  \
+                                                                       \
+  else if (__va_aggregate_p (TYPE) && (AP)->gpr < 8)                   \
+    {                                                                  \
+      __ptr = * __VA_GP_REGSAVE (AP, TYPE *);                          \
+      (AP)->gpr++;                                                     \
+    }                                                                  \
+                                                                       \
+  else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE)            \
+          && (AP)->gpr + __va_size(TYPE) <= 8)                         \
+    {                                                                  \
+      __ptr = __VA_GP_REGSAVE (AP, TYPE);                              \
+      (AP)->gpr += __va_size (TYPE);                                   \
+    }                                                                  \
+                                                                       \
+  else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE)            \
+          && (AP)->gpr < 8)                                            \
+    {                                                                  \
+      (AP)->gpr = 8;                                                   \
+      __ptr = (TYPE *) (void *) ((AP)->overflow_arg_area);             \
+      (AP)->overflow_arg_area += __va_size (TYPE) * sizeof (long);     \
+    }                                                                  \
+                                                                       \
+  else if (__va_aggregate_p (TYPE))                                    \
+    {                                                                  \
+      __ptr = * (TYPE **) (void *) ((AP)->overflow_arg_area);          \
+      (AP)->overflow_arg_area += sizeof (TYPE *);                      \
+    }                                                                  \
+  else                                                                 \
+    {                                                                  \
+      __ptr = (TYPE *) (void *) ((AP)->overflow_arg_area);             \
+      (AP)->overflow_arg_area += __va_size (TYPE) * sizeof (long);     \
+    }                                                                  \
+                                                                       \
+  __ptr;                                                               \
+}))
+
+#define va_end(AP)     ((void)0)
+
+#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
diff --git a/sys/arch/powerpc/include/varargs.h b/sys/arch/powerpc/include/varargs.h
new file mode 100644 (file)
index 0000000..ee015e0
--- /dev/null
@@ -0,0 +1,53 @@
+/*     $NetBSD: varargs.h,v 1.1 1996/09/30 16:34:37 ws Exp $   */
+
+/*-
+ * Copyright (c) 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ *
+ *     @(#)varargs.h   8.2 (Berkeley) 3/22/94
+ */
+
+#ifndef _PPC_VARARGS_H_
+#define        _PPC_VARARGS_H_
+
+#define _VARARGS_H
+
+#include <machine/ansi.h>
+#include <machine/va-ppc.h>
+
+typedef _BSD_VA_LIST_ va_list;
+
+#endif /* !_PPC_VARARGS_H_ */
diff --git a/sys/arch/powerpc/include/vmparam.h b/sys/arch/powerpc/include/vmparam.h
new file mode 100644 (file)
index 0000000..3cf36e0
--- /dev/null
@@ -0,0 +1,96 @@
+/*     $NetBSD: vmparam.h,v 1.1 1996/09/30 16:34:38 ws Exp $   */
+
+/*-
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define        USRTEXT         CLBYTES
+#define        USRSTACK        VM_MAXUSER_ADDRESS
+
+#ifndef        MAXTSIZ
+#define        MAXTSIZ         (16*1024*1024)          /* max text size */
+#endif
+
+#ifndef        DFLDSIZ
+#define        DFLDSIZ         (16*1024*1024)          /* default data size */
+#endif
+
+#ifndef        MAXDSIZ
+#define        MAXDSIZ         (512*1024*1024)         /* max data size */
+#endif
+
+#ifndef        DFLSSIZ
+#define        DFLSSIZ         (1*1024*1024)           /* default stack size */
+#endif
+
+#ifndef        MAXSSIZ
+#define        MAXSSIZ         (32*1024*1024)          /* max stack size */
+#endif
+
+/*
+ * Min & Max swap space allocation chunks
+ */
+#define        DMMIN           32
+#define        DMMAX           4096
+
+/*
+ * Size of shared memory map
+ */
+#ifndef        SHMMAXPGS
+#define        SHMMAXPGS       1024
+#endif
+
+/*
+ * Size of User Raw I/O map
+ */
+#define        USRIOSIZE       1024
+
+/*
+ * 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
+
+/*
+ * Would like to have MAX addresses = 0, but this doesn't (currently) work
+ */
+#define        VM_MIN_ADDRESS          ((vm_offset_t)0)
+#define        VM_MAXUSER_ADDRESS      ((vm_offset_t)0xfffff000)
+#define        VM_MAX_ADDRESS          VM_MAXUSER_ADDRESS
+#define        VM_MIN_KERNEL_ADDRESS   ((vm_offset_t)(KERNEL_SR << ADDR_SR_SHFT))
+
+#define        VM_KMEM_SIZE            (NKMEMCLUSTERS * CLBYTES)
+#define        VM_MBUF_SIZE            (NMBCLUSTERS * CLBYTES)
+#define        VM_PHYS_SIZE            (USRIOSIZE * CLBYTES)
diff --git a/sys/arch/powerpc/powerpc/Locore.c b/sys/arch/powerpc/powerpc/Locore.c
new file mode 100644 (file)
index 0000000..d4665a9
--- /dev/null
@@ -0,0 +1,90 @@
+/*     $NetBSD: Locore.c,v 1.1 1996/09/30 16:34:39 ws Exp $    */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+
+/*
+ * Some additional routines that happened to be in locore.S traditionally,
+ * but have no need to be coded in assembly.
+ */
+
+#include <sys/param.h>
+#include <sys/proc.h>
+
+int whichqs;
+
+/*
+ * Put process p on the run queue indicated by its priority.
+ * Calls should be made at splstatclock(), and p->p_stat should be SRUN.
+ */
+void
+setrunqueue(p)
+       struct proc *p;
+{
+       struct  prochd *q;
+       struct proc *oldlast;
+       int which = p->p_priority >> 2;
+       
+#ifdef DIAGNOSTIC
+       if (p->p_back)
+               panic("setrunqueue");
+#endif
+       q = &qs[which];
+       whichqs |= 0x80000000 >> which;
+       p->p_forw = (struct proc *)q;
+       p->p_back = oldlast = q->ph_rlink;
+       q->ph_rlink = p;
+       oldlast->p_forw = p;
+}
+
+/*
+ * Remove process p from its run queue, which should be the one
+ * indicated by its priority.
+ * Calls should be made at splstatclock().
+ */
+void
+remrq(p)
+       struct proc *p;
+{
+       int which = p->p_priority >> 2;
+       struct prochd *q;
+
+#ifdef DIAGNOSTIC      
+       if (!(whichqs & (0x80000000 >> which)))
+               panic("remrq");
+#endif
+       p->p_forw->p_back = p->p_back;
+       p->p_back->p_forw = p->p_forw;
+       p->p_back = NULL;
+       q = &qs[which];
+       if (q->ph_link == (struct proc *)q)
+               whichqs &= ~(0x80000000 >> which);
+}
diff --git a/sys/arch/powerpc/powerpc/autoconf.c b/sys/arch/powerpc/powerpc/autoconf.c
new file mode 100644 (file)
index 0000000..2b874ea
--- /dev/null
@@ -0,0 +1,120 @@
+/*     $NetBSD: autoconf.c,v 1.1 1996/09/30 16:34:39 ws Exp $  */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/reboot.h>
+#include <sys/systm.h>
+
+#include <machine/powerpc.h>
+
+extern int cold;
+
+void configure __P((void));
+void setroot __P((void));
+void swapconf __P((void));
+
+
+/*
+ * Determine device configuration for a machine.
+ */
+void
+configure()
+{
+       ofrootfound();
+       (void)spl0();
+
+       /*
+        * Setup root device.
+        * Configure swap area.
+        */
+       setroot();
+       swapconf();
+       cold = 0;
+}
+
+/*
+ * Try to find the device we were booted from to set rootdev.
+ */
+void
+setroot()
+{
+       char *cp;
+       
+       if (mountroot) {
+               /*
+                * rootdev/swdevt/mountroot etc. already setup by config.
+                */
+               return;
+       }
+       
+       /*
+        * Try to find the device where we were booted from.
+        */
+       for (cp = bootpath + strlen(bootpath); --cp >= bootpath;) {
+               if (*cp == '/') {
+                       *cp = '\0';
+                       if (!dk_match(bootpath)) {
+                               *cp = '/';
+                               break;
+                       }
+                       *cp = '/';
+               }
+       }
+       if (cp < bootpath || boothowto & RB_ASKNAME) {
+               /* Insert -a processing here                            XXX */
+               panic("Cannot find root device");
+       }
+       dk_cleanup();
+}
+
+/*
+ * Configure swap space
+ */
+void
+swapconf()
+{
+       struct swdevt *swp;
+       int nblks;
+       
+       for (swp = swdevt; swp->sw_dev != NODEV; swp++)
+               if (bdevsw[major(swp->sw_dev)].d_psize) {
+                       nblks = (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
+                       if (nblks != -1
+                           && (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
+                               swp->sw_nblks = nblks;
+                       swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
+               }
+       dumpconf();
+}
diff --git a/sys/arch/powerpc/powerpc/bcopy.c b/sys/arch/powerpc/powerpc/bcopy.c
new file mode 100644 (file)
index 0000000..42b5b42
--- /dev/null
@@ -0,0 +1,143 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)bcopy.c     5.11 (Berkeley) 6/21/91";*/
+static char *rcsid = "$Id: bcopy.c,v 1.1.1.1 1996/12/21 20:35:56 rahnds Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+/*
+#include <string.h>
+*/
+#include <sys/types.h>
+
+/*
+ * sizeof(word) MUST BE A POWER OF TWO
+ * SO THAT wmask BELOW IS ALL ONES
+ */
+typedef        int word;               /* "word" used for optimal copy speed */
+
+#define        wsize   sizeof(word)
+#define        wmask   (wsize - 1)
+
+/*
+ * Copy a block of memory, handling overlap.
+ * This is the routine that actually implements
+ * (the portable versions of) bcopy, memcpy, and memmove.
+ */
+#ifdef MEMCOPY
+void *
+memcpy(dst0, src0, length)
+#else
+#ifdef MEMMOVE
+void *
+memmove(dst0, src0, length)
+#else
+void
+bcopy(src0, dst0, length)
+#endif
+#endif
+       void *dst0;
+       const void *src0;
+       register size_t length;
+{
+       register char *dst = dst0;
+       register const char *src = src0;
+       register size_t t;
+
+       if (length == 0 || dst == src)          /* nothing to do */
+               goto done;
+
+       /*
+        * Macros: loop-t-times; and loop-t-times, t>0
+        */
+#define        TLOOP(s) if (t) TLOOP1(s)
+#define        TLOOP1(s) do { s; } while (--t)
+
+       if ((unsigned long)dst < (unsigned long)src) {
+               /*
+                * Copy forward.
+                */
+               t = (int)src;   /* only need low bits */
+               if ((t | (int)dst) & wmask) {
+                       /*
+                        * Try to align operands.  This cannot be done
+                        * unless the low bits match.
+                        */
+                       if ((t ^ (int)dst) & wmask || length < wsize)
+                               t = length;
+                       else
+                               t = wsize - (t & wmask);
+                       length -= t;
+                       TLOOP1(*dst++ = *src++);
+               }
+               /*
+                * Copy whole words, then mop up any trailing bytes.
+                */
+               t = length / wsize;
+               TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
+               t = length & wmask;
+               TLOOP(*dst++ = *src++);
+       } else {
+               /*
+                * Copy backwards.  Otherwise essentially the same.
+                * Alignment works as before, except that it takes
+                * (t&wmask) bytes to align, not wsize-(t&wmask).
+                */
+               src += length;
+               dst += length;
+               t = (int)src;
+               if ((t | (int)dst) & wmask) {
+                       if ((t ^ (int)dst) & wmask || length <= wsize)
+                               t = length;
+                       else
+                               t &= wmask;
+                       length -= t;
+                       TLOOP1(*--dst = *--src);
+               }
+               t = length / wsize;
+               TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
+               t = length & wmask;
+               TLOOP(*--dst = *--src);
+       }
+done:
+#if defined(MEMCOPY) || defined(MEMMOVE)
+       return (dst0);
+#else
+       return;
+#endif
+}
diff --git a/sys/arch/powerpc/powerpc/clock.c b/sys/arch/powerpc/powerpc/clock.c
new file mode 100644 (file)
index 0000000..07a9655
--- /dev/null
@@ -0,0 +1,320 @@
+/*     $NetBSD: clock.c,v 1.1 1996/09/30 16:34:40 ws Exp $     */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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/kernel.h>
+
+void resettodr();
+/*
+ * Initially we assume a processor with a bus frequency of 12.5 MHz.
+ */
+static u_long ticks_per_sec = 3125000;
+static u_long ns_per_tick = 320;
+static long ticks_per_intr;
+static volatile u_long lasttb;
+
+/*
+ * BCD to decimal and decimal to BCD.
+ */
+#define FROMBCD(x)      (((x) >> 4) * 10 + ((x) & 0xf))
+#define TOBCD(x)        (((x) / 10 * 16) + ((x) % 10))
+
+#define SECDAY          (24 * 60 * 60)
+#define SECYR           (SECDAY * 365)
+#define LEAPYEAR(y)     (((y) & 3) == 0)
+
+typedef int (clock_read_t)(int *sec, int *min, int *hour, int *day,
+         int *mon, int *yr);
+clock_read_t *clock_read;
+
+static u_long
+chiptotime(int sec, int min, int hour, int day, int mon, int year);
+
+/*
+ * For now we let the machine run with boot time, not changing the clock
+ * at inittodr at all.
+ *
+ * We might continue to do this due to setting up the real wall clock with
+ * a user level utility in the future.
+ */
+
+/* ARGSUSED */
+void
+inittodr(base)
+       time_t base;
+{
+       int sec, min, hour, day, mon, year;
+
+       int badbase = 0, waszero = base == 0;
+
+        if (base < 5 * SECYR) {
+                /*
+                 * If base is 0, assume filesystem time is just unknown
+                 * instead of preposterous. Don't bark.
+                 */
+                if (base != 0)
+                        printf("WARNING: preposterous time in file system\n");
+                /* not going to use it anyway, if the chip is readable */
+                base = 21*SECYR + 186*SECDAY + SECDAY/2;
+                badbase = 1;
+        }
+
+       if (clock_read != NULL ) {
+               (*clock_read)( &sec, &min, &hour, &day, &mon, &year);
+       }
+printf("time: sec %x, min %x, hour %x, day %x, mon %x, year %x\n",
+       sec, min, hour, day, mon, year);
+       if ((time.tv_sec = chiptotime(sec, min, hour, day, mon, year)) == 0) {
+               printf("WARNING: unable to get date/time");
+               /*
+                * Believe the time in the file system for lack of
+                * anything better, resetting the clock.
+                */
+               time.tv_sec = base;
+               if (!badbase)
+                       resettodr();
+       } else {
+               int deltat = time.tv_sec - base;
+
+               if (deltat < 0)
+                       deltat = -deltat;
+               if (waszero || deltat < 2 * SECDAY)
+                       return;
+               printf("WARNING: clock %s %d days",
+                   time.tv_sec < base ? "lost" : "gained", deltat / SECDAY);
+       }
+       printf(" -- CHECK AND RESET THE DATE!\n");
+}
+
+/*
+ * This code is defunct after 2068.
+ * Will Unix still be here then??
+ */
+const short dayyr[12] =
+    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+
+static u_long
+chiptotime(sec, min, hour, day, mon, year)
+        int sec, min, hour, day, mon, year;
+{
+       int days, yr;
+               
+#if 0
+       sec = FROMBCD(sec);
+       min = FROMBCD(min);
+       hour = FROMBCD(hour);
+       day = FROMBCD(day);
+       mon = FROMBCD(mon);
+       year = FROMBCD(year) + YEAR0;
+#endif
+               
+       /* simple sanity checks */
+       if (year < 1970 || mon < 1 || mon > 12 || day < 1 || day > 31)
+               return (0);
+       days = 0;
+       for (yr = 1970; yr < year; yr++)
+               days += LEAPYEAR(yr) ? 366 : 365;
+       days += dayyr[mon - 1] + day - 1;
+       if (LEAPYEAR(yr) && mon > 2)
+               days++;
+       /* now have days since Jan 1, 1970; the rest is easy... */
+       return (days * SECDAY + hour * 3600 + min * 60 + sec);
+}
+
+
+/*
+ * Similar to the above
+ */
+void
+resettodr()
+{
+}
+
+void
+decr_intr(frame)
+       struct clockframe *frame;
+{
+       int msr;
+       u_long tb;
+       long tick;
+       int nticks;
+       int pri;
+
+       /*
+        * Check whether we are initialized.
+        */
+       if (!ticks_per_intr)
+               return;
+
+       /*
+        * Based on the actual time delay since the last decrementer reload,
+        * we arrange for earlier interrupt next time.
+        */
+       asm ("mftb %0; mfdec %1" : "=r"(tb), "=r"(tick));
+       for (nticks = 0; tick < 0; nticks++)
+               tick += ticks_per_intr;
+       asm volatile ("mtdec %0" :: "r"(tick));
+       /*
+        * lasttb is used during microtime. Set it to the virtual
+        * start of this tick interval.
+        */
+       lasttb = tb + tick - ticks_per_intr;
+
+       pri = cpl;
+       
+       if (pri & SPLCLOCK)
+               clockpending += nticks;
+       else {
+               cpl = pri | SPLCLOCK | SPLSOFTCLOCK | SPLSOFTNET;
+
+               /*
+                * Reenable interrupts
+                */
+               asm volatile ("mfmsr %0; ori %0, %0, %1; mtmsr %0"
+                             : "=r"(msr) : "K"(PSL_EE));
+               
+               /*
+                * Do standard timer interrupt stuff.
+                * Do softclock stuff only on the last iteration.
+                */
+               frame->pri = pri | SPLSOFTCLOCK;
+               while (--nticks > 0)
+                       hardclock(frame);
+               frame->pri = pri;
+               hardclock(frame);
+       }
+       intr_return(pri);
+}
+
+void
+cpu_initclocks()
+{
+       int qhandle, phandle;
+       char name[32];
+       int msr, scratch;
+       
+       /*
+        * Get this info during autoconf?                               XXX
+        */
+       for (qhandle = OF_peer(0); qhandle; qhandle = phandle) {
+               if (OF_getprop(qhandle, "device_type", name, sizeof name) >= 0
+                   && !strcmp(name, "cpu")
+                   && OF_getprop(qhandle, "timebase-frequency",
+                                 &ticks_per_sec, sizeof ticks_per_sec) >= 0) {
+                       /*
+                        * Should check for correct CPU here?           XXX
+                        */
+                       asm volatile ("mfmsr %0; andi. %1, %0, %2; mtmsr %1"
+                                     : "=r"(msr), "=r"(scratch) : "K"((u_short)~PSL_EE));
+                       ns_per_tick = 1000000000 / ticks_per_sec;
+                       ticks_per_intr = ticks_per_sec / hz;
+                       asm volatile ("mftb %0" : "=r"(lasttb));
+                       asm volatile ("mtdec %0" :: "r"(ticks_per_intr));
+                       asm volatile ("mtmsr %0" :: "r"(msr));
+                       break;
+               }
+               if (phandle = OF_child(qhandle))
+                       continue;
+               while (qhandle) {
+                       if (phandle = OF_peer(qhandle))
+                               break;
+                       qhandle = OF_parent(qhandle);
+               }
+       }
+       if (!phandle)
+               panic("no cpu node");
+}
+
+static inline u_quad_t
+mftb()
+{
+       u_long scratch;
+       u_quad_t tb;
+       
+       asm ("1: mftbu %0; mftb %0+1; mftbu %1; cmpw %0,%1; bne 1b"
+            : "=r"(tb), "=r"(scratch));
+       return tb;
+}
+
+/*
+ * Fill in *tvp with current time with microsecond resolution.
+ */
+void
+microtime(tvp)
+       struct timeval *tvp;
+{
+       u_long tb;
+       u_long ticks;
+       int msr, scratch;
+       
+       asm volatile ("mfmsr %0; andi. %1,%0,%2; mtmsr %1"
+                     : "=r"(msr), "=r"(scratch) : "K"((u_short)~PSL_EE));
+       asm ("mftb %0" : "=r"(tb));
+       ticks = (tb - lasttb) * ns_per_tick;
+       *tvp = time;
+       asm volatile ("mtmsr %0" :: "r"(msr));
+       ticks /= 1000;
+       tvp->tv_usec += ticks;
+       while (tvp->tv_usec > 1000000) {
+               tvp->tv_usec -= 1000000;
+               tvp->tv_sec++;
+       }
+}
+
+/*
+ * Wait for about n microseconds (at least!).
+ */
+void
+delay(n)
+       unsigned n;
+{
+       u_quad_t tb;
+       u_long tbh, tbl, scratch;
+       
+       tb = mftb();
+       tb += (n * 1000 + ns_per_tick - 1) / ns_per_tick;
+       tbh = tb >> 32;
+       tbl = tb;
+       asm ("1: mftbu %0; cmpw %0,%1; blt 1b; bgt 2f; mftb %0; cmpw %0,%2; blt 1b; 2:"
+            :: "r"(scratch), "r"(tbh), "r"(tbl));
+}
+
+/*
+ * Nothing to do.
+ */
+void
+setstatclockrate(arg)
+       int arg;
+{
+       /* Do nothing */
+}
diff --git a/sys/arch/powerpc/powerpc/conf.c b/sys/arch/powerpc/powerpc/conf.c
new file mode 100644 (file)
index 0000000..ec1791e
--- /dev/null
@@ -0,0 +1,257 @@
+/*     $NetBSD: conf.c,v 1.2 1996/10/16 17:26:19 ws Exp $      */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/param.h>
+#include <sys/buf.h>
+#include <sys/conf.h>
+#include <sys/ioctl.h>
+#include <sys/systm.h>
+#include <sys/tty.h>
+#include <sys/vnode.h>
+
+#include "ofdisk.h"
+bdev_decl(ofd);
+bdev_decl(sw);
+
+struct bdevsw bdevsw[] = {
+       bdev_notdef(),                  /* 0 */
+       bdev_swap_init(1,sw),           /* 1: swap pseudo device */
+       bdev_notdef(),                  /* 2 SCSI tape */
+       bdev_notdef(),                  /* 3 SCSI CD-ROM */
+       bdev_disk_init(NOFDISK,ofd),    /* 4: Openfirmware disk */
+};
+int nblkdev = sizeof bdevsw / sizeof bdevsw[0];
+
+cdev_decl(cn);
+cdev_decl(ctty);
+#define mmread mmrw
+#define        mmwrite mmrw
+cdev_decl(mm);
+#include "pty.h"
+#define        ptstty          ptytty
+#define        ptsioctl        ptyioctl
+cdev_decl(pts);
+#define        ptctty          ptytty
+#define        ptcioctl        ptyioctl
+cdev_decl(ptc);
+cdev_decl(log);
+cdev_decl(sw);
+#include "ofcons.h"
+cdev_decl(ofc);
+cdev_decl(ofd);
+#include "ofrtc.h"
+cdev_decl(ofrtc);
+
+#include <sd.h>
+#include <st.h>
+#include <cd.h>
+#include <vnd.h>
+cdev_decl(st);  
+cdev_decl(sd);
+cdev_decl(cd);
+cdev_decl(vnd);
+cdev_decl(ccd);
+
+dev_decl(filedesc,open);
+
+#include "bpfilter.h"
+cdev_decl(bpf); 
+
+#include "tun.h"
+cdev_decl(tun);
+cdev_decl(random); 
+
+#ifdef LKM
+#define NLKM 1
+#else
+#define NLKM 0
+#endif  
+cdev_decl(lkm);
+
+/* open, close, read, ioctl */
+cdev_decl(ipl);
+#ifdef IPFILTER
+#define NIPF 1
+#else   
+#define NIPF 0
+#endif  
+
+#define        cdev_rtc_init(c,n) { \
+       dev_init(c,n,open), dev_init(c,n,close), \
+       dev_init(c,n,read), dev_init(c,n,write), \
+       (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \
+       0, seltrue, (dev_type_mmap((*))) enodev }
+
+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(NOFCONS,ofc),     /* 7: Openfirmware console */
+        cdev_disk_init(NSD,sd),         /* 8: SCSI disk */
+        cdev_disk_init(NCD,cd),         /* 9: SCSI CD-ROM */
+        cdev_notdef(),                  /* 10 */
+        cdev_notdef(),                  /* 11 */
+        cdev_notdef(),                  /* 12 */
+       cdev_disk_init(NOFDISK,ofd),    /* 13: Openfirmware disk */
+        cdev_notdef(),                  /* 14 */
+        cdev_notdef(),                  /* 15 */
+        cdev_notdef(),                  /* 16 */
+       cdev_rtc_init(NOFRTC,ofrtc),    /* 17: Openfirmware RTC */
+        cdev_notdef(),                  /* 18 */
+        cdev_disk_init(NVND,vnd),       /* 19: vnode disk */
+        cdev_tape_init(NST,st),         /* 20: SCSI tape */
+        cdev_fd_init(1,filedesc),       /* 21: file descriptor pseudo-dev */
+        cdev_bpftun_init(NBPFILTER,bpf),/* 22: berkeley packet filter */
+        cdev_bpftun_init(NTUN,tun),     /* 23: network tunnel */
+        cdev_lkm_init(NLKM,lkm),        /* 24: loadable module driver */
+        cdev_notdef(),                  /* 25 */ 
+        cdev_notdef(),                  /* 26 */
+        cdev_notdef(),                  /* 27 */
+        cdev_notdef(),                  /* 28 */
+        cdev_notdef(),                  /* 29 */
+        cdev_notdef(),                  /* 30 */
+        cdev_notdef(),                  /* 31 */
+        cdev_notdef(),                  /* 32 */
+        cdev_lkm_dummy(),               /* 33 */
+        cdev_lkm_dummy(),               /* 34 */
+        cdev_lkm_dummy(),               /* 35 */
+        cdev_lkm_dummy(),               /* 36 */
+        cdev_lkm_dummy(),               /* 37 */
+        cdev_lkm_dummy(),               /* 38 */
+        cdev_gen_ipf(NIPF,ipl),         /* 39: IP filter */
+        cdev_random_init(1,random),     /* 40: random data source */
+};
+int nchrdev = sizeof cdevsw / sizeof cdevsw[0];
+
+int mem_no = 2;                                /* major number of /dev/mem */
+
+/*
+ * Swapdev is a fake device implemented in sw.c.
+ * It is used only internally to get to swstrategy.
+ */
+dev_t swapdev = makedev(1, 0);
+
+/*
+ * Check whether dev is /dev/mem or /dev/kmem.
+ */
+int
+iskmemdev(dev)
+       dev_t dev;
+{
+       return major(dev) == mem_no && minor(dev) < 2;
+}
+
+/*
+ * Check whether 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 */        NODEV,
+       /*  9 */        NODEV,
+       /* 10 */        NODEV,
+       /* 11 */        NODEV,
+       /* 12 */        NODEV,
+       /* 13 */        4,
+       /* 14 */        NODEV,
+       /* 15 */        NODEV,
+       /* 16 */        NODEV,
+       /* 10 */        NODEV,
+       /* 10 */        NODEV,
+       /* 10 */        NODEV,
+       /* 10 */        NODEV,
+       /* 10 */        NODEV,
+};
+
+/*
+ * Return accompanying block dev for a char dev.
+ */
+int
+chrtoblk(dev)
+       dev_t dev;
+{
+       int major;
+       
+       if ((major = major(dev)) >= nchrdev)
+               return NODEV;
+       if ((major = chrtoblktbl[major]) == NODEV)
+               return NODEV;
+       return makedev(major, minor(dev));
+}
+
+/*
+ * Convert a character device number to a block device number.
+ */
+dev_t
+blktochr(dev)
+       dev_t dev;
+{
+       int blkmaj = major(dev);
+       int i;
+
+       if (blkmaj >= nblkdev)
+               return (NODEV);
+       for (i = 0; i < sizeof(chrtoblktbl)/sizeof(chrtoblktbl[0]); i++)
+               if (blkmaj == chrtoblktbl[i])
+                       return (makedev(i, minor(dev)));
+       return (NODEV);
+}
+
+#include <dev/cons.h>
+
+cons_decl(ofc);
+
+struct consdev constab[] = {
+#if NOFCONS > 0
+       cons_init(ofc),
+#endif
+       { 0 },
+};
diff --git a/sys/arch/powerpc/powerpc/copyinstr.c b/sys/arch/powerpc/powerpc/copyinstr.c
new file mode 100644 (file)
index 0000000..e8a2ea4
--- /dev/null
@@ -0,0 +1,62 @@
+/*     $NetBSD: copyinstr.c,v 1.1 1996/09/30 16:34:42 ws Exp $ */
+
+/*-
+ * Copyright (C) 1995 Wolfgang Solfrank.
+ * Copyright (C) 1995 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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/errno.h>
+
+/*
+ * Emulate copyinstr.
+ */
+int
+copyinstr(udaddr, kaddr, len, done)
+       void *udaddr;
+       void *kaddr;
+       size_t len;
+       size_t *done;
+{
+       int c;
+       u_char *kp = kaddr;
+       int l;
+       
+       for (l = 0; len-- > 0; l++) {
+               if ((c = fubyte(udaddr++)) < 0) {
+                       *done = l;
+                       return EACCES;
+               }
+               if (!(*kp++ = c)) {
+                       *done = l + 1;
+                       return 0;
+               }
+       }
+       *done = l;
+       return ENAMETOOLONG;
+}
diff --git a/sys/arch/powerpc/powerpc/copyoutstr.c b/sys/arch/powerpc/powerpc/copyoutstr.c
new file mode 100644 (file)
index 0000000..730f16a
--- /dev/null
@@ -0,0 +1,61 @@
+/*     $NetBSD: copyoutstr.c,v 1.1 1996/09/30 16:34:42 ws Exp $        */
+
+/*-
+ * Copyright (C) 1995 Wolfgang Solfrank.
+ * Copyright (C) 1995 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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/errno.h>
+
+/*
+ * Emulate copyoutstr.
+ */
+int
+copyoutstr(kaddr, udaddr, len, done)
+       void *kaddr;
+       void *udaddr;
+       size_t len;
+       size_t *done;
+{
+       u_char *kp = kaddr;
+       int l;
+       
+       for (l = 0; len-- > 0; l++) {
+               if (subyte(udaddr++, *kp) < 0) {
+                       *done = l;
+                       return EACCES;
+               }
+               if (!*kp++) {
+                       *done = l + 1;
+                       return 0;
+               }
+       }
+       *done = l;
+       return ENAMETOOLONG;
+}
diff --git a/sys/arch/powerpc/powerpc/copystr.c b/sys/arch/powerpc/powerpc/copystr.c
new file mode 100644 (file)
index 0000000..0a5976d
--- /dev/null
@@ -0,0 +1,58 @@
+/*     $NetBSD: copystr.c,v 1.1 1996/09/30 16:34:43 ws Exp $   */
+
+/*-
+ * Copyright (C) 1995 Wolfgang Solfrank.
+ * Copyright (C) 1995 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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/errno.h>
+
+/*
+ * Emulate copyinstr.
+ */
+int
+copystr(kfaddr, kdaddr, len, done)
+       void *kfaddr;
+       void *kdaddr;
+       size_t len;
+       size_t *done;
+{
+       u_char *kfp = kfaddr;
+       u_char *kdp = kdaddr;
+       size_t l;
+       
+       for (l = 0; len-- > 0; l++) {
+               if (!(*kdp++ = *kfp++)) {
+                       *done = l + 1;
+                       return 0;
+               }
+       }
+       *done = l;
+       return ENAMETOOLONG;
+}
diff --git a/sys/arch/powerpc/powerpc/db_disasm.c b/sys/arch/powerpc/powerpc/db_disasm.c
new file mode 100644 (file)
index 0000000..c856ea9
--- /dev/null
@@ -0,0 +1,857 @@
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/proc.h>
+
+#include <machine/db_machdep.h>
+
+#include <ddb/db_access.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_variables.h>
+#include <ddb/db_interface.h>
+
+enum function_mask {
+       Op_A    =       0x00000001,
+       Op_B    =       0x00000002,
+       Op_BI   =       0x00000004,
+       Op_BO   =       0x00000008,
+       Op_CRM  =       0x00000010,
+       Op_D    =       0x00000020, /* yes, Op_S and Op_D are the same */
+       Op_S    =       0x00000020,
+       Op_FM   =       0x00000040,
+       Op_IMM  =       0x00000080,
+       Op_LK   =       0x00000100,
+       Op_Rc   =       0x00000200,
+       Op_AA   =       Op_LK | Op_Rc, /* kludge (reduce Op_s) */
+       Op_LKM  =       Op_AA,
+       Op_RcM  =       Op_AA,
+       Op_OE   =       0x00000400,
+       Op_SR   =       0x00000800,
+       Op_TO   =       0x00001000,
+       Op_sign =       0x00002000,
+       Op_const =      0x00004000,
+       Op_SIMM =       Op_const | Op_sign,
+       Op_UIMM =       Op_const,
+       Op_d    =       Op_const | Op_sign,
+       Op_crbA =       0x00008000,
+       Op_crbB =       0x00010000,
+       Op_crbD =       0x00020000,
+       Op_crfD =       0x00040000,
+       Op_crfS =       0x00080000,
+       Op_ds   =       0x00100000,
+       Op_me   =       0x00200000,
+       Op_spr  =       0x00400000,
+       Op_tbr  =       0x00800000,
+
+       Op_L    =       0x01000000,
+       Op_BD   =       0x02000000,
+       Op_LI   =       0x04000000,
+       Op_C    =       0x08000000,
+
+       Op_NB   =       0x10000000,
+
+       Op_sh_mb_sh =   0x20000000,
+       Op_sh   =       0x40000000,
+       Op_SH   =       Op_sh | Op_sh_mb_sh,
+       Op_mb   =       0x80000000,
+       Op_MB   =       Op_mb | Op_sh_mb_sh,
+       Op_ME   =       Op_MB,
+
+};
+
+struct opcode {
+       char *name;
+       u_int32_t mask;
+       u_int32_t code;
+       enum function_mask func;
+};
+
+typedef u_int32_t instr_t;
+typedef void (op_class_func) (instr_t);
+
+void dis_ppc(const struct opcode *opcodeset, instr_t instr);
+
+op_class_func op_ill, op_base;
+op_class_func op_cl_x13, op_cl_x1e, op_cl_x1f;
+op_class_func op_cl_x3a, op_cl_x3b;
+op_class_func op_cl_x3e, op_cl_x3f;
+
+op_class_func *opcodes_base[] = {
+/*x00*/        op_ill,         op_ill,         op_base,        op_ill,
+/*x04*/        op_ill,         op_ill,         op_ill,         op_base,
+/*x08*/        op_base,        op_base,        op_ill,         op_base,        
+/*x0C*/ op_base,       op_base,        op_base/*XXX*/, op_base/*XXX*/,
+/*x10*/ op_base,       op_base,        op_base,        op_cl_x13,
+/*x14*/        op_base,        op_base,        op_ill,         op_base,
+/*x18*/        op_base,        op_base,        op_base,        op_base,
+/*x1C*/ op_base,       op_base,        op_cl_x1e,      op_cl_x1f,
+/*x20*/        op_base,        op_base,        op_base,        op_base,
+/*x24*/        op_base,        op_base,        op_base,        op_base,
+/*x28*/        op_base,        op_base,        op_base,        op_base,
+/*x2C*/        op_base,        op_base,        op_base,        op_base,
+/*x30*/        op_base,        op_base,        op_base,        op_base,
+/*x34*/        op_base,        op_base,        op_base,        op_base,
+/*x38*/ op_ill,                op_ill,         op_cl_x3a,      op_cl_x3b,
+/*x3C*/        op_ill,         op_ill,         op_cl_x3e,      op_cl_x3f
+};
+
+
+/* This table could be modified to make significant the "reserved" fields
+ * of the opcodes, But I didn't feel like it when typing in the table,
+ * I would recommend that this table be looked over for errors, 
+ * This was derived from the table in Appendix A.2 of (Mot part # MPCFPE/AD)
+ * PowerPC Microprocessor Family: The Programming Environments
+ */
+       
+const struct opcode opcodes[] = {
+       { "tdi",        0xfc000000, 0x08000000, Op_TO | Op_A | Op_SIMM },
+       { "twi",        0xfc000000, 0x0c000000, Op_TO | Op_A | Op_SIMM },
+       { "mulli",      0xfc000000, 0x1c000000, Op_D | Op_A | Op_SIMM },
+       { "subfic",     0xfc000000, 0x20000000, Op_D | Op_A | Op_SIMM },
+       { "cmpli",      0xfc000000, 0x28000000, Op_crfD | Op_L | Op_A | Op_SIMM },
+       { "cmpi",       0xfc000000, 0x2c000000, Op_crfD | Op_L | Op_A | Op_SIMM },
+       { "addic",      0xfc000000, 0x30000000, Op_D | Op_A | Op_SIMM },
+       { "addic.",     0xfc000000, 0x34000000, Op_D | Op_A | Op_SIMM },
+       { "addi",       0xfc000000, 0x38000000, Op_D | Op_A | Op_SIMM },
+       { "addis",      0xfc000000, 0x3c000000, Op_D | Op_A | Op_SIMM },
+       { "bc",         0xfc000000, 0x40000000, Op_BO | Op_BI | Op_BD | Op_AA | Op_LK },
+       { "sc",         0xffffffff, 0x44000002, Op_BO | Op_BI | Op_BD | Op_AA | Op_LK },
+       { "b",          0xfc000000, 0x48000000, Op_LI | Op_AA | Op_LK },
+
+       { "rlwimi",     0xfc000000, 0x50000000, Op_S | Op_A | Op_SH | Op_MB | Op_ME | Op_Rc },
+       { "rlwinmi",    0xfc000000, 0x54000000, Op_S | Op_A | Op_SH | Op_MB | Op_ME | Op_Rc },
+       { "rlwnmi",     0xfc000000, 0x5C000000, Op_S | Op_A | Op_SH | Op_MB | Op_ME | Op_Rc },
+
+       { "ori",        0xfc000000, 0x60000000, Op_S | Op_A | Op_UIMM },
+       { "oris",       0xfc000000, 0x64000000, Op_S | Op_A | Op_UIMM },
+       { "xori",       0xfc000000, 0x68000000, Op_S | Op_A | Op_UIMM },
+       { "xoris",      0xfc000000, 0x6C000000, Op_S | Op_A | Op_UIMM },
+
+       { "andi.",      0xfc000000, 0x70000000, Op_S | Op_A | Op_UIMM },
+       { "andis.",     0xfc000000, 0x74000000, Op_S | Op_A | Op_UIMM },
+
+       { "lwz",        0xfc000000, 0x80000000, Op_D | Op_A | Op_d },
+       { "lwzu",       0xfc000000, 0x84000000, Op_D | Op_A | Op_d },
+       { "lbz",        0xfc000000, 0x88000000, Op_D | Op_A | Op_d },
+       { "lbzu",       0xfc000000, 0x8c000000, Op_D | Op_A | Op_d },
+       { "stw",        0xfc000000, 0x90000000, Op_S | Op_A | Op_d },
+       { "stwu",       0xfc000000, 0x94000000, Op_S | Op_A | Op_d },
+       { "stb",        0xfc000000, 0x98000000, Op_S | Op_A | Op_d },
+       { "stbu",       0xfc000000, 0x9c000000, Op_S | Op_A | Op_d },
+
+       { "lhz",        0xfc000000, 0xa0000000, Op_D | Op_A | Op_d },
+       { "lhzu",       0xfc000000, 0xa4000000, Op_D | Op_A | Op_d },
+       { "lha",        0xfc000000, 0xa8000000, Op_D | Op_A | Op_d },
+       { "lhau",       0xfc000000, 0xac000000, Op_D | Op_A | Op_d },
+       { "sth",        0xfc000000, 0xb0000000, Op_S | Op_A | Op_d },
+       { "sthu",       0xfc000000, 0xb4000000, Op_S | Op_A | Op_d },
+       { "lmw",        0xfc000000, 0xb8000000, Op_D | Op_A | Op_d },
+       { "stmw",       0xfc000000, 0xbc000000, Op_S | Op_A | Op_d },
+
+       { "lfs",        0xfc000000, 0xc0000000, Op_D | Op_A | Op_d },
+       { "lfsu",       0xfc000000, 0xc4000000, Op_D | Op_A | Op_d },
+       { "lfd",        0xfc000000, 0xc8000000, Op_D | Op_A | Op_d },
+       { "lfdu",       0xfc000000, 0xcc000000, Op_D | Op_A | Op_d },
+
+       { "stfs",       0xfc000000, 0xd0000000, Op_S | Op_A | Op_d },
+       { "stfsu",      0xfc000000, 0xd4000000, Op_S | Op_A | Op_d },
+       { "stfd",       0xfc000000, 0xd8000000, Op_S | Op_A | Op_d },
+       { "stfdu",      0xfc000000, 0xdc000000, Op_S | Op_A | Op_d },
+       { "",           0x0,            0x0, 0 }
+
+};
+/* 13 * 4 = 4c */
+const struct opcode opcodes_13[] = {
+/* 0x13 << 2 */
+       { "mcrf",       0xfc0007fe, 0x4c000000, Op_crfD | Op_crfS },
+       { "bclr",       0xfc0007fe, 0x4c000020, Op_BO | Op_BI | Op_LK },
+       { "crnor",      0xfc0007fe, 0x4c000042, Op_crbD | Op_crbA | Op_crbB },
+       { "rfi",        0xfc0007fe, 0x4c000064, 0 },
+       { "crandc",     0xfc0007fe, 0x4c000102, Op_BO | Op_BI | Op_LK },
+       { "isync",      0xfc0007fe, 0x4c00012c, 0 },
+       { "crxor",      0xfc0007fe, 0x4c000182, Op_crbD | Op_crbA | Op_crbB },
+       { "crnand",     0xfc0007fe, 0x4c0001c2, Op_crbD | Op_crbA | Op_crbB },
+       { "crand",      0xfc0007fe, 0x4c000202, Op_crbD | Op_crbA | Op_crbB },
+       { "creqv",      0xfc0007fe, 0x4c000242, Op_crbD | Op_crbA | Op_crbB },
+       { "crorc",      0xfc0007fe, 0x4c000342, Op_crbD | Op_crbA | Op_crbB },
+       { "cror",       0xfc0007fe, 0x4c000382, Op_crbD | Op_crbA | Op_crbB },
+       { "bcctr",      0xfc0007fe, 0x4c000420, Op_BO | Op_BI | Op_LK },
+       { "",           0x0,            0x0, 0 }
+};
+
+/* 1e * 4 = 78 */
+const struct opcode opcodes_1e[] = {
+       { "rldicl",     0xfc00001c, 0x78000000, Op_S | Op_A | Op_sh | Op_mb | Op_Rc },
+       { "rldicr",     0xfc00001c, 0x78000004, Op_S | Op_A | Op_sh | Op_me | Op_Rc },
+       { "rldic",      0xfc00001c, 0x78000008, Op_S | Op_A | Op_sh | Op_mb | Op_Rc },
+       { "rldimi",     0xfc00001c, 0x7800000c, Op_S | Op_A | Op_sh | Op_mb | Op_Rc },
+       { "rldcl",      0xfc00003e, 0x78000010, Op_S | Op_A | Op_B | Op_mb | Op_Rc },
+       { "rldcr",      0xfc00003e, 0x78000012, Op_S | Op_A | Op_B | Op_me | Op_Rc },
+       { "",           0x0,            0x0, 0 }
+};
+
+/* 1f * 4 = 7c */
+const struct opcode opcodes_1f[] = {
+/* 1f << 2 */
+       { "cmp",        0xfc0007fe, 0x7c000000, Op_S | Op_A | Op_B | Op_me | Op_Rc },
+       { "tw",         0xfc0007fe, 0x7c000008, Op_TO | Op_A | Op_B },
+       { "subfc",      0xfc0003fe, 0x7c000010, Op_D | Op_A | Op_B | Op_OE | Op_Rc },
+       { "mulhdu",     0xfc0007fe, 0x7c000012, Op_D | Op_A | Op_B | Op_Rc },
+       { "addc",       0xfc0003fe, 0x7c000014, Op_D | Op_A | Op_B | Op_OE | Op_Rc },
+       { "mulhwu",     0xfc0007fe, 0x7c000016, Op_D | Op_A | Op_B | Op_Rc },
+
+       { "mfcr",       0xfc0007fe, 0x7c000026, Op_D },
+       { "lwarx",      0xfc0007fe, 0x7c000028, Op_D | Op_A | Op_B },
+       { "ldx",        0xfc0007fe, 0x7c00002a, Op_D | Op_A | Op_B },
+       { "lwzx",       0xfc0007fe, 0x7c00002c, Op_D | Op_A | Op_B },
+       { "slw",        0xfc0007fe, 0x7c000030, Op_D | Op_A | Op_B | Op_Rc },
+       { "cntlzw",     0xfc0007fe, 0x7c000034, Op_D | Op_A | Op_Rc },
+       { "sld",        0xfc0007fe, 0x7c000036, Op_D | Op_A | Op_B | Op_Rc },
+       { "and",        0xfc0007fe, 0x7c000038, Op_D | Op_A | Op_B | Op_Rc },
+       { "cmpl",       0xfc0007fe, 0x7c000040, Op_crfD | Op_L | Op_A | Op_B },
+       { "subf",       0xfc0007fe, 0x7c000050, Op_D | Op_A | Op_B | Op_OE | Op_Rc },
+       { "ldux",       0xfc0007fe, 0x7c00006a, Op_D | Op_A | Op_B },
+       { "dbcst",      0xfc0007fe, 0x7c00006c, Op_A | Op_B },
+       { "lwzux",      0xfc0007fe, 0x7c00006e, Op_D | Op_A | Op_B },
+       { "cntlzd",     0xfc0007fe, 0x7c000074, Op_S | Op_A | Op_Rc },
+       { "andc",       0xfc0007fe, 0x7c000078, Op_S | Op_A | Op_B | Op_Rc },
+       { "td",         0xfc0007fe, 0x7c000088, Op_TO | Op_A | Op_B },
+       { "mulhd",      0xfc0007fe, 0x7c000092, Op_D | Op_A | Op_B | Op_Rc },
+       { "mulhw",      0xfc0007fe, 0x7c000093, Op_D | Op_A | Op_B | Op_Rc },
+       { "mfmsr",      0xfc0007fe, 0x7c0000a6, Op_D },
+       { "ldarx",      0xfc0007fe, 0x7c0000a8, Op_D | Op_A | Op_B },
+       { "dcbf",       0xfc0007fe, 0x7c0000ac, Op_A | Op_B },
+       { "lbzx",       0xfc0007fe, 0x7c0000ae, Op_D | Op_A | Op_B },
+       { "neg",        0xfc0007fe, 0x7c0000d0, Op_D | Op_A | Op_OE | Op_Rc },
+       { "lbzux",      0xfc0007fe, 0x7c0000ee, Op_D | Op_A | Op_B },
+       { "nor",        0xfc0007fe, 0x7c0000f8, Op_S | Op_A | Op_B | Op_Rc },
+       { "subfe",      0xfc0007fe, 0x7c000110, Op_D | Op_A | Op_B | Op_OE | Op_Rc },
+       { "adde",       0xfc0007fe, 0x7c000114, Op_D | Op_A | Op_B | Op_OE | Op_Rc },
+       { "mtcrf",      0xfc0007fe, 0x7c000120, Op_S | Op_CRM },
+       { "mtmsr",      0xfc0007fe, 0x7c000124, Op_S },
+       { "stdx",       0xfc0007fe, 0x7c00012a, Op_S | Op_A | Op_B },
+       { "stwcx.",     0xfc0007ff, 0x7c00012d, Op_S | Op_A | Op_B },
+       { "stwx",       0xfc0007fe, 0x7c00012e, Op_S | Op_A | Op_B },
+       { "stdux",      0xfc0007fe, 0x7c00016a, Op_S | Op_A | Op_B },
+       { "stwux",      0xfc0007fe, 0x7c00016e, Op_S | Op_A | Op_B },
+       { "subfze",     0xfc0007fe, 0x7c000190, Op_D | Op_A | Op_OE | Op_Rc },
+       { "addze",      0xfc0007fe, 0x7c000194, Op_D | Op_A | Op_OE | Op_Rc },
+       { "mtsr",       0xfc0007fe, 0x7c0001a4, Op_S | Op_SR },
+       { "stdcx.",     0xfc0007ff, 0x7c0001ad, Op_S | Op_A | Op_B },
+       { "stbx",       0xfc0007fe, 0x7c0001ae, Op_S | Op_A | Op_B },
+       { "subfme",     0xfc0007fe, 0x7c0001d0, Op_D | Op_A | Op_OE | Op_Rc },
+       { "mulld",      0xfc0007fe, 0x7c0001d2, Op_D | Op_A | Op_B | Op_OE | Op_Rc },
+       { "addme",      0xfc0007fe, 0x7c0001d4, Op_D | Op_A | Op_OE | Op_Rc },
+       { "mullw",      0xfc0007fe, 0x7c0001d6, Op_D | Op_A | Op_B | Op_OE | Op_Rc },
+       { "mtsrin",     0xfc0007fe, 0x7c0001e4, Op_S | Op_B },
+       { "dcbtst",     0xfc0007fe, 0x7c0001ec, Op_A | Op_B },
+       { "stbux",      0xfc0007fe, 0x7c0001ee, Op_S | Op_A | Op_B },
+       { "add",        0xfc0007fe, 0x7c000214, Op_D | Op_A | Op_B | Op_OE | Op_Rc },
+       { "dcbt",       0xfc0007fe, 0x7c00022c, Op_A | Op_B },
+       { "lhzx",       0xfc0007ff, 0x7c00022f, Op_D | Op_A | Op_B },
+       { "eqv",        0xfc0007fe, 0x7c000238, Op_S | Op_A | Op_B | Op_Rc },
+       { "tlbie",      0xfc0007fe, 0x7c000264, Op_B },
+       { "eciwx",      0xfc0007fe, 0x7c00026c, Op_D | Op_A | Op_B },
+       { "lhzux",      0xfc0007fe, 0x7c00026e, Op_D | Op_A | Op_B },
+       { "xor",        0xfc0007fe, 0x7c000278, Op_S | Op_A | Op_B | Op_Rc },
+       { "mfspr",      0xfc0007fe, 0x7c0002a6, Op_D | Op_spr },
+       { "lhax",       0xfc0007fe, 0x7c0002aa, Op_D | Op_A | Op_B },
+       { "lhax",       0xfc0007fe, 0x7c0002ae, Op_D | Op_A | Op_B },
+       { "tlbia",      0xfc0007fe, 0x7c0002e4, 0 },
+       { "mftb",       0xfc0007fe, 0x7c0002e6, Op_D | Op_tbr },
+       { "lwaux",      0xfc0007fe, 0x7c0002e6, Op_D | Op_A | Op_B },
+       { "lhaux",      0xfc0007fe, 0x7c0002ee, Op_D | Op_A | Op_B },
+       { "sthx",       0xfc0007fe, 0x7c00032e, Op_S | Op_A | Op_B },
+       { "orc",        0xfc0007fe, 0x7c000338, Op_S | Op_A | Op_B | Op_Rc },
+       { "econwx",     0xfc0007fe, 0x7c00036c, Op_S | Op_A | Op_B | Op_Rc },
+       { "slbie",      0xfc0007fc, 0x7c000364, Op_B },
+       { "sthux",      0xfc0007fe, 0x7c00036e, Op_S | Op_A | Op_B },
+       { "or",         0xfc0007fe, 0x7c000378, Op_S | Op_A | Op_B | Op_Rc },
+       { "divdu",      0xfc0007fe, 0x7c000392, Op_D | Op_A | Op_B | Op_OE | Op_Rc },
+       { "divwu",      0xfc0007fe, 0x7c000396, Op_D | Op_A | Op_B | Op_OE | Op_Rc },
+       { "mtspr",      0xfc0007fe, 0x7c0003a6, Op_S | Op_spr },
+       { "dcbi",       0xfc0007fe, 0x7c0003ac, Op_A | Op_B },
+       { "nand",       0xfc0007fe, 0x7c0003b8, Op_S | Op_A | Op_B | Op_Rc },
+       { "divd",       0xfc0007fe, 0x7c0003d2, Op_S | Op_A | Op_B | Op_OE | Op_Rc },
+       { "divw",       0xfc0007fe, 0x7c0003d6, Op_S | Op_A | Op_B | Op_OE | Op_Rc },
+       { "slbia",      0xfc0007fe, 0x7c0003d4, Op_S | Op_A | Op_B | Op_OE | Op_Rc },
+       { "slbia",      0xfc0007fe, 0x7c0003e4, Op_S | Op_A | Op_B | Op_OE | Op_Rc },
+       { "mcrxr",      0xfc0007fe, 0x7c000400, Op_crfD },
+       { "lswx",       0xfc0007fe, 0x7c00042a, Op_D | Op_A | Op_B },
+       { "lwbrx",      0xfc0007fe, 0x7c00042c, Op_D | Op_A | Op_B },
+       { "lfsx",       0xfc0007fe, 0x7c00042e, Op_D | Op_A | Op_B },
+       { "srw",        0xfc0007fe, 0x7c000430, Op_S | Op_A | Op_B | Op_Rc },
+       { "srd",        0xfc0007fe, 0x7c000436, Op_S | Op_A | Op_B | Op_Rc },
+       { "tlbsync",    0xfc0007fe, 0x7c00046c, 0 },
+       { "lfsux",      0xfc0007fe, 0x7c00046e, Op_D | Op_A | Op_B },
+       { "mfsr",       0xfc0007fe, 0x7c0004a6, Op_D | Op_SR },
+       { "iswi",       0xfc0007fe, 0x7c0004a6, Op_D | Op_A | Op_NB },
+       { "sync",       0xfc0007fe, 0x7c0004ac, 0 },
+       { "lfdx",       0xfc0007fe, 0x7c0004ac, Op_D | Op_A | Op_B },
+       { "lfdux",      0xfc0007fe, 0x7c0004ec, Op_D | Op_A | Op_B },
+       { "mfsrin",     0xfc0007fe, 0x7c000526, Op_D | Op_B },
+       { "stswx",      0xfc0007fe, 0x7c00052a, Op_S | Op_A | Op_B },
+       { "stwbrx",     0xfc0007fe, 0x7c00052c, Op_S | Op_A | Op_B },
+       { "stfsx",      0xfc0007fe, 0x7c00052e, Op_S | Op_A | Op_B },
+       { "stfsux",     0xfc0007fe, 0x7c00056e, Op_S | Op_A | Op_B },
+       { "stswi",      0xfc0007fe, 0x7c0005aa, Op_S | Op_A | Op_NB },
+       { "stfdx",      0xfc0007fe, 0x7c0005ae, Op_S | Op_A | Op_B },
+       { "stfdx",      0xfc0007fe, 0x7c0005ae, Op_S | Op_A | Op_B },
+       { "stfdux",     0xfc0007fe, 0x7c0005ee, Op_S | Op_A | Op_B },
+       { "lhbrx",      0xfc0007fe, 0x7c00062c, Op_D | Op_A | Op_B },
+       { "sraw",       0xfc0007fe, 0x7c000630, Op_S | Op_A | Op_B },
+       { "srad",       0xfc0007fe, 0x7c000634, Op_S | Op_A | Op_B | Op_Rc},
+       { "srawi",      0xfc0007fe, 0x7c000670, Op_S | Op_A | Op_B | Op_Rc},
+/* ? */        { "sradix",     0xfc0007fc, 0x7c000674, Op_S | Op_A | Op_sh },
+       { "eieio",      0xfc0007fe, 0x7c0006ac, 0 },
+       { "sthbrx",     0xfc0007fe, 0x7c00072c, Op_S | Op_A | Op_B },
+       { "extsh",      0xfc0007fe, 0x7c000734, Op_S | Op_A | Op_B | Op_Rc },
+       { "extsb",      0xfc0007fe, 0x7c000774, Op_S | Op_A | Op_Rc },
+       { "icbi",       0xfc0007fe, 0x7c0007ac, Op_A | Op_B },
+
+       { "stfiwx",     0xfc0007fe, 0x7c0007ae, Op_S | Op_A | Op_B },
+       { "extsw",      0xfc0007fe, 0x7c0007b4, Op_S | Op_A | Op_Rc },
+       { "dcbz",       0xfc0007fe, 0x7c0007ec, Op_A | Op_B },
+       { "",           0x0,            0x0, 0 }
+};
+
+/* 3a * 4 = e8 */
+const struct opcode opcodes_3a[] = {
+       { "ld",         0xfc000003, 0xe8000000, Op_D | Op_A | Op_ds },
+       { "ldu",        0xfc000003, 0xe8000001, Op_D | Op_A | Op_ds },
+       { "lwa",        0xfc000003, 0xe8000002, Op_D | Op_A | Op_ds },
+       { "",           0x0,            0x0, 0 }
+};
+/* 3b * 4 = ec */
+const struct opcode opcodes_3b[] = {
+       { "fdisvs",     0xfc00003e, 0xec000024, Op_D | Op_A | Op_B | Op_Rc },
+       { "fsubs",      0xfc00003e, 0xec000028, Op_D | Op_A | Op_B | Op_Rc },
+
+       { "fadds",      0xfc00003e, 0xec00002a, Op_D | Op_A | Op_B | Op_Rc },
+       { "fsqrts",     0xfc00003e, 0xec00002c, Op_D | Op_B | Op_Rc },
+       { "fres",       0xfc00003e, 0xec000030, Op_D | Op_B | Op_Rc },
+       { "fmuls",      0xfc00003e, 0xec000032, Op_D | Op_A | Op_C | Op_Rc },
+       { "fmsubs",     0xfc00003e, 0xec000038, Op_D | Op_A | Op_B | Op_C | Op_Rc },
+       { "fmadds",     0xfc00003e, 0xec00003a, Op_D | Op_A | Op_B | Op_C | Op_Rc },
+       { "fnmsubs",    0xfc00003e, 0xec00003c, Op_D | Op_A | Op_B | Op_C | Op_Rc },
+       { "fnmadds",    0xfc00003e, 0xec00003e, Op_D | Op_A | Op_B | Op_C | Op_Rc },
+       { "",           0x0,            0x0, 0 }
+};
+/* 3e * 4 = f8 */
+const struct opcode opcodes_3e[] = {
+       { "std",        0xfc000003, 0xf8000000, Op_S | Op_A | Op_ds },
+       { "stdu",       0xfc000003, 0xf8000001, Op_S | Op_A | Op_ds },
+       { "",           0x0,            0x0, 0 }
+};
+
+/* 3f * 4 = fc */
+const struct opcode opcodes_3f[] = {
+       { "fcmpu",      0xfc0007fe, 0xfc000000, Op_crfD | Op_A | Op_B },
+       { "frsp",       0xfc0007fe, 0xfc000018, Op_D | Op_B | Op_Rc },
+/* ? */        { "fctiw",      0xfc0007fe, 0xfc00001c, Op_D | Op_B | Op_Rc },
+       { "fctiwz",     0xfc0007fe, 0xfc00001e, Op_D | Op_B | Op_Rc },
+
+       { "fdiv",       0xfc00003e, 0xfc000024, Op_D | Op_A | Op_B | Op_Rc },
+       { "fsub",       0xfc00003e, 0xfc000028, Op_D | Op_A | Op_B | Op_Rc },
+       { "fadd",       0xfc00003e, 0xfc00002a, Op_D | Op_A | Op_B | Op_Rc },
+       { "fsqrt",      0xfc00003e, 0xfc00002c, Op_D | Op_B | Op_Rc },
+       { "fsel",       0xfc00003e, 0xfc00002e, Op_D | Op_A | Op_B | Op_C | Op_Rc },
+       { "fmul",       0xfc00003e, 0xfc000032, Op_D | Op_A | Op_C | Op_Rc },
+       { "frsqrte",    0xfc00003e, 0xfc000034, Op_D | Op_B | Op_Rc },
+       { "fmsub",      0xfc00003e, 0xfc000038, Op_D | Op_A | Op_B | Op_C | Op_Rc },
+       { "fmadd",      0xfc00003e, 0xfc00003a, Op_D | Op_A | Op_B | Op_C | Op_Rc },
+       { "fnmsub",     0xfc00003e, 0xfc00003c, Op_D | Op_A | Op_B | Op_C | Op_Rc },
+       { "fnmadd",     0xfc00003e, 0xfc00003e, Op_D | Op_A | Op_B | Op_C | Op_Rc },
+
+       { "fcmpo",      0xfc0007fe, 0xfc000040, Op_crfD | Op_A | Op_B },
+       { "mtfsb1",     0xfc0007fe, 0xfc00004c, Op_crfD | Op_Rc },
+       { "fneg",       0xfc0007fe, 0xfc000050, Op_D | Op_B | Op_Rc },
+       { "mcrfs",      0xfc0007fe, 0xfc000080, Op_D | Op_B | Op_Rc },
+       { "mtfsb0",     0xfc0007fe, 0xfc00008c, Op_crfD | Op_Rc },
+       { "fmr",        0xfc0007fe, 0xfc000090, Op_D | Op_B | Op_Rc },
+       { "mtfsfi",     0xfc0007fe, 0xfc00010c, Op_crfD | Op_IMM | Op_Rc },
+
+       { "fnabs",      0xfc0007fe, 0xfc000110, Op_D | Op_B | Op_Rc },
+       { "fabs",       0xfc0007fe, 0xfc000210, Op_D | Op_B | Op_Rc },
+       { "mffs",       0xfc0007fe, 0xfc00048e, Op_D | Op_B | Op_Rc },
+       { "mtfsf",      0xfc0007fe, 0xfc00058e, Op_FM | Op_B | Op_Rc },
+       { "fctid",      0xfc0007fe, 0xfc00065c, Op_D | Op_B | Op_Rc },
+       { "fctidz",     0xfc0007fe, 0xfc00065e, Op_D | Op_B | Op_Rc },
+       { "fcfid",      0xfc0007fe, 0xfc00069c, Op_D | Op_B | Op_Rc },
+       { "",           0x0,            0x0, 0 }
+};
+
+/*
+typedef void (op_class_func) (instr_t);
+*/
+void
+op_ill(instr_t instr)
+{
+       db_printf("illegal instruction %x\n", instr);
+}
+
+u_int32_t
+extract_field(u_int32_t value, u_int32_t base, u_int32_t width)
+{
+       u_int32_t mask = (1 << width) - 1;
+       return ((value >> base) & mask);
+}
+
+const struct opcode * search_op(const struct opcode *);
+
+void
+disasm_fields(const struct opcode *popcode, instr_t instr, char *disasm_str)
+{
+       char * pstr;
+       enum function_mask func;
+
+       pstr = disasm_str;
+
+       func =  popcode->func;
+       if (func & Op_OE) {
+               u_int OE;
+               /* also for Op_S (they are the same) */
+               OE = extract_field(instr, 31 - 21, 1);
+               if (OE) {
+                       pstr += sprintf (pstr, "o");
+               }
+               func &= ~Op_D;
+       }
+       switch  (func & Op_LKM) {
+       case Op_Rc:
+               if (instr & 0x1) {
+                       pstr += sprintf (pstr,". ");
+               }
+               break;
+       case Op_AA:
+               if (instr & 0x2) {
+                       pstr += sprintf (pstr,"a");
+               }
+       case Op_LK:
+               if (instr & 0x1) {
+                       pstr += sprintf (pstr,"l ");
+               }
+               break;
+       default:
+               func &= ~Op_LKM;
+       }
+       pstr += sprintf (pstr, " ");
+       if (func & Op_D) {
+               u_int D;
+               /* also for Op_S (they are the same) */
+               D = extract_field(instr, 31 - 10, 5);
+               pstr += sprintf (pstr, "r%d, ", D);
+               func &= ~Op_D;
+       }
+       if (func & Op_crbD) {
+               u_int crbD;
+               crbD = extract_field(instr, 31 - 10, 5);
+               pstr += sprintf (pstr, "crb%d, ", crbD);
+               func &= ~Op_crbD;
+       }
+       if (func & Op_crfD) {
+               u_int crfD;
+               crfD = extract_field(instr, 31 - 8, 3);
+               pstr += sprintf (pstr, "crf%d, ", crfD);
+               func &= ~Op_crfD;
+       }
+       if (func & Op_L) {
+               u_int L;
+               L = extract_field(instr, 31 - 10, 1);
+               if (L) {
+                       pstr += sprintf (pstr, "L, ");
+               }
+               func &= ~Op_L;
+       }
+       if (func & Op_FM) {
+               u_int FM;
+               FM = extract_field(instr, 31 - 10, 8);
+               pstr += sprintf (pstr, "%d, ", FM);
+               func &= ~Op_FM;
+       }
+       if (func & Op_TO) {
+               u_int TO;
+               TO = extract_field(instr, 31 - 10, 1);
+               pstr += sprintf (pstr, "%d, ", TO);
+               func &= ~Op_TO;
+       }
+       if (func & Op_crfS) {
+               u_int crfS;
+               crfS = extract_field(instr, 31 - 13, 3);
+               pstr += sprintf (pstr, "%d, ", crfS);
+               func &= ~Op_crfS;
+       }
+       if (func & Op_BO) {
+               u_int BO;
+               BO = extract_field(instr, 31 - 10, 5);
+               pstr += sprintf (pstr ,"%d, ", BO);
+               func &= ~Op_BO;
+       }
+       if (func & Op_A) {
+               u_int A;
+               A = extract_field(instr, 31 - 15, 5);
+               pstr += sprintf (pstr, "r%d, ", A);
+               func &= ~Op_A;
+       }
+       if (func & Op_B) {
+               u_int B;
+               B = extract_field(instr, 31 - 20, 5);
+               pstr += sprintf (pstr, "r%d, ", B);
+               func &= ~Op_B;
+       }
+       if (func & Op_C) {
+               u_int C;
+               C = extract_field(instr, 31 - 25, 5);
+               pstr += sprintf (pstr, "r%d, ", C);
+               func &= ~Op_C;
+       }
+       if (func & Op_BI) {
+               u_int BI;
+               BI = extract_field(instr, 31 - 10, 5);
+               pstr += sprintf (pstr, "%d, ", BI);
+               func &= ~Op_BI;
+       }
+       if (func & Op_crbA) {
+               u_int crbA;
+               crbA = extract_field(instr, 31 - 15, 5);
+               pstr += sprintf (pstr, "%d, ", crbA);
+               func &= ~Op_crbA;
+       }
+       if (func & Op_crbB) {
+               u_int crbB;
+               crbB = extract_field(instr, 31 - 20, 5);
+               pstr += sprintf (pstr, "%d, ", crbB);
+               func &= ~Op_crbB;
+       }
+       if (func & Op_CRM) {
+               u_int CRM;
+               CRM = extract_field(instr, 31 - 19, 8);
+               pstr += sprintf (pstr, "0x%x, ", CRM);
+               func &= ~Op_CRM;
+       }
+       if (func & Op_LI) {
+               u_int LI;
+               LI = extract_field(instr, 31 - 29, 24);
+               pstr += sprintf (pstr, "0x%x, ", LI);
+               func &= ~Op_LI;
+       }
+       switch (func & Op_SIMM) {
+               u_int IMM;
+       case Op_SIMM: /* same as Op_d */
+               IMM = extract_field(instr, 31 - 31, 16);
+               if (IMM & 0x8000) {
+                       pstr += sprintf (pstr, "-");
+               }
+                       /* no break */
+               func &= ~Op_SIMM;
+       case Op_UIMM:
+               IMM = extract_field(instr, 31 - 31, 16);
+               pstr += sprintf (pstr, "0x%x, ", IMM);
+               func &= ~Op_UIMM;
+               break;
+       default:
+       }
+       if (func & Op_BD ) {
+               u_int BD;
+               BD = extract_field(instr, 31 - 29, 14);
+               pstr += sprintf (pstr, "0x%x, ", BD);
+               func &= ~Op_BD;
+       }
+       if (func & Op_ds ) {
+               u_int ds;
+               ds = extract_field(instr, 31 - 29, 14) << 2;
+               pstr += sprintf (pstr, "0x%x, ", ds);
+               func &= ~Op_ds;
+       }
+       if (func & Op_spr ) {
+               u_int spr;
+               u_int sprl;
+               u_int sprh;
+               char *reg;
+               sprh = extract_field(instr, 31 - 15, 5);
+               sprl = extract_field(instr, 31 - 20, 5);
+               spr = sprh << 5 | sprl;
+
+               /* this table could be written better */
+               switch (spr) {
+               case    1:
+                       reg = "xer";
+                       break;
+               case    8:
+                       reg = "lr";
+                       break;
+               case    9:
+                       reg = "ctr";
+                       break;
+               case    18:
+                       reg = "dsisr";
+                       break;
+               case    19:
+                       reg = "dar";
+                       break;
+               case    22:
+                       reg = "dec";
+                       break;
+               case    25:
+                       reg = "sdr1";
+                       break;
+               case    26:
+                       reg = "srr0";
+                       break;
+               case    27:
+                       reg = "srr1";
+                       break;
+               case    272:
+                       reg = "SPRG0";
+                       break;
+               case    273:
+                       reg = "SPRG1";
+                       break;
+               case    274:
+                       reg = "SPRG3";
+                       break;
+               case    275:
+                       reg = "SPRG3";
+                       break;
+               case    280:
+                       reg = "asr";
+                       break;
+               case    282:
+                       reg = "aer";
+                       break;
+               case    287:
+                       reg = "pvr";
+                       break;
+               case    528:
+                       reg = "ibat0u";
+                       break;
+               case    529:
+                       reg = "ibat0l";
+                       break;
+               case    530:
+                       reg = "ibat1u";
+                       break;
+               case    531:
+                       reg = "ibat1l";
+                       break;
+               case    532:
+                       reg = "ibat2u";
+                       break;
+               case    533:
+                       reg = "ibat2l";
+                       break;
+               case    534:
+                       reg = "ibat3u";
+                       break;
+               case    535:
+                       reg = "ibat3l";
+                       break;
+               case    536:
+                       reg = "dbat0u";
+                       break;
+               case    537:
+                       reg = "dbat0l";
+                       break;
+               case    538:
+                       reg = "dbat1u";
+                       break;
+               case    539:
+                       reg = "dbat1l";
+                       break;
+               case    540:
+                       reg = "dbat2u";
+                       break;
+               case    541:
+                       reg = "dbat2l";
+                       break;
+               case    542:
+                       reg = "dbat3u";
+                       break;
+               case    543:
+                       reg = "dbat3l";
+                       break;
+               case    1013:
+                       reg = "dabr";
+                       break;
+               default:
+                       reg = 0;
+               }
+               if (reg == 0) {
+                       pstr += sprintf (pstr, ", [unknown spr (%d)]", spr);
+               } else {
+                       pstr += sprintf (pstr, ", %s", reg);
+               }
+               func &= ~Op_spr;
+       }
+
+       if (func & Op_me) {
+               u_int me, mel, meh;
+               mel = extract_field(instr, 31 - 25, 4);
+               meh = extract_field(instr, 31 - 26, 1);
+               me = meh << 4 | mel;
+               pstr += sprintf (pstr, ", 0x%x", me);
+               func &= ~Op_me;
+       }
+       if ((func & Op_MB ) && (func & Op_sh_mb_sh)) {
+               u_int MB;
+               u_int ME;
+               MB = extract_field(instr, 31 - 20, 5);
+               pstr += sprintf (pstr, ", %d", MB);
+               ME = extract_field(instr, 31 - 25, 5);
+               pstr += sprintf (pstr, ", %d", ME);
+       }
+       if ((func & Op_SH ) && (func & Op_sh_mb_sh)) {
+               u_int SH;
+               SH = extract_field(instr, 31 - 20, 5);
+               pstr += sprintf (pstr, ", %d", SH);
+       }
+       if ((func & Op_sh ) && ! (func & Op_sh_mb_sh)) {
+               u_int sh, shl, shh;
+               shl = extract_field(instr, 31 - 19, 4);
+               shh = extract_field(instr, 31 - 20, 1);
+               sh = shh << 4 | shl;
+               pstr += sprintf (pstr, ", %d", sh);
+       }
+       if ((func & Op_mb ) && ! (func & Op_sh_mb_sh)) {
+               u_int mb, mbl, mbh;
+               mbl = extract_field(instr, 31 - 25, 4);
+               mbh = extract_field(instr, 31 - 26, 1);
+               mb = mbh << 4 | mbl;
+               pstr += sprintf (pstr, ", %d", mb);
+       }
+       if ((func & Op_me ) && ! (func & Op_sh_mb_sh)) {
+               u_int me, mel, meh;
+               mel = extract_field(instr, 31 - 25, 4);
+               meh = extract_field(instr, 31 - 26, 1);
+               me = meh << 4 | mel;
+               pstr += sprintf (pstr, ", %d", me);
+       }
+       if (func & Op_tbr ) {
+               u_int tbr;
+               u_int tbrl;
+               u_int tbrh;
+               char *reg;
+               tbrh = extract_field(instr, 31 - 15, 5);
+               tbrl = extract_field(instr, 31 - 20, 5);
+               tbr = tbrh << 5 | tbrl;
+               switch (tbr) {
+               case 268:
+                       reg = "tbl";
+                       break;
+               case 269:
+                       reg = "tbu";
+                       break;
+               default:
+                       reg = 0;
+               }
+               if (reg == 0) {
+                       pstr += sprintf (pstr, ", [unknown tbr %d ]", tbr);
+               } else {
+                       pstr += sprintf (pstr, ", %s", reg);
+               }
+               func &= ~Op_tbr;
+       }
+       if (func & Op_SR) {
+               u_int SR;
+               SR = extract_field(instr, 31 - 15, 3);
+               pstr += sprintf (pstr, ", sr%d", SR);
+               func &= ~Op_SR;
+       }
+       if (func & Op_NB) {
+               u_int NB;
+               NB = extract_field(instr, 31 - 20, 5);
+               if (NB == 0 ) {
+                       NB=32;
+               }
+               pstr += sprintf (pstr, ", %d", NB);
+               func &= ~Op_SR;
+       }
+       if (func & Op_IMM) {
+               u_int IMM;
+               IMM = extract_field(instr, 31 - 19, 4);
+               pstr += sprintf (pstr, ", %d", IMM);
+               func &= ~Op_SR;
+       }
+}
+
+void
+op_base(instr_t instr)
+{
+       dis_ppc (opcodes,instr);
+}
+
+void
+op_cl_x13(instr_t instr)
+{
+       dis_ppc (opcodes_13,instr);
+}
+
+void
+op_cl_x1e(instr_t instr)
+{
+       dis_ppc (opcodes_1e,instr);
+}
+
+void
+op_cl_x1f(instr_t instr)
+{
+       dis_ppc (opcodes_1f,instr);
+}
+
+void
+op_cl_x3a(instr_t instr)
+{
+       dis_ppc (opcodes_3a,instr);
+}
+
+void
+op_cl_x3b(instr_t instr)
+{
+       dis_ppc (opcodes_3b,instr);
+}
+
+void
+op_cl_x3e(instr_t instr)
+{
+       dis_ppc (opcodes_3e,instr);
+}
+
+void
+op_cl_x3f(instr_t instr)
+{
+       dis_ppc (opcodes_3f,instr);
+}
+
+void
+dis_ppc(const struct opcode *opcodeset, instr_t instr)
+{
+       const struct opcode *op;
+       int found = 0;
+       int i;
+       char disasm_str[30];
+
+       for (   i=0, op = &opcodeset[0];
+               found == 0 && op->mask != 0;
+               i++, op= &opcodeset[i] )
+       {
+               if ((instr & op->mask) == op->code) {
+                       found = 1;
+                       disasm_fields(op, instr, disasm_str);
+                       db_printf("%s%s",op->name, disasm_str);
+                       return;
+               }
+       }
+       op_ill(instr);
+}
+
+db_addr_t
+db_disasm(db_addr_t loc, boolean_t extended)
+{
+       int class;
+       instr_t opcode;
+       opcode = *(instr_t *)(loc);
+       class = opcode >> 26;
+       (opcodes_base[class])(opcode);
+
+       return loc + 4;
+}
diff --git a/sys/arch/powerpc/powerpc/db_interface.c b/sys/arch/powerpc/powerpc/db_interface.c
new file mode 100644 (file)
index 0000000..e4b1876
--- /dev/null
@@ -0,0 +1,13 @@
+
+#include <sys/param.h>
+#include <sys/proc.h>
+
+#include <machine/db_machdep.h>
+void
+Debugger()
+{
+       db_trap(T_BREAKPOINT);
+/*
+       __asm volatile ("tw 4,2,2");
+*/
+}
diff --git a/sys/arch/powerpc/powerpc/db_memrw.c b/sys/arch/powerpc/powerpc/db_memrw.c
new file mode 100644 (file)
index 0000000..e0a6c1f
--- /dev/null
@@ -0,0 +1,102 @@
+/*     $NetBSD: db_memrw.c,v 1.1 1996/02/22 23:23:35 gwr Exp $ */
+
+/* 
+ * Mach Operating System
+ * Copyright (c) 1992 Carnegie Mellon University
+ * All Rights Reserved.
+ * 
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ * 
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ * 
+ * Carnegie Mellon requests users of this software to return to
+ * 
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie Mellon 
+ * the rights to redistribute these changes.
+ */
+
+/*
+ * Interface to the debugger for virtual memory read/write.
+ * This is a simple version for kernels with writable text.
+ * For an example of read-only kernel text, see the file:
+ * sys/arch/sun3/sun3/db_memrw.c
+ *
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+
+#include <machine/db_machdep.h>
+
+#include <ddb/db_access.h>
+
+/*
+ * Read bytes from kernel address space for debugger.
+ */
+void
+db_read_bytes(addr, size, data)
+       vm_offset_t     addr;
+       register size_t size;
+       register char   *data;
+{
+       register 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 to kernel address space for debugger.
+ */
+void
+db_write_bytes(addr, size, data)
+       vm_offset_t     addr;
+       register size_t size;
+       register char   *data;
+{
+       register char   *dst = (char *)addr;
+
+       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/powerpc/powerpc/db_trace.c b/sys/arch/powerpc/powerpc/db_trace.c
new file mode 100644 (file)
index 0000000..0dcba16
--- /dev/null
@@ -0,0 +1,95 @@
+/*     $NetBSD: db_trace.c,v 1.15 1996/02/22 23:23:41 gwr Exp $        */
+
+/* 
+ * Mach Operating System
+ * Copyright (c) 1992 Carnegie Mellon University
+ * All Rights Reserved.
+ * 
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ * 
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ * 
+ * Carnegie Mellon requests users of this software to return to
+ * 
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie Mellon 
+ * the rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/proc.h>
+
+#include <machine/db_machdep.h>
+
+#include <ddb/db_access.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_variables.h>
+
+struct db_variable db_regs[] = { 
+       { "r1",  (int *) &ddb_regs.r1,  FCN_NULL },
+       { "r2",  (int *) &ddb_regs.r2,  FCN_NULL },
+       { "r3",  (int *) &ddb_regs.r3,  FCN_NULL },
+       { "r4",  (int *) &ddb_regs.r4,  FCN_NULL },
+       { "r5",  (int *) &ddb_regs.r5,  FCN_NULL },
+       { "r6",  (int *) &ddb_regs.r6,  FCN_NULL },
+       { "r7",  (int *) &ddb_regs.r7,  FCN_NULL },
+       { "r8",  (int *) &ddb_regs.r8,  FCN_NULL },
+       { "r9",  (int *) &ddb_regs.r9,  FCN_NULL },
+       { "r10", (int *) &ddb_regs.r10, FCN_NULL },
+       { "r11", (int *) &ddb_regs.r11, FCN_NULL },
+       { "r12", (int *) &ddb_regs.r12, FCN_NULL },
+       { "r13", (int *) &ddb_regs.r13, FCN_NULL },
+       { "r14", (int *) &ddb_regs.r13, FCN_NULL },
+       { "r15", (int *) &ddb_regs.r13, FCN_NULL },
+       { "r16", (int *) &ddb_regs.r13, FCN_NULL },
+       { "r17", (int *) &ddb_regs.r17, FCN_NULL },
+       { "r18", (int *) &ddb_regs.r18, FCN_NULL },
+       { "r19", (int *) &ddb_regs.r19, FCN_NULL },
+       { "r20", (int *) &ddb_regs.r20, FCN_NULL },
+       { "r21", (int *) &ddb_regs.r21, FCN_NULL },
+       { "r22", (int *) &ddb_regs.r22, FCN_NULL },
+       { "r23", (int *) &ddb_regs.r23, FCN_NULL },
+       { "r24", (int *) &ddb_regs.r24, FCN_NULL },
+       { "r25", (int *) &ddb_regs.r25, FCN_NULL },
+       { "r26", (int *) &ddb_regs.r26, FCN_NULL },
+       { "r27", (int *) &ddb_regs.r27, FCN_NULL },
+       { "r28", (int *) &ddb_regs.r28, FCN_NULL },
+       { "r29", (int *) &ddb_regs.r29, FCN_NULL },
+       { "r30", (int *) &ddb_regs.r30, FCN_NULL },
+       { "r31", (int *) &ddb_regs.r31, FCN_NULL },
+       { "r32", (int *) &ddb_regs.r32, FCN_NULL },
+       { "iar", (int *) &ddb_regs.iar, FCN_NULL },
+};
+struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
+
+extern label_t *db_recover;
+
+/*
+ *     Frame tracing.
+ */
+void
+db_stack_trace_cmd(addr, have_addr, count, modif)
+       db_expr_t       addr;
+       int             have_addr;
+       db_expr_t       count;
+       char            *modif;
+{
+       int i, val, nargs, spa;
+       db_addr_t       regp;
+       char *          name;
+       boolean_t       kernel_only = TRUE;
+       boolean_t       trace_thread = FALSE;
+
+       db_printf("not supported");
+}
+
diff --git a/sys/arch/powerpc/powerpc/disksubr.c b/sys/arch/powerpc/powerpc/disksubr.c
new file mode 100644 (file)
index 0000000..23a9969
--- /dev/null
@@ -0,0 +1,405 @@
+/*     $NetBSD: disksubr.c,v 1.1 1996/09/30 16:34:43 ws Exp $  */
+
+/*
+ * Copyright (C) 1996 Wolfgang Solfrank.
+ * Copyright (C) 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/param.h>
+#include <sys/buf.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/disk.h>
+#include <sys/disklabel.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/stat.h>
+#include <sys/systm.h>
+
+static inline unsigned short get_short __P((void *p));
+static inline unsigned long get_long __P((void *p));
+static int get_netbsd_label __P((dev_t dev, void (*strat)(struct buf *),
+                                struct disklabel *lp, daddr_t bno));
+static int mbr_to_label __P((dev_t dev, void (*strat)(struct buf *),
+                            daddr_t bno, struct disklabel *lp,
+                            unsigned short *pnpart,
+                            struct cpu_disklabel *osdep, daddr_t off));
+
+/*
+ * Little endian access routines
+ */
+static inline unsigned short
+get_short(p)
+       void *p;
+{
+       unsigned char *cp = p;
+
+       return cp[0] | (cp[1] << 8);
+}
+
+static inline unsigned long
+get_long(p)
+       void *p;
+{
+       unsigned char *cp = p;
+
+       return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24);
+}
+
+/*
+ * Get real NetBSD disk label
+ */
+static int
+get_netbsd_label(dev, strat, lp, bno)
+       dev_t dev;
+       void (*strat)();
+       struct disklabel *lp;
+       daddr_t bno;
+{
+       struct buf *bp;
+       struct disklabel *dlp;
+
+       /* get a buffer and initialize it */
+       bp = geteblk((int)lp->d_secsize);
+       bp->b_dev = dev;
+
+       /* Now get the label block */
+       bp->b_blkno = bno + LABELSECTOR;
+       bp->b_bcount = lp->d_secsize;
+       bp->b_flags = B_BUSY | B_READ;
+       bp->b_cylinder = bp->b_blkno / (lp->d_secsize / DEV_BSIZE) / lp->d_secpercyl;
+       (*strat)(bp);
+
+       if (biowait(bp))
+               goto done;
+
+       for (dlp = (struct disklabel *)bp->b_data;
+            dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof (*dlp));
+            dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
+               if (dlp->d_magic == DISKMAGIC
+                   && dlp->d_magic2 == DISKMAGIC
+                   && dlp->d_npartitions <= MAXPARTITIONS
+                   && dkcksum(dlp) == 0) {
+                       *lp = *dlp;
+                       brelse(bp);
+                       return 1;
+               }
+       }
+done:
+       bp->b_flags |= B_INVAL;
+       brelse(bp);
+       return 0;
+}
+
+/*
+ * Construct disklabel entries from partition entries.
+ */
+static int
+mbr_to_label(dev, strat, bno, lp, pnpart, osdep, off)
+       dev_t dev;
+       void (*strat)();
+       daddr_t bno;
+       struct disklabel *lp;
+       unsigned short *pnpart;
+       struct cpu_disklabel *osdep;
+       daddr_t off;
+{
+       static int recursion = 0;
+       struct mbr_partition *mp;
+       struct partition *pp;
+       struct buf *bp;
+       int i, found = 0;
+
+       /* Check for recursion overflow. */
+       if (recursion > MAXPARTITIONS)
+               return 0;
+
+       /*
+        * Extended partitions seem to be relative to their first occurence?
+        */
+       if (recursion++ == 1)
+               off = bno;
+
+       /* get a buffer and initialize it */
+       bp = geteblk((int)lp->d_secsize);
+       bp->b_dev = dev;
+
+       /* Now get the MBR */
+       bp->b_blkno = bno;
+       bp->b_bcount = lp->d_secsize;
+       bp->b_flags = B_BUSY | B_READ;
+       bp->b_cylinder = bp->b_blkno / (lp->d_secsize / DEV_BSIZE) / lp->d_secpercyl;
+       (*strat)(bp);
+
+       if (biowait(bp))
+               goto done;
+
+       if (get_short(bp->b_data + MBRMAGICOFF) != MBRMAGIC)
+               goto done;
+
+       /* Extract info from MBR partition table */
+       mp = (struct mbr_partition *)(bp->b_data + MBRPARTOFF);
+       for (i = 0; i < NMBRPART; i++, mp++) {
+               if (get_long(&mp->mbr_size)) {
+                       switch (mp->mbr_type) {
+                       case MBR_EXTENDED:
+                               if (*pnpart < MAXPARTITIONS) {
+                                       pp = lp->d_partitions + *pnpart;
+                                       bzero(pp, sizeof *pp);
+                                       pp->p_size = get_long(&mp->mbr_size);
+                                       pp->p_offset = off + get_long(&mp->mbr_start);
+                                       ++*pnpart;
+                               }
+                               if (found = mbr_to_label(dev, strat,
+                                                        off + get_long(&mp->mbr_start),
+                                                        lp, pnpart, osdep, off))
+                                       goto done;
+                               break;
+                       case MBR_NETBSD:
+                               /* Found the real NetBSD partition, use it */
+                               osdep->cd_start = off + get_long(&mp->mbr_start);
+                               if (found = get_netbsd_label(dev, strat, lp, osdep->cd_start))
+                                       goto done;
+                               /* FALLTHROUGH */
+                       default:
+                               if (*pnpart < MAXPARTITIONS) {
+                                       pp = lp->d_partitions + *pnpart;
+                                       bzero(pp, sizeof *pp);
+                                       pp->p_size = get_long(&mp->mbr_size);
+                                       pp->p_offset = off + get_long(&mp->mbr_start);
+                                       ++*pnpart;
+                               }
+                               break;
+                       }
+               }
+       }
+done:
+       recursion--;
+       bp->b_flags |= B_INVAL;
+       brelse(bp);
+       return found;
+}
+
+/*
+ * Attempt to read a disk label from a device
+ * using the indicated strategy routine.
+ *
+ * If we can't find a NetBSD label, we attempt to fake one
+ * based on the MBR (and extended partition) information
+ */
+char *
+readdisklabel(dev, strat, lp, osdep)
+       dev_t dev;
+       void (*strat)();
+       struct disklabel *lp;
+       struct cpu_disklabel *osdep;
+{
+       struct mbr_partition *mp;
+       struct buf *bp;
+       char *msg = 0;
+       int i;
+
+       /* Initialize disk label with some defaults */
+       if (lp->d_secsize == 0)
+               lp->d_secsize = DEV_BSIZE;
+       if (lp->d_secpercyl == 0)
+               lp->d_secpercyl = 1;
+       if (lp->d_secperunit == 0)
+               lp->d_secperunit = 0x7fffffff;
+       lp->d_npartitions = RAW_PART + 1;
+       for (i = 0; i < MAXPARTITIONS; i++) {
+               if (i != RAW_PART) {
+                       lp->d_partitions[i].p_size = 0;
+                       lp->d_partitions[i].p_offset = 0;
+               }
+       }
+       if (lp->d_partitions[RAW_PART].p_size == 0) {
+               lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
+               lp->d_partitions[RAW_PART].p_offset = 0;
+       }
+
+       osdep->cd_start = -1;
+
+       mbr_to_label(dev, strat, MBRSECTOR, lp, &lp->d_npartitions, osdep, 0);
+       return 0;
+}
+
+/*
+ * Check new disk label for sensibility before setting it.
+ */
+int
+setdisklabel(olp, nlp, openmask, osdep)
+       struct disklabel *olp, *nlp;
+       u_long openmask;
+       struct cpu_disklabel *osdep;
+{
+       /* 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;
+
+       /* openmask parameter ignored */
+
+       *olp = *nlp;
+       return 0;
+}
+
+/*
+ * Write disk label back to device after modification.
+ */
+int
+writedisklabel(dev, strat, lp, osdep)
+       dev_t dev;
+       void (*strat)();
+       struct disklabel *lp;
+       struct cpu_disklabel *osdep;
+{
+       struct buf *bp;
+       int error;
+       struct disklabel label;
+
+       /*
+        * Try to re-read a disklabel, in case he changed the MBR.
+        */
+       label = *lp;
+       readdisklabel(dev, strat, &label, osdep);
+       if (osdep->cd_start < 0)
+               return EINVAL;
+
+       /* get a buffer and initialize it */
+       bp = geteblk(lp->d_secsize);
+       bp->b_dev = dev;
+
+       bp->b_blkno = osdep->cd_start + LABELSECTOR;
+       bp->b_cylinder = bp->b_blkno / (lp->d_secsize / DEV_BSIZE) / lp->d_secpercyl;
+       bp->b_bcount = lp->d_secsize;
+       bp->b_flags = B_BUSY | B_WRITE;
+
+       bcopy((caddr_t)lp, (caddr_t)bp->b_data, sizeof *lp);
+
+       (*strat)(bp);
+       error = biowait(bp);
+
+       bp->b_flags |= B_INVAL;
+       brelse(bp);
+
+       return error;
+}
+
+/*
+ * Determine the size of the transfer, and make sure it is
+ * within the boundaris 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 = lp->d_partitions + DISKPART(bp->b_dev);
+       int sz;
+
+       sz = howmany(bp->b_bcount, lp->d_secsize);
+
+       if (bp->b_blkno + sz > p->p_size) {
+               sz = p->p_size - bp->b_blkno;
+               if (sz == 0) {
+                       /* If axactly at end of disk, return EOF. */
+                       bp->b_resid = bp->b_bcount;
+                       goto done;
+               }
+               if (sz < 0) {
+                       /* If past end of disk, return EINVAL. */
+                       bp->b_error = EINVAL;
+                       goto bad;
+               }
+               /* Otherwise truncate request. */
+               bp->b_bcount = sz * lp->d_secsize;
+       }
+
+       /* calculate cylinder for disksort to order transfers with */
+       bp->b_cylinder = (bp->b_blkno + p->p_offset)
+                        / (lp->d_secsize / DEV_BSIZE) / lp->d_secpercyl;
+
+       return 1;
+
+bad:
+       bp->b_flags |= B_ERROR;
+done:
+       return 0;
+}
+
+extern int dumpsize;
+/*
+ * This is called by configure to set dumplo and dumpsize.
+ */
+void
+dumpconf()
+{
+       int nblks;              /* size of dump device */
+       int skip;
+       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);
+       if (nblks <= ctod(1))
+               return;
+
+       dumpsize = physmem;
+
+       /* Skip enough blocks at start of disk to preserve an eventual disklabel. */
+       skip = LABELSECTOR + 1;
+       skip += ctod(1) - 1;
+       skip = ctod(dtoc(skip));
+       if (dumplo < skip)
+               dumplo = skip;
+
+       /* Put dump at end of partition */
+       if (dumpsize > dtoc(nblks - dumplo))
+               dumpsize = dtoc(nblks - dumplo);
+       if (dumplo < nblks - ctod(dumpsize))
+               dumplo = nblks - ctod(dumpsize);
+}
diff --git a/sys/arch/powerpc/powerpc/fpu.c b/sys/arch/powerpc/powerpc/fpu.c
new file mode 100644 (file)
index 0000000..46e723d
--- /dev/null
@@ -0,0 +1,134 @@
+/*     $NetBSD: fpu.c,v 1.1 1996/09/30 16:34:44 ws Exp $       */
+
+/*
+ * Copyright (C) 1996 Wolfgang Solfrank.
+ * Copyright (C) 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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/proc.h>
+#include <sys/user.h>
+
+#include <machine/fpu.h>
+#include <machine/psl.h>
+
+void
+enable_fpu(p)
+       struct proc *p;
+{
+       int msr, scratch;
+       struct pcb *pcb = &p->p_addr->u_pcb;
+       struct trapframe *tf = trapframe(p);
+       
+       tf->srr1 |= PSL_FP;
+       if (!(pcb->pcb_flags & PCB_FPU)) {
+               bzero(&pcb->pcb_fpu, sizeof pcb->pcb_fpu);
+               pcb->pcb_flags |= PCB_FPU;
+       }
+       asm volatile ("mfmsr %0; ori %1,%0,%2; mtmsr %1; isync"
+                     : "=r"(msr), "=r"(scratch) : "K"(PSL_FP));
+       asm volatile ("lfd 0,0(%0); mtfsf 0xff,0" :: "b"(&pcb->pcb_fpu.fpcsr));
+       asm ("lfd 0,0(%0);"
+            "lfd 1,8(%0);"
+            "lfd 2,16(%0);"
+            "lfd 3,24(%0);"
+            "lfd 4,32(%0);"
+            "lfd 5,40(%0);"
+            "lfd 6,48(%0);"
+            "lfd 7,56(%0);"
+            "lfd 8,64(%0);"
+            "lfd 9,72(%0);"
+            "lfd 10,80(%0);"
+            "lfd 11,88(%0);"
+            "lfd 12,96(%0);"
+            "lfd 13,104(%0);"
+            "lfd 14,112(%0);"
+            "lfd 15,120(%0);"
+            "lfd 16,128(%0);"
+            "lfd 17,136(%0);"
+            "lfd 18,144(%0);"
+            "lfd 19,152(%0);"
+            "lfd 20,160(%0);"
+            "lfd 21,168(%0);"
+            "lfd 22,176(%0);"
+            "lfd 23,184(%0);"
+            "lfd 24,192(%0);"
+            "lfd 25,200(%0);"
+            "lfd 26,208(%0);"
+            "lfd 27,216(%0);"
+            "lfd 28,224(%0);"
+            "lfd 29,232(%0);"
+            "lfd 30,240(%0);"
+            "lfd 31,248(%0)" :: "b"(&pcb->pcb_fpu.fpr[0]));
+       asm volatile ("mtmsr %0; isync" :: "r"(msr));
+}
+
+void
+save_fpu(p)
+       struct proc *p;
+{
+       int msr, scratch;
+       struct pcb *pcb = &p->p_addr->u_pcb;
+       
+       asm volatile ("mfmsr %0; ori %1,%0,%2; mtmsr %1; isync"
+                     : "=r"(msr), "=r"(scratch) : "K"(PSL_FP));
+       asm ("stfd 0,0(%0);"
+            "stfd 1,8(%0);"
+            "stfd 2,16(%0);"
+            "stfd 3,24(%0);"
+            "stfd 4,32(%0);"
+            "stfd 5,40(%0);"
+            "stfd 6,48(%0);"
+            "stfd 7,56(%0);"
+            "stfd 8,64(%0);"
+            "stfd 9,72(%0);"
+            "stfd 10,80(%0);"
+            "stfd 11,88(%0);"
+            "stfd 12,96(%0);"
+            "stfd 13,104(%0);"
+            "stfd 14,112(%0);"
+            "stfd 15,120(%0);"
+            "stfd 16,128(%0);"
+            "stfd 17,136(%0);"
+            "stfd 18,144(%0);"
+            "stfd 19,152(%0);"
+            "stfd 20,160(%0);"
+            "stfd 21,168(%0);"
+            "stfd 22,176(%0);"
+            "stfd 23,184(%0);"
+            "stfd 24,192(%0);"
+            "stfd 25,200(%0);"
+            "stfd 26,208(%0);"
+            "stfd 27,216(%0);"
+            "stfd 28,224(%0);"
+            "stfd 29,232(%0);"
+            "stfd 30,240(%0);"
+            "stfd 31,248(%0)" :: "b"(&pcb->pcb_fpu.fpr[0]));
+       asm volatile ("mffs 0; stfd 0,0(%0)" :: "b"(&pcb->pcb_fpu.fpcsr));
+       asm volatile ("mtmsr %0; isync" :: "r"(msr));
+}
diff --git a/sys/arch/powerpc/powerpc/fubyte.c b/sys/arch/powerpc/powerpc/fubyte.c
new file mode 100644 (file)
index 0000000..e19219f
--- /dev/null
@@ -0,0 +1,46 @@
+/*     $NetBSD: fubyte.c,v 1.1 1996/09/30 16:34:45 ws Exp $    */
+
+/*-
+ * Copyright (C) 1993 Wolfgang Solfrank.
+ * Copyright (C) 1993 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+
+/*
+ * Emulate fubyte.
+ */
+int
+fubyte(addr)
+char *addr;
+{
+       unsigned char c;
+       
+       if (copyin(addr,&c,sizeof(c)))
+               return -1;
+       return c;
+}
diff --git a/sys/arch/powerpc/powerpc/fuswintr.c b/sys/arch/powerpc/powerpc/fuswintr.c
new file mode 100644 (file)
index 0000000..e97f743
--- /dev/null
@@ -0,0 +1,44 @@
+/*     $NetBSD: fuswintr.c,v 1.1 1996/09/30 16:34:45 ws Exp $  */
+
+/*-
+ * Copyright (C) 1994 Wolfgang Solfrank.
+ * Copyright (C) 1994 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+
+/*
+ * Emulate fuswintr
+ *
+ * Simply return fault for all cases
+ */
+int
+fuswintr(addr)
+       char *addr;
+{
+       return -1;
+}
diff --git a/sys/arch/powerpc/powerpc/genassym.c b/sys/arch/powerpc/powerpc/genassym.c
new file mode 100644 (file)
index 0000000..2b357d8
--- /dev/null
@@ -0,0 +1,78 @@
+/*     $NetBSD: genassym.c,v 1.1 1996/09/30 16:34:46 ws Exp $  */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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 <stdio.h>
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+
+#include <machine/pcb.h>
+#include <machine/pmap.h>
+
+int
+main()
+{
+#define        def(N,V)        printf("#define\t%s\t%d\n", #N, (V))
+#define        offsetof(s,f)   (&(((s *)0)->f))
+
+       def(FRAMELEN, FRAMELEN);
+       def(FRAME_0, offsetof(struct trapframe, fixreg[0]));
+       def(FRAME_1, offsetof(struct trapframe, fixreg[1]));
+       def(FRAME_2, offsetof(struct trapframe, fixreg[2]));
+       def(FRAME_3, offsetof(struct trapframe, fixreg[3]));
+       def(FRAME_LR, offsetof(struct trapframe, lr));
+       def(FRAME_CR, offsetof(struct trapframe, cr));
+       def(FRAME_CTR, offsetof(struct trapframe, ctr));
+       def(FRAME_XER, offsetof(struct trapframe, xer));
+       def(FRAME_SRR0, offsetof(struct trapframe, srr0));
+       def(FRAME_SRR1, offsetof(struct trapframe, srr1));
+       def(FRAME_DAR, offsetof(struct trapframe, dar));
+       def(FRAME_DSISR, offsetof(struct trapframe, dsisr));
+       def(FRAME_EXC, offsetof(struct trapframe, exc));
+
+       def(SFRAMELEN, roundup(sizeof(struct switchframe), 16));
+
+       def(PCB_PMR, offsetof(struct pcb, pcb_pmreal));
+       def(PCB_SP, offsetof(struct pcb, pcb_sp));
+       def(PCB_SPL, offsetof(struct pcb, pcb_spl));
+       def(PCB_FAULT, offsetof(struct pcb, pcb_onfault));
+
+       def(PM_USRSR, offsetof(struct pmap, pm_sr[USER_SR]));
+       def(PM_KERNELSR, offsetof(struct pmap, pm_sr[KERNEL_SR]));
+
+       def(P_FORW, offsetof(struct proc, p_forw));
+       def(P_BACK, offsetof(struct proc, p_back));
+       def(P_ADDR, offsetof(struct proc, p_addr));
+
+       return 0;
+}
diff --git a/sys/arch/powerpc/powerpc/in_cksum.c b/sys/arch/powerpc/powerpc/in_cksum.c
new file mode 100644 (file)
index 0000000..8992b3c
--- /dev/null
@@ -0,0 +1,84 @@
+/*     $NetBSD: in_cksum.c,v 1.1 1996/09/30 16:34:47 ws Exp $  */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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/mbuf.h>
+
+/*
+ * First cut for in_cksum.
+ * This code is in C and should be optimized for PPC later.
+ */
+#define        REDUCE          (sum = (sum & 0xffff) + (sum >> 16))
+#define        ROL             (sum = sum << 8)
+#define        ADDB            (ROL, sum += *w, byte_swapped ^= 1)
+#define        ADDS            (sum += *(u_short *)w)
+#define        SHIFT(n)        (w += (n), mlen -= (n))
+#define        ADDCARRY        do { while (sum > 0xffff) REDUCE; } while (0)
+
+int
+in_cksum(m, len)
+       struct mbuf *m;
+       int len;
+{
+       u_char *w;
+       u_int sum = 0;
+       int mlen;
+       int byte_swapped = 0;
+       
+       for (; m && len; m = m->m_next) {
+               if (m->m_len == 0)
+                       continue;
+               w = mtod(m, u_char *);
+               mlen = m->m_len;
+               if (len < mlen)
+                       mlen = len;
+               len -= mlen;
+               if ((long)w & 1) {
+                       REDUCE;
+                       ADDB;
+                       SHIFT(1);
+               }
+               while (mlen >= 2) {
+                       ADDS;
+                       SHIFT(2);
+               }
+               REDUCE;
+               if (mlen == 1)
+                       ADDB;
+       }
+       if (byte_swapped) {
+               REDUCE;
+               ROL;
+       }
+       ADDCARRY;
+       return sum ^ 0xffff;
+}
diff --git a/sys/arch/powerpc/powerpc/locore.S b/sys/arch/powerpc/powerpc/locore.S
new file mode 100644 (file)
index 0000000..a425049
--- /dev/null
@@ -0,0 +1,1254 @@
+/*     $NetBSD: locore.S,v 1.2 1996/10/16 19:33:09 ws Exp $    */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "machine/ipkdb.h"
+
+#include "assym.h"
+
+#include <sys/syscall.h>
+
+#include <machine/asm.h>
+#include <machine/param.h>
+#include <machine/pmap.h>
+#include <machine/psl.h>
+#include <machine/trap.h>
+
+/*
+ * Globals
+ */
+       .globl  _C_LABEL(esym),_C_LABEL(proc0paddr)
+       .data
+_C_LABEL(esym):        .long   0                       /* end of symbol table */
+_C_LABEL(proc0paddr):  .long   0               /* proc0 p_addr */
+idle_u:        .long   0                       /* fake uarea during idle after exit */
+openfirmware_entry:    .long   0               /* openfirmware entry point */
+
+/*
+ * Startup entry
+ */
+_ENTRY(_C_LABEL(kernel_text))
+_ENTRY(_ASM_LABEL(start))
+       .globl  start
+start:
+#ifdef FIREPOWERBUGS
+       mfmsr   0
+       andi.   0,0,PSL_IR|PSL_DR
+       beq     1f
+
+       bl      _C_LABEL(ofwr_init)
+1:
+#endif
+       li      0,0
+       mtmsr   0                       /* Disable FPU/MMU/exceptions */
+       isync
+
+/* compute end of kernel memory */
+       lis     8,_end@ha
+       addi    8,8,_end@l
+#if defined(DDB) || defined(KERNFS)
+       lwz     9,0(8)                  /* number of symbols */
+       add     8,8,9
+       lwzu    9,4(8)                  /* length of string table */
+       add     8,8,9
+       lis     9,_C_LABEL(esym)@ha
+       stw     8,_C_LABEL(esym)@l(9)           /* save for symbol handling */
+#endif
+       li      9,PGOFSET
+       add     8,8,9
+       andc    8,8,9
+       lis     9,_C_LABEL(OF_buf)@ha
+       stw     8,_C_LABEL(OF_buf)@l(9)
+       addi    8,8,NBPG
+       lis     9,idle_u@ha
+       stw     8,idle_u@l(9)
+       addi    8,8,USPACE              /* space for idle_u */
+       lis     9,_C_LABEL(proc0paddr)@ha
+       stw     8,_C_LABEL(proc0paddr)@l(9)
+       addi    1,8,USPACE-FRAMELEN     /* stackpointer for proc0 */
+       mr      4,1                     /* end of mem reserved for kernel */
+       xor     0,0,0
+       stwu    0,-16(1)                /* end of stack chain */
+       
+       lis     8,openfirmware_entry@ha
+       stw     5,openfirmware_entry@l(8)       /* save client interface handler */
+       lis     3,start@ha
+       addi    3,3,start@l
+       mr      5,6                     /* args string */
+       bl      _C_LABEL(initppc)
+       bl      _C_LABEL(main)
+       b       _C_LABEL(OF_exit)
+
+/*
+ * OpenFirmware entry point
+ */
+_ENTRY(_C_LABEL(openfirmware))
+       mflr    0                       /* save return address */
+       stw     0,4(1)
+       stwu    1,-16(1)                /* setup stack frame */
+
+       mfmsr   4                       /* save msr */
+       stw     4,8(1)
+
+       lis     4,openfirmware_entry@ha /* get firmware entry point */
+       lwz     4,openfirmware_entry@l(4)
+       mtlr    4
+
+       li      0,0                     /* turn off any ints/mmu/etc. */
+       mtmsr   0
+       isync
+
+       blrl                            /* call OpenFirmware */
+
+       lwz     4,8(1)                  /* restore msr */
+       mtmsr   4
+       isync
+
+       lwz     1,0(1)                  /* and return */
+       lwz     0,4(1)
+       mtlr    0
+       blr
+
+/*
+ * Switch to/from OpenFirmware real mode stack
+ *
+ * Note: has to be called as the very first thing in OpenFirmware interface routines.
+ * E.g.:
+ * int
+ * OF_xxx(arg1, arg2)
+ * type arg1, arg2;
+ * {
+ *     static struct {
+ *             char *name;
+ *             int nargs;
+ *             int nreturns;
+ *             char *method;
+ *             int arg1;
+ *             int arg2;
+ *             int ret;
+ *     } args = {
+ *             "xxx",
+ *             2,
+ *             1,
+ *     };
+ *
+ *     ofw_stack();
+ *     args.arg1 = arg1;
+ *     args.arg2 = arg2;
+ *     if (openfirmware(&args) < 0)
+ *             return -1;
+ *     return args.ret;
+ * }
+ */
+.lcomm firmstk,NBPG,8
+
+_ENTRY(_C_LABEL(ofw_stack))
+       mfmsr   8                       /* turn off interrupts */
+       andi.   0,8,~(PSL_EE|PSL_RI)@l
+       mtmsr   0
+       stw     8,4(1)                  /* abuse return address slot */
+
+       lwz     5,0(1)                  /* get length of stack frame */
+       subf    5,1,5
+
+       lis     7,firmstk+NBPG-8@ha
+       addi    7,7,firmstk+NBPG-8@l
+       lis     6,ofw_back@ha
+       addi    6,6,ofw_back@l
+       subf    4,5,7                   /* make room for stack frame on new stack */
+       stw     6,-4(7)                 /* setup return pointer */
+       stwu    1,-8(7)
+       
+       stw     7,-8(4)
+
+       addi    3,1,8
+       addi    1,4,-8
+       subi    5,5,8
+
+       b       _C_LABEL(ofbcopy)               /* and copy it */
+
+ofw_back:
+       lwz     1,0(1)                  /* get callers original stack pointer */
+
+       lwz     0,4(1)                  /* get saved msr from abused slot */
+       mtmsr   0
+       
+       lwz     1,0(1)                  /* return */
+       lwz     0,4(1)
+       mtlr    0
+       blr
+
+\f
+/*
+ * No processes are runnable, so loop waiting for one.
+ * Separate label here for accounting purposes.
+ */
+_C_LABEL(idle):
+       mfmsr   3
+       andi.   3,3,~PSL_EE@l           /* disable interrupts while manipulating runque */
+       mtmsr   3
+
+       lis     8,_C_LABEL(whichqs)@ha
+       lwz     9,_C_LABEL(whichqs)@l(8)
+
+       or.     9,9,9
+       bne-    _C_LABEL(sw1)                   /* at least one queue non-empty */
+       
+       ori     3,3,PSL_EE              /* reenable ints again */
+       mtmsr   3
+       isync
+       
+/* May do some power saving here? */
+
+       b       _C_LABEL(idle)
+
+/*
+ * switchexit gets called from cpu_exit to free the user structure
+ * and kernel stack of the current process.
+ */
+_ENTRY(_C_LABEL(switchexit))
+/* First switch to the idle pcb/kernel stack */
+       lis     6,idle_u@ha
+       lwz     6,idle_u@l(6)
+       lis     7,_C_LABEL(curpcb)@ha
+       stw     6,_C_LABEL(curpcb)@l(7)
+       addi    1,6,USPACE-16           /* 16 bytes are reserved at stack top */
+/* Now free the old user structure (args are already in r3, r4, r5) */
+       bl      _C_LABEL(kmem_free)
+/* Fall through to cpu_switch to actually select another proc */
+
+/*
+ * void cpu_switch(struct proc *p)
+ * Find a runnable process and switch to it.
+ */
+_ENTRY(_C_LABEL(cpu_switch))
+       mflr    0                       /* save lr */
+       stw     0,4(1)
+       stwu    1,-16(1)
+       stw     31,12(1)
+       stw     30,8(1)
+
+       mr      30,3
+       lis     3,_C_LABEL(curproc)@ha
+       xor     31,31,31
+       stw     31,_C_LABEL(curproc)@l(3)       /* Zero to not accumulate cpu time */
+       lis     3,_C_LABEL(curpcb)@ha
+       lwz     31,_C_LABEL(curpcb)@l(3)
+
+       xor     3,3,3
+       bl      _C_LABEL(splx)
+       stw     3,PCB_SPL(31)           /* save spl */
+
+/* Find a new process */
+       mfmsr   3
+       andi.   3,3,~PSL_EE@l           /* disable interrupts while manipulating runque */
+       mtmsr   3
+       isync
+
+       lis     8,_C_LABEL(whichqs)@ha
+       lwz     9,_C_LABEL(whichqs)@l(8)
+
+       or.     9,9,9
+       beq-    _C_LABEL(idle)                  /* all queues empty */
+_C_LABEL(sw1):
+       cntlzw  10,9
+       lis     4,_C_LABEL(qs)@ha
+       addi    4,4,_C_LABEL(qs)@l
+       slwi    3,10,3
+       add     3,3,4                   /* select queue */
+       
+       lwz     31,P_FORW(3)            /* unlink first proc from queue */
+       lwz     4,P_FORW(31)
+       stw     4,P_FORW(3)
+       stw     3,P_BACK(4)
+
+       cmpl    0,3,4                   /* queue empty? */
+       bne     1f
+
+       lis     3,0x80000000@ha
+       srw     3,3,10
+       andc    9,9,3
+       stw     9,_C_LABEL(whichqs)@l(8)                /* mark it empty */
+
+1:
+       xor     3,3,3
+       lis     4,_C_LABEL(want_resched)@ha
+       stw     3,_C_LABEL(want_resched)@l(4)   /* just did this resched thing */
+
+       stw     3,P_BACK(31)            /* probably superfluous */
+
+       lis     4,_C_LABEL(curproc)@ha
+       stw     31,_C_LABEL(curproc)@l(4)       /* record new process */
+
+       mfmsr   3
+       ori     3,3,PSL_EE              /* Now we can interrupt again */
+       mtmsr   3
+
+       cmpl    0,31,30                 /* is it the same process? */
+       beq     switch_return
+
+       or.     30,30,30                /* old process was exiting? */
+       beq     switch_exited
+
+       mfsr    10,USER_SR              /* save USER_SR for copyin/copyout */
+       mfcr    11                      /* save cr */
+       mr      12,2                    /* save r2 */
+       stwu    1,-SFRAMELEN(1)         /* still running on old stack */
+       stmw    10,8(1)
+       lwz     3,P_ADDR(30)
+       stw     1,PCB_SP(3)             /* save SP */
+
+switch_exited:
+       mfmsr   3
+       andi.   3,3,~PSL_EE@l           /* disable interrupts while actually switching */
+       mtmsr   3
+
+       lwz     4,P_ADDR(31)
+       lis     5,_C_LABEL(curpcb)@ha
+       stw     4,_C_LABEL(curpcb)@l(5)         /* indicate new pcb */
+
+       lwz     5,PCB_PMR(4)
+       lis     6,_C_LABEL(curpm)@ha
+       stwu    5,_C_LABEL(curpm)@l(6)          /* save real pmap pointer for spill fill */
+       stwcx.  5,0,6                   /* clear possible reservation */
+
+       addic.  5,5,64
+       li      6,0
+       mfsr    8,KERNEL_SR             /* save kernel SR */
+1:
+       addis   6,6,-0x10000000@ha      /* set new procs segment registers */
+       or.     6,6,6                   /* This is done from the real address pmap */
+       lwzu    7,-4(5)                 /* so we don't have to worry */
+       mtsrin  7,6                     /* about accessibility */
+       bne     1b
+       mtsr    KERNEL_SR,8             /* restore kernel SR */
+       isync
+
+       lwz     1,PCB_SP(4)             /* get new procs SP */
+
+       ori     3,3,PSL_EE              /* interrupts are okay again */
+       mtmsr   3
+
+       lmw     10,8(1)                 /* get other regs */
+       lwz     1,0(1)                  /* get saved SP */
+       mr      2,12                    /* get saved r2 */
+       mtcr    11                      /* get saved cr */
+       isync
+       mtsr    USER_SR,10              /* get saved USER_SR */
+       isync
+
+switch_return:
+       mr      30,7                    /* save proc pointer */
+       lwz     3,PCB_SPL(4)
+       bl      _C_LABEL(splx)
+
+       mr      3,30                    /* get curproc for special fork returns */
+
+       lwz     31,12(1)
+       lwz     30,8(1)
+       addi    1,1,16
+       lwz     0,4(1)
+       mtlr    0
+       blr
+
+\f
+/*
+ * Data used during primary/secondary traps/interrupts
+ */
+#define        tempsave        0x2e0           /* primary save area for trap handling */
+#define        disisave        0x3e0           /* primary save area for dsi/isi traps */
+#define        INTSTK  (8*1024)                /* 8K interrupt stack */
+       .data
+intstk:        .space  INTSTK                  /* interrupt stack */
+       .global _C_LABEL(intr_depth)
+_C_LABEL(intr_depth):
+       .long   -1                      /* in-use marker */
+#define        SPILLSTK 1024                   /* 1K spill stack */
+.lcomm spillstk,SPILLSTK,8
+
+/*
+ * This code gets copied to all the trap vectors
+ * (except ISI/DSI, the interrupts, and possibly the debugging traps when using IPKDB).
+ */
+       .text
+       .globl  _C_LABEL(trapcode),_C_LABEL(trapsize)
+_C_LABEL(trapcode):
+       mtsprg  1,1                     /* save SP */
+       stmw    28,tempsave(0)          /* free r28-r31 */
+       mflr    28                      /* save LR */
+       mfcr    29                      /* save CR */
+/* Test whether we already had PR set */
+       mfsrr1  31
+       mtcr    31
+       bc      4,17,1f                 /* branch if PSL_PR is clear */
+       lis     1,_C_LABEL(curpcb)@ha
+       lwz     1,_C_LABEL(curpcb)@l(1)
+       addi    1,1,USPACE              /* stack is top of user struct */
+1:
+       bla     s_trap
+_C_LABEL(trapsize) =   .-_C_LABEL(trapcode)
+
+/*
+ * Similar to the above for DSI
+ * Has to handle BAT spills
+ * and standard pagetable spills
+ */
+       .globl  _C_LABEL(dsitrap),_C_LABEL(dsisize)
+_C_LABEL(dsitrap):
+       stmw    28,disisave(0)          /* free r28-r31 */
+       mfcr    29                      /* save CR */
+       mfxer   30                      /* save XER */
+       mtsprg  2,30                    /* in SPRG2 */
+       mfsrr1  31                      /* test kernel mode */
+       mtcr    31
+       bc      12,17,1f                /* branch if PSL_PR is set */
+       mfdar   31                      /* get fault address */
+       rlwinm  31,31,7,25,28           /* get segment * 8 */
+       addis   31,31,_C_LABEL(battable)@ha
+       lwz     30,_C_LABEL(battable)@l(31)     /* get batu */
+       mtcr    30
+       bc      4,30,1f                 /* branch if supervisor valid is false */
+       lwz     31,_C_LABEL(battable)+4@l(31)   /* get batl */
+/* We randomly use the highest two bat registers here */
+       mftb    28
+       andi.   28,28,1
+       bne     2f
+       mtdbatu 2,30
+       mtdbatl 2,31
+       b       3f
+2:
+       mtdbatu 3,30
+       mtdbatl 3,31
+3:
+       mfsprg  30,2                    /* restore XER */
+       mtxer   30
+       mtcr    29                      /* restore CR */
+       lmw     28,disisave(0)          /* restore r28-r31 */
+       rfi                             /* return to trapped code */
+1:
+       mflr    28                      /* save LR */
+       bla     s_dsitrap
+_C_LABEL(dsisize) =    .-_C_LABEL(dsitrap)
+
+/*
+ * Similar to the above for ISI
+ */
+       .globl  _C_LABEL(isitrap),_C_LABEL(isisize)
+_C_LABEL(isitrap):
+       stmw    28,disisave(0)          /* free r28-r31 */
+       mflr    28                      /* save LR */
+       mfcr    29                      /* save CR */
+       mfsrr1  31                      /* test kernel mode */
+       mtcr    31
+       bc      12,17,1f                /* branch if PSL_PR is set */
+       mfsrr0  31                      /* get fault address */
+       rlwinm  31,31,7,25,28           /* get segment * 8 */
+       addis   31,31,_C_LABEL(battable)@ha
+       lwz     30,_C_LABEL(battable)@l(31)     /* get batu */
+       mtcr    30
+       bc      4,30,1f                 /* branch if supervisor valid is false */
+       mtibatu 3,30
+       lwz     30,_C_LABEL(battable)+4@l(31)   /* get batl */
+       mtibatl 3,30
+       mtcr    29                      /* restore CR */
+       lmw     28,disisave(0)          /* restore r28-r31 */
+       rfi                             /* return to trapped code */
+1:
+       bla     s_isitrap
+_C_LABEL(isisize) =    .-_C_LABEL(isitrap)
+
+/*
+ * This one for the external interrupt handler.
+ */
+       .globl  _C_LABEL(extint),_C_LABEL(extsize)
+_C_LABEL(extint):
+       mtsprg  1,1                     /* save SP */
+       stmw    28,tempsave(0)          /* free r28-r31 */
+       mflr    28                      /* save LR */
+       mfcr    29                      /* save CR */
+       mfxer   30                      /* save XER */
+       lis     1,intstk+INTSTK@ha      /* get interrupt stack */
+       addi    1,1,intstk+INTSTK@l
+       lwz     31,0(1)                 /* were we already running on intstk? */
+       addic.  31,31,1
+       stw     31,0(1)
+       beq     1f
+       mfsprg  1,1                     /* yes, get old SP */
+1:
+       ba      extintr
+_C_LABEL(extsize) =    .-_C_LABEL(extint)
+
+/*
+ * And this one for the decrementer interrupt handler.
+ */
+       .globl  _C_LABEL(decrint),_C_LABEL(decrsize)
+_C_LABEL(decrint):
+       mtsprg  1,1                     /* save SP */
+       stmw    28,tempsave(0)          /* free r28-r31 */
+       mflr    28                      /* save LR */
+       mfcr    29                      /* save CR */
+       mfxer   30                      /* save XER */
+       lis     1,intstk+INTSTK@ha      /* get interrupt stack */
+       addi    1,1,intstk+INTSTK@l
+       lwz     31,0(1)                 /* were we already running on intstk? */
+       addic.  31,31,1
+       stw     31,0(1)
+       beq     1f
+       mfsprg  1,1                     /* yes, get old SP */
+1:
+       ba      decrintr
+_C_LABEL(decrsize) =   .-_C_LABEL(decrint)
+
+/*
+ * Now the tlb software load for 603 processors:
+ * (Code essentially from the 603e User Manual, Chapter 5)
+ */
+#define        DMISS   976
+#define        DCMP    977
+#define        HASH1   978
+#define        HASH2   979
+#define        IMISS   980
+#define        ICMP    981
+#define        RPA     982
+
+#define        bdneq   bdnzf 2,
+#define        tlbli   .long   0x7c0007e4+0x800*
+#define        tlbld   .long   0x7c0007a4+0x800*
+
+       .globl  _C_LABEL(tlbimiss),_C_LABEL(tlbimsize)
+_C_LABEL(tlbimiss):
+       mfspr   2,HASH1                 /* get first pointer */
+       li      1,8
+       mfctr   0                       /* save counter */
+       mfspr   3,ICMP                  /* get first compare value */
+       addi    2,2,-8                  /* predec pointer */
+1:
+       mtctr   1                       /* load counter */
+2:
+       lwzu    1,8(2)                  /* get next pte */
+       cmpl    0,1,3                   /* see if found pte */
+       bdneq   2b                      /* loop if not eq */
+       bne     3f                      /* not found */
+       lwz     1,4(2)                  /* load tlb entry lower word */
+       andi.   3,1,8                   /* check G-bit */
+       bne     4f                      /* if guarded, take ISI */
+       mtctr   0                       /* restore counter */
+       mfspr   0,IMISS                 /* get the miss address for the tlbli */
+       mfsrr1  3                       /* get the saved cr0 bits */
+       mtcrf   0x80,3                  /* and restore */
+       ori     1,1,0x100               /* set the reference bit */
+       mtspr   RPA,1                   /* set the pte */
+       srwi    1,1,8                   /* get byte 7 of pte */
+       tlbli   0                       /* load the itlb */
+       stb     1,6(2)                  /* update page table */
+       rfi
+
+3:     /* not found in pteg */
+       andi.   1,3,0x40                /* have we already done second hash? */
+       bne     5f
+       mfspr   2,HASH2                 /* get the second pointer */
+       ori     3,3,0x40                /* change the compare value */
+       li      1,8
+       addi    2,2,-8                  /* predec pointer */
+       b       1b
+4:     /* guarded */
+       mfsrr1  3
+       andi.   2,3,0xffff              /* clean upper srr1 */
+       addis   2,2,0x800               /* set srr<4> to flag prot violation */
+       b       6f
+5:     /* not found anywhere */
+       mfsrr1  3
+       andi.   2,3,0xffff              /* clean upper srr1 */
+       addis   2,2,0x4000              /* set srr1<1> to flag pte not found */
+6:
+       mtctr   0                       /* restore counter */
+       mtsrr1  2
+       mfmsr   0
+       xoris   0,0,2                   /* flip the msr<tgpr> bit */
+       mtcrf   0x80,3                  /* restore cr0 */
+       mtmsr   0                       /* now with native gprs */
+       isync
+       ba      EXC_ISI
+_C_LABEL(tlbimsize) =  .-_C_LABEL(tlbimiss)
+
+       .globl  _C_LABEL(tlbdlmiss),_C_LABEL(tlbdlmsize)
+_C_LABEL(tlbdlmiss):
+       mfspr   2,HASH1                 /* get first pointer */
+       li      1,8
+       mfctr   0                       /* save counter */
+       mfspr   3,DCMP                  /* get first compare value */
+       addi    2,2,-8                  /* predec pointer */
+1:
+       mtctr   1                       /* load counter */
+2:
+       lwzu    1,8(2)                  /* get next pte */
+       cmpl    0,1,3                   /* see if found pte */
+       bdneq   2b                      /* loop if not eq */
+       bne     3f                      /* not found */
+       lwz     1,4(2)                  /* load tlb entry lower word */
+       mtctr   0                       /* restore counter */
+       mfspr   0,DMISS                 /* get the miss address for the tlbld */
+       mfsrr1  3                       /* get the saved cr0 bits */
+       mtcrf   0x80,3                  /* and restore */
+       ori     1,1,0x100               /* set the reference bit */
+       mtspr   RPA,1                   /* set the pte */
+       srwi    1,1,8                   /* get byte 7 of pte */
+       tlbld   0                       /* load the dtlb */
+       stb     1,6(2)                  /* update page table */
+       rfi
+
+3:     /* not found in pteg */
+       andi.   1,3,0x40                /* have we already done second hash? */
+       bne     5f
+       mfspr   2,HASH2                 /* get the second pointer */
+       ori     3,3,0x40                /* change the compare value */
+       li      1,8
+       addi    2,2,-8                  /* predec pointer */
+       b       1b
+5:     /* not found anywhere */
+       mfsrr1  3
+       lis     1,0x4000                /* set dsisr<1> to flag pte not found */
+       mtctr   0                       /* restore counter */
+       andi.   2,3,0xffff              /* clean upper srr1 */
+       mtsrr1  2
+       mtdsisr 1                       /* load the dsisr */
+       mfspr   1,DMISS                 /* get the miss address */
+       mtdar   1                       /* put in dar */
+       mfmsr   0
+       xoris   0,0,2                   /* flip the msr<tgpr> bit */
+       mtcrf   0x80,3                  /* restore cr0 */
+       mtmsr   0                       /* now with native gprs */
+       isync
+       ba      EXC_DSI
+_C_LABEL(tlbdlmsize) = .-_C_LABEL(tlbdlmiss)
+
+       .globl  _C_LABEL(tlbdsmiss),_C_LABEL(tlbdsmsize)
+_C_LABEL(tlbdsmiss):
+       mfspr   2,HASH1                 /* get first pointer */
+       li      1,8
+       mfctr   0                       /* save counter */
+       mfspr   3,DCMP                  /* get first compare value */
+       addi    2,2,-8                  /* predec pointer */
+1:
+       mtctr   1                       /* load counter */
+2:
+       lwzu    1,8(2)                  /* get next pte */
+       cmpl    0,1,3                   /* see if found pte */
+       bdneq   2b                      /* loop if not eq */
+       bne     3f                      /* not found */
+       lwz     1,4(2)                  /* load tlb entry lower word */
+       andi.   3,1,0x80                /* check the C-bit */
+       beq     4f
+5:
+       mtctr   0                       /* restore counter */
+       mfspr   0,DMISS                 /* get the miss address for the tlbld */
+       mfsrr1  3                       /* get the saved cr0 bits */
+       mtcrf   0x80,3                  /* and restore */
+       mtspr   RPA,1                   /* set the pte */
+       tlbld   0                       /* load the dtlb */
+       rfi
+
+3:     /* not found in pteg */
+       andi.   1,3,0x40                /* have we already done second hash? */
+       bne     5f
+       mfspr   2,HASH2                 /* get the second pointer */
+       ori     3,3,0x40                /* change the compare value */
+       li      1,8
+       addi    2,2,-8                  /* predec pointer */
+       b       1b
+4:     /* found, but C-bit = 0 */
+       rlwinm. 3,1,30,0,1              /* test PP */
+       bge-    7f
+       andi.   3,1,1
+       beq+    8f
+9:     /* found, but protection violation (PP==00)*/
+       mfsrr1  3
+       lis     1,0xa00                 /* indicate protection violation on store */
+       b       1f
+7:     /* found, PP=1x */
+       mfspr   3,DMISS                 /* get the miss address */
+       mfsrin  1,3                     /* get the segment register */
+       mfsrr1  3
+       rlwinm  3,3,18,31,31            /* get PR-bit */
+       rlwnm.  2,2,3,1,1               /* get the key */
+       bne-    9b                      /* protection violation */
+8:     /* found, set reference/change bits */
+       lwz     1,4(2)                  /* reload tlb entry */
+       ori     1,1,0x180
+       sth     1,6(2)
+       b       5b
+5:     /* not found anywhere */
+       mfsrr1  3
+       lis     1,0x4200                /* set dsisr<1> to flag pte not found */
+                                       /* dsisr<6> to flag store */
+1:
+       mtctr   0                       /* restore counter */
+       andi.   2,3,0xffff              /* clean upper srr1 */
+       mtsrr1  2
+       mtdsisr 1                       /* load the dsisr */
+       mfspr   1,DMISS                 /* get the miss address */
+       mtdar   1                       /* put in dar */
+       mfmsr   0
+       xoris   0,0,2                   /* flip the msr<tgpr> bit */
+       mtcrf   0x80,3                  /* restore cr0 */
+       mtmsr   0                       /* now with native gprs */
+       isync
+       ba      EXC_DSI
+_C_LABEL(tlbdsmsize) = .-_C_LABEL(tlbdsmiss)
+
+#if NIPKDB > 0
+#define        ipkdbsave       0xde0           /* primary save area for IPKDB */
+/*
+ * In case of IPKDB we want a separate trap catcher for it
+ */
+.lcomm ipkdbstk,INTSTK                 /* ipkdb stack */
+
+       .globl  _C_LABEL(ipkdblow),_C_LABEL(ipkdbsize)
+_C_LABEL(ipkdblow):
+       mtsprg  1,1                     /* save SP */
+       stmw    28,ipkdbsave(0)         /* free r28-r31 */
+       lis     1,ipkdbstk+INTSTK@ha    /* get new SP */
+       addi    1,1,ipkdbstk+INTSTK@l
+       mflr    28
+       mfcr    29
+       bla     ipkdbtrap
+_C_LABEL(ipkdbsize) =  .-_C_LABEL(ipkdblow)
+#endif /* NIPKDB > 0 */
+
+/*
+ * FRAME_SETUP assumes:
+ *     SPRG1           SP (1)
+ *     savearea        r28-r31,DAR,DSISR       (DAR & DSISR only for DSI traps)
+ *     28              LR
+ *     29              CR
+ *     1               kernel stack
+ *     LR              trap type
+ *     SRR0/1          as at start of trap
+ */
+#define        FRAME_SETUP(savearea)                                           \
+/* Have to enable translation to allow access of kernel stack: */      \
+       mfsrr0  30;                                                     \
+       mfsrr1  31;                                                     \
+       stmw    30,savearea+24(0);                                      \
+       mfmsr   30;                                                     \
+       ori     30,30,(PSL_DR|PSL_IR);                                  \
+       mtmsr   30;                                                     \
+       isync;                                                          \
+       mfsprg  31,1;                                                   \
+       stwu    31,-FRAMELEN(1);                                        \
+       stw     0,FRAME_0+8(1);                                         \
+       stw     31,FRAME_1+8(1);                                        \
+       stw     28,FRAME_LR+8(1);                                       \
+       stw     29,FRAME_CR+8(1);                                       \
+       lmw     28,savearea(0);                                         \
+       stmw    2,FRAME_2+8(1);                                         \
+       lmw     28,savearea+16(0);                                      \
+       mfxer   3;                                                      \
+       mfctr   4;                                                      \
+       mflr    5;                                                      \
+       andi.   5,5,0xff00;                                             \
+       stw     3,FRAME_XER+8(1);                                       \
+       stw     4,FRAME_CTR+8(1);                                       \
+       stw     5,FRAME_EXC+8(1);                                       \
+       stw     28,FRAME_DAR+8(1);                                      \
+       stw     29,FRAME_DSISR+8(1);                                    \
+       stw     30,FRAME_SRR0+8(1);                                     \
+       stw     31,FRAME_SRR1+8(1)
+
+#define        FRAME_LEAVE(savearea)                                           \
+/* Now restore regs: */                                                        \
+       lwz     2,FRAME_SRR0+8(1);                                      \
+       lwz     3,FRAME_SRR1+8(1);                                      \
+       lwz     4,FRAME_CTR+8(1);                                       \
+       lwz     5,FRAME_XER+8(1);                                       \
+       lwz     6,FRAME_LR+8(1);                                        \
+       lwz     7,FRAME_CR+8(1);                                        \
+       stw     2,savearea(0);                                          \
+       stw     3,savearea+4(0);                                        \
+       mtctr   4;                                                      \
+       mtxer   5;                                                      \
+       mtlr    6;                                                      \
+       mtsprg  1,7;                    /* save cr */                   \
+       lmw     2,FRAME_2+8(1);                                         \
+       lwz     0,FRAME_0+8(1);                                         \
+       lwz     1,FRAME_1+8(1);                                         \
+       mtsprg  2,2;                    /* save r2 & r3 */              \
+       mtsprg  3,3;                                                    \
+/* Disable translation, machine check and recoverability: */           \
+       mfmsr   2;                                                      \
+       andi.   2,2,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI);                     \
+       mtmsr   2;                                                      \
+       isync;                                                          \
+/* Decide whether we return to user mode: */                           \
+       lwz     3,savearea+4(0);                                        \
+       mtcr    3;                                                      \
+       bc      4,17,1f;                /* branch if PSL_PR is false */ \
+/* Restore user & kernel access SR: */                                 \
+       lis     2,_C_LABEL(curpm)@ha;   /* get real address of pmap */  \
+       lwz     2,_C_LABEL(curpm)@l(2);                                 \
+       lwz     3,PM_USRSR(2);                                          \
+       mtsr    USER_SR,3;                                              \
+       lwz     3,PM_KERNELSR(2);                                       \
+       mtsr    KERNEL_SR,3;                                            \
+1:     mfsprg  2,1;                    /* restore cr */                \
+       mtcr    2;                                                      \
+       lwz     2,savearea(0);                                          \
+       lwz     3,savearea+4(0);                                        \
+       mtsrr0  2;                                                      \
+       mtsrr1  3;                                                      \
+       mfsprg  2,2;                    /* restore r2 & r3 */           \
+       mfsprg  3,3
+
+/*
+ * Preamble code for DSI/ISI traps
+ */
+disitrap:
+       lmw     30,disisave(0)
+       stmw    30,tempsave(0)
+       lmw     30,disisave+8(0)
+       stmw    30,tempsave+8(0)
+       mfdar   30
+       mfdsisr 31
+       stmw    30,tempsave+16(0)
+realtrap:
+/* Test whether we already had PR set */
+       mfsrr1  1
+       mtcr    1
+       mfsprg  1,1                     /* restore SP (might have been overwritten) */
+       bc      4,17,s_trap             /* branch if PSL_PR is false */
+       lis     1,_C_LABEL(curpcb)@ha
+       lwz     1,_C_LABEL(curpcb)@l(1)
+       addi    1,1,USPACE              /* stack is top of user struct */
+/*
+ * Now the common trap catching code.
+ */
+s_trap:
+/* First have to enable KERNEL mapping */
+       lis     31,KERNEL_SEGMENT@ha
+       addi    31,31,KERNEL_SEGMENT@l
+       mtsr    KERNEL_SR,31
+       FRAME_SETUP(tempsave)
+/* Now we can recover interrupts again: */
+       mfmsr   7
+       ori     7,7,(PSL_EE|PSL_ME|PSL_RI)
+       mtmsr   7
+       isync
+/* Call C trap code: */
+trapagain:
+       addi    3,1,8
+       bl      _C_LABEL(trap)
+trapexit:
+/* Disable interrupts: */
+       mfmsr   3
+       andi.   3,3,~PSL_EE@l
+       mtmsr   3
+/* Test AST pending: */
+       lwz     5,FRAME_SRR1+8(1)
+       mtcr    5
+       bc      4,17,1f                 /* branch if PSL_PR is false */
+       lis     3,_C_LABEL(astpending)@ha
+       lwz     4,_C_LABEL(astpending)@l(3)
+       andi.   4,4,1
+       beq     1f
+       li      6,EXC_AST
+       stw     6,FRAME_EXC+8(1)
+       b       trapagain
+1:
+       FRAME_LEAVE(tempsave)
+       rfi
+
+/*
+ * Child comes here at the end of a fork.
+ * Mostly similar to the above.
+ */
+       .globl  _C_LABEL(fork_trampoline)
+_C_LABEL(fork_trampoline):
+       xor     3,3,3
+       bl      _C_LABEL(splx)
+       mtlr    31
+       mr      3,30
+       blrl                            /* jump indirect to r31 */
+       b       trapexit
+
+/*
+ * DSI second stage fault handler
+ */
+s_dsitrap:
+       mfdsisr 31                      /* test whether this may be a spill fault */
+       mtcr    31
+       mtsprg  1,1                     /* save SP */
+       bc      4,1,disitrap            /* branch if table miss is false */
+       lis     1,spillstk+SPILLSTK@ha
+       addi    1,1,spillstk+SPILLSTK@l /* get spill stack */
+       stwu    1,-52(1)
+       stw     0,48(1)                 /* save non-volatile registers */
+       stw     3,44(1)
+       stw     4,40(1)
+       stw     5,36(1)
+       stw     6,32(1)
+       stw     7,28(1)
+       stw     8,24(1)
+       stw     9,20(1)
+       stw     10,16(1)
+       stw     11,12(1)
+       stw     12,8(1)
+       mflr    30                      /* save trap type */
+       mfctr   31                      /* & CTR */
+       mfdar   3
+s_pte_spill:
+       bl      _C_LABEL(pte_spill)             /* try a spill */
+       or.     3,3,3
+       mtctr   31                      /* restore CTR */
+       mtlr    30                      /* and trap type */
+       mfsprg  31,2                    /* get saved XER */
+       mtxer   31                      /* restore XER */
+       lwz     12,8(1)                 /* restore non-volatile registers */
+       lwz     11,12(1)
+       lwz     10,16(1)
+       lwz     9,20(1)
+       lwz     8,24(1)
+       lwz     7,28(1)
+       lwz     6,32(1)
+       lwz     5,36(1)
+       lwz     4,40(1)
+       lwz     3,44(1)
+       lwz     0,48(1)
+       beq     disitrap
+       mfsprg  1,1                     /* restore SP */
+       mtcr    29                      /* restore CR */
+       mtlr    28                      /* restore LR */
+       lmw     28,disisave(0)          /* restore r28-r31 */
+       rfi                             /* return to trapped code */
+
+/*
+ * ISI second stage fault handler
+ */
+s_isitrap:
+       mfsrr1  31                      /* test whether this may be a spill fault */
+       mtcr    31
+       mtsprg  1,1                     /* save SP */
+       bc      4,1,disitrap            /* branch if table miss is false */
+       lis     1,spillstk+SPILLSTK@ha
+       addi    1,1,spillstk+SPILLSTK@l /* get spill stack */
+       stwu    1,-52(1)
+       stw     0,48(1)                 /* save non-volatile registers */
+       stw     3,44(1)
+       stw     4,40(1)
+       stw     5,36(1)
+       stw     6,32(1)
+       stw     7,28(1)
+       stw     8,24(1)
+       stw     9,20(1)
+       stw     10,16(1)
+       stw     11,12(1)
+       stw     12,8(1)
+       mfxer   30                      /* save XER */
+       mtsprg  2,30
+       mflr    30                      /* save trap type */
+       mfctr   31                      /* & ctr */
+       mfsrr0  3
+       b       s_pte_spill             /* above */
+
+/*
+ * External interrupt second level handler
+ */
+#define        INTRENTER                                                       \
+/* Save non-volatile registers: */                                     \
+       stwu    1,-88(1);               /* temporarily */               \
+       stw     0,84(1);                                                \
+       mfsprg  0,1;                    /* get original SP */           \
+       stw     0,0(1);                 /* and store it */              \
+       stw     3,80(1);                                                \
+       stw     4,76(1);                                                \
+       stw     5,72(1);                                                \
+       stw     6,68(1);                                                \
+       stw     7,64(1);                                                \
+       stw     8,60(1);                                                \
+       stw     9,56(1);                                                \
+       stw     10,52(1);                                               \
+       stw     11,48(1);                                               \
+       stw     12,44(1);                                               \
+       stw     28,40(1);               /* saved LR */                  \
+       stw     29,36(1);               /* saved CR */                  \
+       stw     30,32(1);               /* saved XER */                 \
+       lmw     28,tempsave(0);         /* restore r28-r31 */           \
+       mfctr   6;                                                      \
+       li      5,_C_LABEL(intr_depth)@ha;                              \
+       lwz     5,_C_LABEL(intr_depth)@l(5);                            \
+       mfsrr0  4;                                                      \
+       mfsrr1  3;                                                      \
+       stw     6,28(1);                                                \
+       stw     5,20(1);                                                \
+       stw     4,12(1);                                                \
+       stw     3,8(1);                                                 \
+/* interrupts are recoverable here, and enable translation */          \
+       lis     3,(KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY)@ha;                \
+       addi    3,3,(KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY)@l;               \
+       mtsr    KERNEL_SR,3;                                            \
+       mfmsr   5;                                                      \
+       ori     5,5,(PSL_IR|PSL_DR|PSL_RI);                             \
+       mtmsr   5;                                                      \
+       isync
+
+       .globl  _C_LABEL(extint_call)
+extintr:
+       INTRENTER
+_C_LABEL(extint_call):
+       bl      _C_LABEL(extint_call)           /* to be filled in later */
+intr_exit:
+/* Disable interrupts (should already be disabled) and MMU here: */
+       mfmsr   3
+       andi.   3,3,~(PSL_EE|PSL_ME|PSL_RI|PSL_DR|PSL_IR)@l
+       mtmsr   3
+       isync
+/* restore possibly overwritten registers: */
+       lwz     12,44(1)
+       lwz     11,48(1)
+       lwz     10,52(1)
+       lwz     9,56(1)
+       lwz     8,60(1)
+       lwz     7,64(1)
+       lwz     6,8(1)
+       lwz     5,12(1)
+       lwz     4,28(1)
+       lwz     3,32(1)
+       mtsrr1  6
+       mtsrr0  5
+       mtctr   4
+       mtxer   3
+/* Returning to user mode? */
+       mtcr    6                       /* saved SRR1 */
+       bc      4,17,1f                 /* branch if PSL_PR is false */
+       lis     3,_C_LABEL(curpm)@ha    /* get current pmap real address */
+       lwz     3,_C_LABEL(curpm)@l(3)
+       lwz     3,PM_KERNELSR(3)
+       mtsr    KERNEL_SR,3             /* Restore kernel SR */
+       lis     3,_C_LABEL(astpending)@ha       /* Test AST pending */
+       lwz     4,_C_LABEL(astpending)@l(3)
+       andi.   4,4,1
+       beq     1f
+/* Setup for entry to realtrap: */
+       lwz     3,0(1)                  /* get saved SP */
+       mtsprg  1,3
+       li      6,EXC_AST
+       stmw    28,tempsave(0)          /* establish tempsave again */
+       mtlr    6
+       lwz     28,40(1)                /* saved LR */
+       lwz     29,36(1)                /* saved CR */
+       lwz     6,68(1)
+       lwz     5,72(1)
+       lwz     4,76(1)
+       lwz     3,80(1)
+       lwz     0,84(1)
+       lis     30,_C_LABEL(intr_depth)@ha      /* adjust reentrancy count */
+       lwz     31,_C_LABEL(intr_depth)@l(30)
+       addi    31,31,-1
+       stw     31,_C_LABEL(intr_depth)@l(30)
+       b       realtrap
+1:
+/* Here is the normal exit of extintr: */
+       lwz     5,36(1)
+       lwz     6,40(1)
+       mtcr    5
+       mtlr    6
+       lwz     6,68(1)
+       lwz     5,72(1)
+       lis     3,_C_LABEL(intr_depth)@ha       /* adjust reentrancy count */
+       lwz     4,_C_LABEL(intr_depth)@l(3)
+       addi    4,4,-1
+       stw     4,_C_LABEL(intr_depth)@l(3)
+       lwz     4,76(1)
+       lwz     3,80(1)
+       lwz     0,84(1)
+       lwz     1,0(1)
+       rfi
+
+/*
+ * Decrementer interrupt second level handler
+ */
+decrintr:
+       INTRENTER
+       addi    3,1,8                   /* intr frame */
+       bl      _C_LABEL(decr_intr)
+       b       intr_exit
+
+#if NIPKDB > 0
+/*
+ * Deliberate entry to ipkdbtrap
+ */
+       .globl  _C_LABEL(ipkdb_trap)
+_C_LABEL(ipkdb_trap):
+       
+       mtsprg  2,2
+       mfmsr   3
+       mtsrr1  3
+       andi.   3,3,~(PSL_EE|PSL_ME)@l
+       mtmsr   3                       /* disable interrupts */
+       isync
+       stmw    28,ipkdbsave(0)
+       mflr    28
+       li      29,EXC_BPT
+       mtlr    29
+       mfcr    29
+       mtsrr0  28
+
+/*
+ * Now the ipkdb trap catching code.
+ */
+ipkdbtrap:
+       FRAME_SETUP(ipkdbsave)
+/* Call C trap code: */
+       addi    3,1,8
+       bl      _C_LABEL(ipkdb_trap_glue)
+       or.     3,3,3
+       bne     ipkdbleave
+/* This wasn't for IPKDB, so switch to real trap: */
+       lwz     3,FRAME_EXC+8(1)        /* save exception */
+       stw     3,ipkdbsave+8(0)
+       FRAME_LEAVE(ipkdbsave)
+       mtsprg  1,1                     /* prepare for entrance to realtrap */
+       stmw    28,tempsave(0)
+       mflr    28
+       mfcr    29
+       lwz     31,ipkdbsave+8(0)
+       mtlr    31
+       b       realtrap
+ipkdbleave:
+       FRAME_LEAVE(ipkdbsave)
+       rfi
+
+ipkdbfault:
+       ba      _C_LABEL(ipkdbfault)
+_C_LABEL(ipkdbfault):
+       mfsrr0  3
+       addi    3,3,4
+       mtsrr0  3
+       li      3,-1
+       rfi
+
+/*
+ * int ipkdbfbyte(unsigned char *p)
+ */
+       .globl  _C_LABEL(ipkdbfbyte)
+_C_LABEL(ipkdbfbyte):
+       li      9,EXC_DSI               /* establish new fault routine */
+       lwz     5,0(9)
+       lis     6,ipkdbfault@ha
+       lwz     6,ipkdbfault@l(6)
+       stw     6,0(9)
+#ifdef IPKDBUSERHACK
+       lis     8,_C_LABEL(ipkdbsr)@ha
+       lwz     8,_C_LABEL(ipkdbsr)@l(8)
+       mtsr    USER_SR,8
+       isync
+#endif
+       dcbst   0,9                     /* flush data... */
+       sync
+       icbi    0,9                     /* and instruction caches */
+       lbz     3,0(3)                  /* fetch data */
+       stw     5,0(9)                  /* restore previous fault handler */
+       dcbst   0,9                     /* and flush data... */
+       sync
+       icbi    0,9                     /* and instruction caches */
+       blr
+
+/*
+ * int ipkdbsbyte(unsigned char *p, int c)
+ */
+       .globl  _C_LABEL(ipkdbsbyte)
+_C_LABEL(ipkdbsbyte):
+       li      9,EXC_DSI               /* establish new fault routine */
+       lwz     5,0(9)
+       lis     6,ipkdbfault@ha
+       lwz     6,ipkdbfault@l(6)
+       stw     6,0(9)
+#ifdef IPKDBUSERHACK
+       lis     8,_C_LABEL(ipkdbsr)@ha
+       lwz     8,_C_LABEL(ipkdbsr)@l(8)
+       mtsr    USER_SR,8
+       isync
+#endif
+       dcbst   0,9                     /* flush data... */
+       sync
+       icbi    0,9                     /* and instruction caches */
+       mr      6,3
+       xor     3,3,3
+       stb     4,0(6)
+       dcbst   0,6                     /* Now do appropriate flushes to data... */
+       sync
+       icbi    0,6                     /* and instruction caches */
+       stw     5,0(9)                  /* restore previous fault handler */
+       dcbst   0,9                     /* and flush data... */
+       sync
+       icbi    0,9                     /* and instruction caches */    
+       blr
+#endif /* NIPKDB > 0 */
+       
+/*
+ * int setfault()
+ *
+ * Similar to setjmp to setup for handling faults on accesses to user memory.
+ * Any routine using this may only call bcopy, either the form below,
+ * or the (currently used) C code optimized, so it doesn't use any non-volatile
+ * registers.
+ */
+       .globl  _C_LABEL(setfault)
+_C_LABEL(setfault):
+       mflr    0
+       mfcr    12
+       lis     4,_C_LABEL(curpcb)@ha
+       lwz     4,_C_LABEL(curpcb)@l(4)
+       stw     3,PCB_FAULT(4)
+       stw     0,0(3)
+       stw     1,4(3)
+       stw     2,8(3)
+       stmw    12,12(3)
+       xor     3,3,3
+       blr
+
+/*
+ * The following code gets copied to the top of the user stack on process
+ * execution.  It does signal trampolining on signal delivery.
+ *
+ * On entry r1 points to a struct sigframe at bottom of current stack.
+ * All other registers are unchanged.
+ */
+       .globl  _C_LABEL(sigcode),_C_LABEL(esigcode)
+_C_LABEL(sigcode):
+       addi    1,1,-16                 /* reserved space for callee */
+       blrl
+       addi    3,1,16+8                /* compute &sf_sc */
+       li      0,SYS_sigreturn
+       sc                              /* sigreturn(scp) */
+       li      0,SYS_exit
+       sc                              /* exit(errno) */
+_C_LABEL(esigcode):
diff --git a/sys/arch/powerpc/powerpc/machdep.c b/sys/arch/powerpc/powerpc/machdep.c
new file mode 100644 (file)
index 0000000..3dd3c98
--- /dev/null
@@ -0,0 +1,927 @@
+/*     $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $   */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "machine/ipkdb.h"
+
+#include <sys/param.h>
+#include <sys/buf.h>
+#include <sys/callout.h>
+#include <sys/exec.h>
+#include <sys/malloc.h>
+#include <sys/map.h>
+#include <sys/mbuf.h>
+#include <sys/mount.h>
+#include <sys/msgbuf.h>
+#include <sys/proc.h>
+#include <sys/reboot.h>
+#include <sys/syscallargs.h>
+#include <sys/syslog.h>
+#include <sys/systm.h>
+#include <sys/user.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+
+#include <net/netisr.h>
+
+#include <machine/bat.h>
+#include <machine/pmap.h>
+#include <machine/powerpc.h>
+#include <machine/trap.h>
+
+/*
+ * Global variables used here and there
+ */
+struct pcb *curpcb;
+struct pmap *curpm;
+struct proc *fpuproc;
+
+extern struct user *proc0paddr;
+
+struct bat battable[16];
+
+int astpending;
+
+char *bootpath;
+char bootpathbuf[512];
+
+/*
+ * We use the page just above the interrupt vector as message buffer
+ */
+struct msgbuf *msgbufp = (struct msgbuf *)0x3000;
+int msgbufmapped = 1;          /* message buffer is always mapped */
+
+caddr_t allocsys __P((caddr_t));
+
+static void fake_splx __P((int));
+static void fake_irq_establish __P((int, int, void (*)(void *), void *));
+
+struct machvec machine_interface = {
+       fake_splx,
+       fake_irq_establish,
+};
+
+int cold = 1;
+
+void
+initppc(startkernel, endkernel, args)
+       u_int startkernel, endkernel;
+       char *args;
+{
+       int phandle, qhandle;
+       char name[32];
+       struct machvec *mp;
+       extern trapcode, trapsize;
+       extern dsitrap, dsisize;
+       extern isitrap, isisize;
+       extern decrint, decrsize;
+       extern tlbimiss, tlbimsize;
+       extern tlbdlmiss, tlbdlmsize;
+       extern tlbdsmiss, tlbdsmsize;
+#if NIPKDB > 0
+       extern ipkdblow, ipkdbsize;
+#endif
+       extern void consinit __P((void));
+       extern void callback __P((void *));
+       int exc, scratch;
+
+       proc0.p_addr = proc0paddr;
+       bzero(proc0.p_addr, sizeof *proc0.p_addr);
+       
+       curpcb = &proc0paddr->u_pcb;
+       
+       curpm = curpcb->pcb_pmreal = curpcb->pcb_pm = pmap_kernel();
+       
+       /*
+        * i386 port says, that this shouldn't be here,
+        * but I really think the console should be initialized
+        * as early as possible.
+        */
+       consinit();
+
+#ifdef __notyet__              /* Needs some rethinking regarding real/virtual OFW */
+       OF_set_callback(callback);
+#endif
+       /*
+        * Initialize BAT registers to unmapped to not generate
+        * overlapping mappings below.
+        */
+       asm volatile ("mtibatu 0,%0" :: "r"(0));
+       asm volatile ("mtibatu 1,%0" :: "r"(0));
+       asm volatile ("mtibatu 2,%0" :: "r"(0));
+       asm volatile ("mtibatu 3,%0" :: "r"(0));
+       asm volatile ("mtdbatu 0,%0" :: "r"(0));
+       asm volatile ("mtdbatu 1,%0" :: "r"(0));
+       asm volatile ("mtdbatu 2,%0" :: "r"(0));
+       asm volatile ("mtdbatu 3,%0" :: "r"(0));
+       
+       /*
+        * Set up initial BAT table to only map the lowest 256 MB area
+        */
+       battable[0].batl = BATL(0x00000000, BAT_M);
+       battable[0].batu = BATU(0x00000000);
+
+       /*
+        * Now setup fixed bat registers
+        *
+        * Note that we still run in real mode, and the BAT
+        * registers were cleared above.
+        */
+       /* IBAT0 used for initial 256 MB segment */
+       asm volatile ("mtibatl 0,%0; mtibatu 0,%1"
+                     :: "r"(battable[0].batl), "r"(battable[0].batu));
+       /* DBAT0 used similar */
+       asm volatile ("mtdbatl 0,%0; mtdbatu 0,%1"
+                     :: "r"(battable[0].batl), "r"(battable[0].batu));
+       
+       /*
+        * Set up trap vectors
+        */
+       for (exc = EXC_RSVD; exc <= EXC_LAST; exc += 0x100)
+               switch (exc) {
+               default:
+                       bcopy(&trapcode, (void *)exc, (size_t)&trapsize);
+                       break;
+               case EXC_EXI:
+                       /*
+                        * This one is (potentially) installed during autoconf
+                        */
+                       break;
+               case EXC_DSI:
+                       bcopy(&dsitrap, (void *)EXC_DSI, (size_t)&dsisize);
+                       break;
+               case EXC_ISI:
+                       bcopy(&isitrap, (void *)EXC_ISI, (size_t)&isisize);
+                       break;
+               case EXC_DECR:
+                       bcopy(&decrint, (void *)EXC_DECR, (size_t)&decrsize);
+                       break;
+               case EXC_IMISS:
+                       bcopy(&tlbimiss, (void *)EXC_IMISS, (size_t)&tlbimsize);
+                       break;
+               case EXC_DLMISS:
+                       bcopy(&tlbdlmiss, (void *)EXC_DLMISS, (size_t)&tlbdlmsize);
+                       break;
+               case EXC_DSMISS:
+                       bcopy(&tlbdsmiss, (void *)EXC_DSMISS, (size_t)&tlbdsmsize);
+                       break;
+#if NIPKDB > 0
+               case EXC_PGM:
+               case EXC_TRC:
+               case EXC_BPT:
+                       bcopy(&ipkdblow, (void *)exc, (size_t)&ipkdbsize);
+                       break;
+#endif
+               }
+
+       syncicache((void *)EXC_RST, EXC_LAST - EXC_RST + 0x100);
+
+       /*
+        * Now enable translation (and machine checks/recoverable interrupts).
+        */
+       asm volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0; isync"
+                     : "=r"(scratch) : "K"(PSL_IR|PSL_DR|PSL_ME|PSL_RI));
+
+       /*
+        * Parse arg string.
+        */
+
+       /* make a copy of the args! */
+       strncpy(bootpathbuf, args, 512);
+       bootpath= &bootpathbuf[0];
+       args = bootpath;
+       while ( *++args && *args != ' ');
+       if (*args) {
+               *args++ = 0;
+               while (*args) {
+                       switch (*args++) {
+                       case 'a':
+                               boothowto |= RB_ASKNAME;
+                               break;
+                       case 's':
+                               boothowto |= RB_SINGLE;
+                               break;
+                       case 'd':
+                               boothowto |= RB_KDB;
+                               break;
+                       }
+               }
+       }                       
+
+#if NIPKDB > 0
+       /*
+        * Now trap to IPKDB
+        */
+       ipkdb_init();
+       if (boothowto & RB_KDB)
+               ipkdb_connect(0);
+#endif
+
+       /*
+        * Initialize pmap module.
+        */
+       pmap_bootstrap(startkernel, endkernel);
+}
+
+/*
+ * This should probably be in autoconf!                                XXX
+ */
+int cpu;
+char cpu_model[80];
+char machine[] = "powerpc";    /* cpu architecture */
+
+void
+identifycpu()
+{
+       int phandle, pvr;
+       char name[32];
+
+       /*
+        * Find cpu type (Do it by OpenFirmware?)
+        */
+       asm ("mfpvr %0" : "=r"(pvr));
+       cpu = pvr >> 16;
+       switch (cpu) {
+       case 1:
+               sprintf(cpu_model, "601");
+               break;
+       case 3:
+               sprintf(cpu_model, "603");
+               break;
+       case 4:
+               sprintf(cpu_model, "604");
+               break;
+       case 5:
+               sprintf(cpu_model, "602");
+               break;
+       case 6:
+               sprintf(cpu_model, "603e");
+               break;
+       case 7:
+               sprintf(cpu_model, "603ev");
+               break;
+       case 9:
+               sprintf(cpu_model, "604ev");
+               break;
+       case 20:
+               sprintf(cpu_model, "620");
+               break;
+       default:
+               sprintf(cpu_model, "Version %x", cpu);
+               break;
+       }
+       sprintf(cpu_model + strlen(cpu_model), " (Revision %x)", pvr & 0xffff);
+       printf("CPU: %s\n", cpu_model);
+}
+
+void
+install_extint(handler)
+       void (*handler) __P((void));
+{
+       extern extint, extsize;
+       extern u_long extint_call;
+       u_long offset = (u_long)handler - (u_long)&extint_call;
+       int omsr, msr;
+       
+#ifdef DIAGNOSTIC
+       if (offset > 0x1ffffff)
+               panic("install_extint: too far away");
+#endif
+       asm volatile ("mfmsr %0; andi. %1, %0, %2; mtmsr %1"
+                     : "=r"(omsr), "=r"(msr) : "K"((u_short)~PSL_EE));
+       extint_call = (extint_call & 0xfc000003) | offset;
+       bcopy(&extint, (void *)EXC_EXI, (size_t)&extsize);
+       syncicache((void *)&extint_call, sizeof extint_call);
+       syncicache((void *)EXC_EXI, (int)&extsize);
+       asm volatile ("mtmsr %0" :: "r"(omsr));
+}
+
+/*
+ * Machine dependent startup code.
+ */
+void
+cpu_startup()
+{
+       int sz, i;
+       caddr_t v;
+       vm_offset_t minaddr, maxaddr;
+       int base, residual;
+       
+       proc0.p_addr = proc0paddr;
+       v = (caddr_t)proc0paddr + USPACE;
+
+       printf("%s", version);
+       identifycpu();
+       
+       printf("real mem = %d\n", ctob(physmem));
+       
+       /*
+        * Find out how much space we need, allocate it,
+        * and then give everything true virtual addresses.
+        */
+       sz = (int)allocsys((caddr_t)0);
+       if ((v = (caddr_t)kmem_alloc(kernel_map, round_page(sz))) == 0)
+               panic("startup: no room for tables");
+       if (allocsys(v) - v != sz)
+               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.
+        */
+       sz = MAXBSIZE * nbuf;
+       buffer_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, sz, TRUE);
+       buffers = (char *)minaddr;
+       if (vm_map_find(buffer_map, vm_object_allocate(sz), (vm_offset_t)0,
+                       &minaddr, sz, FALSE) != KERN_SUCCESS)
+               panic("startup: cannot allocate buffers");
+       base = bufpages / nbuf;
+       residual = bufpages % nbuf;
+       if (base >= MAXBSIZE) {
+               /* Don't want to alloc more physical mem than ever needed */
+               base = MAXBSIZE;
+               residual = 0;
+       }
+       for (i = 0; i < nbuf; i++) {
+               vm_size_t curbufsize;
+               vm_offset_t curbuf;
+               
+               curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
+               curbufsize = CLBYTES * (i < residual ? base + 1 : base);
+               vm_map_pageable(buffer_map, curbuf, curbuf + curbufsize, FALSE);
+               vm_map_simplify(buffer_map, curbuf);
+       }
+
+       /*
+        * Allocate a submap for exec arguments.  This map effectively
+        * limits the number of processes exec'ing at any time.
+        */
+       exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
+                                16*NCARGS, TRUE);
+
+       /*
+        * Allocate a submap for physio
+        */
+       phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
+                                VM_PHYS_SIZE, TRUE);
+       
+       /*
+        * Allocate mbuf pool.
+        */
+       mclrefcnt = (char *)malloc(NMBCLUSTERS + CLBYTES/MCLBYTES,
+                                  M_MBUF, M_NOWAIT);
+       bzero(mclrefcnt, NMBCLUSTERS + CLBYTES/MCLBYTES);
+       mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr,
+                              VM_MBUF_SIZE, FALSE);
+       
+       /*
+        * Initialize callouts.
+        */
+       callfree = callout;
+       for (i = 1; i < ncallout; i++)
+               callout[i - 1].c_next = &callout[i];
+       
+       printf("avail mem = %d\n", ptoa(cnt.v_free_count));
+       printf("using %d buffers containing %d bytes of memory\n",
+              nbuf, bufpages * CLBYTES);
+       
+       /*
+        * Set up the buffers.
+        */
+       bufinit();
+
+       /*
+        * Now allow hardware interrupts.
+        */
+       {
+               int msr;
+               
+               splhigh();
+               asm volatile ("mfmsr %0; ori %0, %0, %1; mtmsr %0"
+                             : "=r"(msr) : "K"(PSL_EE));
+       }
+       
+       /*
+        * Configure devices.
+        */
+       configure();
+       
+}
+
+/*
+ * Allocate space for system data structures.
+ */
+caddr_t
+allocsys(v)
+       caddr_t v;
+{
+#define        valloc(name, type, num) \
+       v = (caddr_t)(((name) = (type *)v) + (num))
+
+       valloc(callout, struct callout, ncallout);
+       valloc(swapmap, struct map, nswapmap = maxproc * 2);
+#ifdef SYSVSHM
+       valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
+#endif
+#ifdef SYSVSEM
+       valloc(sema, struct semid_ds, seminfo.semmni);
+       valloc(sem, struct sem, seminfo.semmns);
+       valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
+#endif
+#ifdef SYSVMSG
+       valloc(msgpool, char, msginfo.msgmax);
+       valloc(msgmaps, struct msgmap, msginfo.msgseg);
+       valloc(msghdrs, struct msg, msginfo.msgtql);
+       valloc(msqids, struct msqid_ds, msginfo.msgmni);
+#endif
+
+       /*
+        * Decide on buffer space to use.
+        */
+       if (bufpages == 0)
+               bufpages = (physmem / 20) / CLSIZE;
+       if (nbuf == 0) {
+               nbuf = bufpages;
+               if (nbuf < 16)
+                       nbuf = 16;
+       }
+       if (nswbuf == 0) {
+               nswbuf = (nbuf / 2) & ~1;
+               if (nswbuf > 256)
+                       nswbuf = 256;
+       }
+       valloc(swbuf, struct buf, nswbuf);
+       valloc(buf, struct buf, nbuf);
+       
+       return v;
+}
+
+/*
+ * consinit
+ * Initialize system console.
+ */
+void
+consinit()
+{
+       static int initted;
+       
+       if (initted)
+               return;
+       initted = 1;
+       cninit();
+}
+
+/*
+ * Clear registers on exec
+ */
+void
+setregs(p, pack, stack, retval)
+       struct proc *p;
+       struct exec_package *pack;
+       u_long stack;
+       register_t *retval;
+{
+       u_int32_t newstack;
+       u_int32_t pargs;
+       u_int32_t       args[4];
+
+       struct trapframe *tf = trapframe(p);
+       pargs = -roundup(-stack + 8, 16);
+       newstack = (u_int32_t)(pargs - 32);
+
+       copyin ((void*)(VM_MAX_ADDRESS-0x10), &args, 0x10);
+       
+       bzero(tf, sizeof *tf);
+       tf->fixreg[1] = newstack;
+       tf->fixreg[3] = retval[0] = args[1];    /* XXX */
+       tf->fixreg[4] = retval[1] = args[0];    /* XXX */
+       tf->fixreg[5] = args[2];                /* XXX */
+       tf->fixreg[6] = args[3];                /* XXX */
+       tf->srr0 = pack->ep_entry;
+       tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT;
+       p->p_addr->u_pcb.pcb_flags = 0;
+}
+
+/*
+ * Send a signal to process.
+ */
+void
+sendsig(catcher, sig, mask, code)
+       sig_t catcher;
+       int sig, mask;
+       u_long code;
+{
+       struct proc *p = curproc;
+       struct trapframe *tf;
+       struct sigframe *fp, frame;
+       struct sigacts *psp = p->p_sigacts;
+       int oldonstack;
+       
+       frame.sf_signum = sig;
+       
+       tf = trapframe(p);
+       oldonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
+       
+       /*
+        * Allocate stack space for signal handler.
+        */
+       if ((psp->ps_flags & SAS_ALTSTACK)
+           && !oldonstack
+           && (psp->ps_sigonstack & sigmask(sig))) {
+               fp = (struct sigframe *)(psp->ps_sigstk.ss_sp
+                                        + psp->ps_sigstk.ss_size);
+               psp->ps_sigstk.ss_flags |= SS_ONSTACK;
+       } else
+               fp = (struct sigframe *)tf->fixreg[1];
+       fp = (struct sigframe *)((int)(fp - 1) & ~0xf);
+       
+       frame.sf_code = code;
+       
+       /*
+        * Generate signal context for SYS_sigreturn.
+        */
+       frame.sf_sc.sc_onstack = oldonstack;
+       frame.sf_sc.sc_mask = mask;
+       bcopy(tf, &frame.sf_sc.sc_frame, sizeof *tf);
+       if (copyout(&frame, fp, sizeof frame) != 0)
+               sigexit(p, SIGILL);
+       
+       tf->fixreg[1] = (int)fp;
+       tf->lr = (int)catcher;
+       tf->fixreg[3] = (int)sig;
+       tf->fixreg[4] = (int)code;
+       tf->fixreg[5] = (int)&frame.sf_sc;
+       tf->srr0 = (int)(((char *)PS_STRINGS)
+                        - (p->p_emul->e_esigcode - p->p_emul->e_sigcode));
+}
+
+/*
+ * System call to cleanup state after a signal handler returns.
+ */
+int
+sys_sigreturn(p, v, retval)
+       struct proc *p;
+       void *v;
+       register_t *retval;
+{
+       struct sys_sigreturn_args /* {
+               syscallarg(struct sigcontext *) sigcntxp;
+       } */ *uap = v;
+       struct sigcontext sc;
+       struct trapframe *tf;
+       int error;
+       
+       if (error = copyin(SCARG(uap, sigcntxp), &sc, sizeof sc))
+               return error;
+       tf = trapframe(p);
+       if ((sc.sc_frame.srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC))
+               return EINVAL;
+       bcopy(&sc.sc_frame, tf, sizeof *tf);
+       if (sc.sc_onstack & 1)
+               p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
+       else
+               p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
+       p->p_sigmask = sc.sc_mask & ~sigcantmask;
+       return EJUSTRETURN;
+}
+
+/*
+ * Machine dependent system variables.
+ * None for now.
+ */
+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;
+{
+       /* all sysctl names at this level are terminal */
+       if (namelen != 1)
+               return ENOTDIR;
+       switch (name[0]) {
+       default:
+               return EOPNOTSUPP;
+       }
+}
+
+/*
+ * Crash dump handling.
+ */
+u_long dumpmag = 0x8fca0101;           /* magic number */
+int dumpsize = 0;                      /* size of dump in pages */
+long dumplo = -1;                      /* blocks */
+
+void
+dumpsys()
+{
+       printf("dumpsys: TBD\n");
+}
+
+int cpl;
+int clockpending, softclockpending, softnetpending;
+
+/*
+ * Soft networking interrupts.
+ */
+void
+softnet()
+{
+       int isr = netisr;
+
+       netisr = 0;
+#ifdef INET
+#include "ether.h"
+#if NETHER > 0
+       if (isr & (1 << NETISR_ARP))
+               arpintr();
+#endif
+       if (isr & (1 << NETISR_IP))
+               ipintr();
+#endif
+#ifdef IMP
+       if (isr & (1 << NETISR_IMP))
+               impintr();
+#endif
+#ifdef NS
+       if (isr & (1 << NETISR_NS))
+               nsintr();
+#endif
+#ifdef ISO
+       if (isr & (1 << NETISR_ISO))
+               clnlintr();
+#endif
+#ifdef CCITT
+       if (isr & (1 << NETISR_CCITT))
+               ccittintr();
+#endif
+#include "ppp.h"
+#if NPPP > 0
+       if (isr & (1 << NETISR_PPP))
+               pppintr();
+#endif
+}
+
+/*
+ * Stray interrupts.
+ */
+void
+strayintr(irq)
+       int irq;
+{
+       log(LOG_ERR, "stray interrupt %d\n", irq);
+}
+
+int
+splraise(bits)
+       int bits;
+{
+       int old;
+       
+       old = cpl;
+       cpl |= bits;
+
+       if ((bits & SPLMACHINE) & ~old)
+               (*machine_interface.splx)(cpl & SPLMACHINE);
+
+       return old;
+}
+
+int
+splx(new)
+       int new;
+{
+       int pending, old = cpl;
+       int emsr, dmsr;
+       
+       asm ("mfmsr %0" : "=r"(emsr));
+       dmsr = emsr & ~PSL_EE;
+       
+       cpl = new;
+       
+       if ((new & SPLMACHINE) != (old & SPLMACHINE))
+               (*machine_interface.splx)(new & SPLMACHINE);
+
+       while (1) {
+               cpl = new;
+               
+               asm volatile ("mtmsr %0" :: "r"(dmsr));
+               if (clockpending && !(cpl & SPLCLOCK)) {
+                       struct clockframe frame;
+                       extern int intr_depth;
+                       
+                       cpl |= SPLCLOCK;
+                       clockpending--;
+                       asm volatile ("mtmsr %0" :: "r"(emsr));
+                       
+                       /*
+                        * Fake a clock interrupt frame
+                        */
+                       frame.pri = new;
+                       frame.depth = intr_depth + 1;
+                       frame.srr1 = 0;
+                       frame.srr0 = (int)splx;
+                       /*
+                        * Do standard timer interrupt stuff
+                        */
+                       hardclock(&frame);
+                       continue;
+               }
+               if (softclockpending && !(cpl & SPLSOFTCLOCK)) {
+                       
+                       cpl |= SPLSOFTCLOCK;
+                       softclockpending = 0;
+                       asm volatile ("mtmsr %0" :: "r"(emsr));
+                       
+                       softclock();
+                       continue;
+               }
+               if (softnetpending && !(cpl & SPLSOFTNET)) {
+                       cpl |= SPLSOFTNET;
+                       softnetpending = 0;
+                       asm volatile ("mtmsr %0" :: "r"(emsr));
+                       softnet();
+                       continue;
+               }
+               
+               asm volatile ("mtmsr %0" :: "r"(emsr));
+               
+               return old;
+       }
+}
+
+/*
+ * This one is similar to the above, but returns with interrupts disabled.
+ * It is intended for use during interrupt exit (as the name implies :-)).
+ */
+void
+intr_return(level)
+       int level;
+{
+       int pending, old = cpl;
+       int emsr, dmsr;
+       
+       asm ("mfmsr %0" : "=r"(emsr));
+       dmsr = emsr & ~PSL_EE;
+       
+       cpl = level;
+       
+       if ((level & SPLMACHINE) != (old & SPLMACHINE))
+               (*machine_interface.splx)(level & SPLMACHINE);
+
+       while (1) {
+               cpl = level;
+               
+               asm volatile ("mtmsr %0" :: "r"(dmsr));
+               if (clockpending && !(cpl & SPLCLOCK)) {
+                       struct clockframe frame;
+                       extern int intr_depth;
+                       
+                       cpl |= SPLCLOCK;
+                       clockpending--;
+                       asm volatile ("mtmsr %0" :: "r"(emsr));
+                       
+                       /*
+                        * Fake a clock interrupt frame
+                        */
+                       frame.pri = level | (clockpending ? SPLSOFTCLOCK : 0);
+                       frame.depth = intr_depth + 1;
+                       frame.srr1 = 0;
+                       frame.srr0 = (int)splx;
+                       /*
+                        * Do standard timer interrupt stuff
+                        */
+                       hardclock(&frame);
+                       continue;
+               }
+               if (softclockpending && !(cpl & SPLSOFTCLOCK)) {
+                       
+                       cpl |= SPLSOFTCLOCK;
+                       softclockpending = 0;
+                       asm volatile ("mtmsr %0" :: "r"(emsr));
+                       
+                       softclock();
+                       continue;
+               }
+               if (softnetpending && !(cpl & SPLSOFTNET)) {
+                       cpl |= SPLSOFTNET;
+                       softnetpending = 0;
+                       asm volatile ("mtmsr %0" :: "r"(emsr));
+                       softnet();
+                       continue;
+               }
+               break;
+       }
+}
+
+/*
+ * Halt or reboot the machine after syncing/dumping according to howto.
+ */
+void
+boot(howto)
+       int howto;
+#if 0
+       char *what;
+#endif
+{
+       static int syncing;
+       static char str[256];
+       char *ap = str, *ap1 = ap;
+
+       boothowto = howto;
+       if (!cold && !(howto & RB_NOSYNC) && !syncing) {
+               syncing = 1;
+               vfs_shutdown();         /* sync */
+               resettodr();            /* set wall clock */
+       }
+       splhigh();
+       if (howto & RB_HALT) {
+               doshutdownhooks();
+               printf("halted\n\n");
+               ppc_exit();
+       }
+       if (!cold && (howto & RB_DUMP))
+               dumpsys();
+       doshutdownhooks();
+       printf("rebooting\n\n");
+#if 0
+       if (what && *what) {
+               if (strlen(what) > sizeof str - 5)
+                       printf("boot string too large, ignored\n");
+               else {
+                       strcpy(str, what);
+                       ap1 = ap = str + strlen(str);
+                       *ap++ = ' ';
+               }
+       }
+       *ap++ = '-';
+       if (howto & RB_SINGLE)
+               *ap++ = 's';
+       if (howto & RB_KDB)
+               *ap++ = 'd';
+       *ap++ = 0;
+       if (ap[-2] == '-')
+               *ap1 = 0;
+#endif
+       ppc_boot(str);
+}
+
+/*
+ * OpenFirmware callback routine
+ */
+void
+callback(p)
+       void *p;
+{
+       panic("callback");      /* for now                      XXX */
+}
+
+/*
+ * Fake routines for spl/interrupt handling before autoconfig
+ */
+static void
+fake_splx(new)
+       int new;
+{
+}
+
+static void
+fake_irq_establish(irq, level, handler, arg)
+       int irq, level;
+       void (*handler) __P((void *));
+       void *arg;
+{
+       panic("fake_irq_establish");
+}
diff --git a/sys/arch/powerpc/powerpc/mem.c b/sys/arch/powerpc/powerpc/mem.c
new file mode 100644 (file)
index 0000000..d2e72b4
--- /dev/null
@@ -0,0 +1,154 @@
+/*     $NetBSD: mem.c,v 1.1 1996/09/30 16:34:50 ws Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1986, 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)mem.c       8.3 (Berkeley) 1/12/94
+ */
+
+/*
+ * Memory special file
+ */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/buf.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+
+#include <vm/vm.h>
+
+/*ARGSUSED*/
+int
+mmopen(dev, flag, mode)
+       dev_t dev;
+       int flag, mode;
+{
+       return 0;
+}
+
+/*ARGSUSED*/
+int
+mmclose(dev, flag, mode)
+       dev_t dev;
+       int flag, mode;
+{
+
+       return 0;
+}
+
+/*ARGSUSED*/
+int
+mmrw(dev, uio, flags)
+       dev_t dev;
+       struct uio *uio;
+       int flags;
+{
+       vm_offset_t o, v;
+       u_int c;
+       struct iovec *iov;
+       int error = 0;
+       static caddr_t zeropage;
+       
+       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;
+                       c = uio->uio_resid;
+                       /* This doesn't allow device mapping!   XXX */
+                       pmap_real_memory(&v, &c);
+                       error = uiomove((caddr_t)v, c, uio);
+                       continue;
+
+/* minor device 1 is kernel memory */
+               case 1:
+                       v = uio->uio_offset;
+                       c = min(iov->iov_len, MAXPHYS);
+                       error = uiomove((caddr_t)v, c, uio);
+                       continue;
+
+/* minor device 2 is EOF/RATHOLE */
+               case 2:
+                       if (uio->uio_rw == UIO_WRITE)
+                               uio->uio_resid = 0;
+                       return 0;
+
+/* minor device 12 (/dev/zero) is source of nulls on read, rathole on write */
+               case 12:
+                       if (uio->uio_rw == UIO_WRITE) {
+                               c = iov->iov_len;
+                               break;
+                       }
+                       if (zeropage == NULL) {
+                               zeropage = (caddr_t)malloc(CLBYTES, M_TEMP, M_WAITOK);
+                               bzero(zeropage, CLBYTES);
+                       }
+                       c = min(iov->iov_len, CLBYTES);
+                       error = uiomove(zeropage, c, uio);
+                       continue;
+
+               default:
+                       return ENXIO;
+               }
+               if (error)
+                       break;
+               iov->iov_base += c;
+               iov->iov_len -= c;
+               uio->uio_offset += c;
+               uio->uio_resid -= c;
+       }
+       return error;
+}
+
+int
+mmmmap(dev, off, prot)
+        dev_t dev;
+        int off, prot;
+{
+       return EOPNOTSUPP;
+}
diff --git a/sys/arch/powerpc/powerpc/ofw_machdep.c b/sys/arch/powerpc/powerpc/ofw_machdep.c
new file mode 100644 (file)
index 0000000..7dc784b
--- /dev/null
@@ -0,0 +1,377 @@
+/*     $NetBSD: ofw_machdep.c,v 1.1 1996/09/30 16:34:50 ws Exp $       */
+
+/*
+ * Copyright (C) 1996 Wolfgang Solfrank.
+ * Copyright (C) 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/param.h>
+#include <sys/buf.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/disk.h>
+#include <sys/disklabel.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/stat.h>
+#include <sys/systm.h>
+
+#include <dev/ofw/openfirm.h>
+
+#if defined(FFS) && defined(CD9660)
+#include <ufs/ffs/fs.h>
+#endif
+
+#include <machine/powerpc.h>
+
+#define        OFMEM_REGIONS   32
+static struct mem_region OFmem[OFMEM_REGIONS + 1], OFavail[OFMEM_REGIONS + 3];
+
+/*
+ * This is called during initppc, before the system is really initialized.
+ * It shall provide the total and the available regions of RAM.
+ * Both lists must have a zero-size entry as terminator.
+ * The available regions need not take the kernel into account, but needs
+ * to provide space for two additional entry beyond the terminating one.
+ */
+void
+mem_regions(memp, availp)
+       struct mem_region **memp, **availp;
+{
+       int phandle, i, j, cnt;
+       
+       /*
+        * Get memory.
+        */
+       if ((phandle = OF_finddevice("/memory")) == -1
+           || OF_getprop(phandle, "reg",
+                         OFmem, sizeof OFmem[0] * OFMEM_REGIONS)
+              <= 0
+           || OF_getprop(phandle, "available",
+                         OFavail, sizeof OFavail[0] * OFMEM_REGIONS)
+              <= 0)
+               panic("no memory?");
+       *memp = OFmem;
+       *availp = OFavail;
+}
+
+void
+ppc_exit()
+{
+       OF_exit();
+}
+
+void
+ppc_boot(str)
+       char *str;
+{
+       OF_boot(str);
+}
+
+/*
+ * Establish a list of all available disks to allow specifying the root/swap/dump dev.
+ */
+struct ofb_disk {
+       LIST_ENTRY(ofb_disk) ofb_list;
+       struct disk *ofb_dk;
+       struct device *ofb_dev;
+       int ofb_phandle;
+       int ofb_unit;
+};
+
+static LIST_HEAD(ofb_list, ofb_disk) ofb_head; /* LIST_INIT?           XXX */
+
+void
+dk_establish(dk, dev)
+       struct disk *dk;
+       struct device *dev;
+{
+       struct ofb_disk *od;
+       struct ofb_softc *ofp = (void *)dev;
+
+       MALLOC(od, struct ofb_disk *, sizeof *od, M_TEMP, M_NOWAIT);
+       if (!od)
+               panic("dk_establish");
+       od->ofb_dk = dk;
+       od->ofb_dev = dev;
+       od->ofb_phandle = ofp->sc_phandle;
+       if (dev->dv_class == DV_DISK)                                   /* XXX */
+               od->ofb_unit = ofp->sc_unit;
+       else
+               od->ofb_unit = -1;
+       LIST_INSERT_HEAD(&ofb_head, od, ofb_list);
+}
+
+/*
+ * Cleanup the list.
+ */
+void
+dk_cleanup()
+{
+       struct ofb_disk *od, *nd;
+
+       for (od = ofb_head.lh_first; od; od = nd) {
+               nd = od->ofb_list.le_next;
+               LIST_REMOVE(od, ofb_list);
+               FREE(od, M_TEMP);
+       }
+}
+
+#if defined(FFS) && defined(CD9660)
+static int
+dk_match_ffs()
+{
+       int error;
+       struct partinfo dpart;
+       int bsize = DEV_BSIZE;
+       int secpercyl = 1;
+       struct buf *bp;
+       struct fs *fs;
+
+       if (bdevsw[major(rootdev)].d_ioctl(rootdev, DIOCGPART, (caddr_t)&dpart, FREAD, 0) == 0
+           && dpart.disklab->d_secsize != 0) {
+               bsize = dpart.disklab->d_secsize;
+               secpercyl = dpart.disklab->d_secpercyl;
+       }
+
+       bp = geteblk(SBSIZE);
+       bp->b_dev = rootdev;
+
+       /* Try to read the superblock */
+       bp->b_blkno = SBOFF / bsize;
+       bp->b_bcount = SBSIZE;
+       bp->b_flags = B_BUSY | B_READ;
+       bp->b_cylinder = bp->b_blkno / (bsize / DEV_BSIZE) / secpercyl;
+       bdevsw[major(rootdev)].d_strategy(bp);
+
+       if (error = biowait(bp))
+               goto done;
+
+       fs = (struct fs *)bp->b_data;
+       if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE
+           || fs->fs_bsize < sizeof(struct fs))
+               error = EIO;
+done:
+       brelse(bp);
+       return error;
+}
+#endif
+
+/* These should probably be somewhere else!                            XXX */
+extern int ffs_mountroot __P((void));
+extern int cd9660_mountroot __P((void));
+extern char *nfsbootdevname;
+extern int nfs_mountroot __P((void));
+
+extern int (*mountroot) __P((void));
+
+static void
+dk_setroot(od, part)
+       struct ofb_disk *od;
+       int part;
+{
+       char type[8];
+       int maj, min;
+       struct partinfo dpart;
+       char *cp;
+
+       if (OF_getprop(od->ofb_phandle, "device_type", type, sizeof type) < 0)
+               panic("OF_getproperty");
+#if defined(FFS) || defined(CD9660)
+       if (!strcmp(type, "block")) {
+               for (maj = 0; maj < nblkdev; maj++) {
+                       if (bdevsw[maj].d_strategy == od->ofb_dk->dk_driver->d_strategy)
+                               break;
+               }
+               if (maj >= nblkdev)
+                       panic("dk_setroot");
+
+               /*
+                * Find the unit.
+                */
+               min = 0;
+               for (cp = od->ofb_dk->dk_name; *cp; cp++) {
+                       if (*cp >= '0' && *cp <= '9')
+                               min = min * 10 + *cp - '0';
+                       else
+                               /* Start anew */
+                               min = 0;
+               }
+
+               if (part == -1) {
+                       /* Try to open partition 'a' first */
+                       rootdev = makedev(maj, min * MAXPARTITIONS);
+
+                       if (bdevsw[maj].d_open(rootdev, FREAD, S_IFBLK, 0) < 0)
+                               panic("dk_setroot");
+                       dpart.part = 0;
+                       bdevsw[major(rootdev)].d_ioctl(rootdev, DIOCGPART,
+                                                      (caddr_t)&dpart, FREAD, 0);
+                       bdevsw[maj].d_close(rootdev, FREAD, S_IFBLK, 0);
+                       if (!dpart.part || dpart.part->p_size <= 0) {
+                               /* Now we use the whole disk */
+                               rootdev = makedev(maj, min * MAXPARTITIONS + RAW_PART);
+                       }
+               } else
+                       rootdev = makedev(maj, min * MAXPARTITIONS + part);
+#if defined(FFS) && defined(CD9660)
+               /*
+                * Find out whether to use ffs or cd9660.
+                */
+               if (bdevsw[maj].d_open(rootdev, FREAD, S_IFBLK, 0) < 0)
+                       panic("dk_setroot");
+               if (!dk_match_ffs())
+                       mountroot = ffs_mountroot;
+               else                                                    /* XXX */
+                       mountroot = cd9660_mountroot;
+               bdevsw[maj].d_close(rootdev, FREAD, S_IFBLK, 0);
+#elif defined(FFS)
+               mountroot = ffs_mountroot;
+#elif defined(CD9660)
+               mountroot = cd9660_mountroot;
+#else                          /* Cannot occur */
+               panic("dk_setroot: No disk filesystem");
+#endif
+
+               /*
+                * Now setup the swap/dump device
+                */
+               dumpdev = makedev(major(rootdev), min * MAXPARTITIONS + 1);
+               swdevt[0].sw_dev = dumpdev;
+               swdevt[1].sw_dev = NODEV;
+
+               return;
+       }
+#endif /* defined(FFS) || defined(CD9660) */
+#ifdef NFSCLIENT
+       if (!strcmp(type, "network")) {
+               mountroot = nfs_mountroot;
+               nfsbootdevname = od->ofb_dev->dv_xname;
+               rootdev = NODEV;
+               dumpdev = NODEV;
+               swdevt[0].sw_dev = NODEV;
+               return;
+       }
+#endif
+       panic("Where were we booted from?");
+}
+
+/*
+ * Try to find a disk with the given name.
+ * This allows either the OpenFirmware device name,
+ * or the NetBSD device name, both with optional trailing partition.
+ */
+int
+dk_match(name)
+       char *name;
+{
+       struct ofb_disk *od;
+       char *cp;
+       int phandle;
+       int part, unit;
+       int l;
+
+       for (od = ofb_head.lh_first; od; od = od->ofb_list.le_next) {
+               /*
+                * First try the NetBSD name.
+                */
+               l = strlen(od->ofb_dev->dv_xname);
+               if (!bcmp(name, od->ofb_dev->dv_xname, l)) {
+                       if (!name[l]) {
+                               /* Default partition, (or none at all) */
+                               dk_setroot(od, -1);
+                               return 0;
+                       }
+                       if (!name[l + 1]) {
+                               switch (name[l]) {
+                               case '*':
+                                       /* Default partition */
+                                       dk_setroot(od, -1);
+                                       return 0;
+                               default:
+                                       if (name[l] >= 'a'
+                                           && name[l] < 'a' + MAXPARTITIONS) {
+                                               /* specified partition */
+                                               dk_setroot(od, name[l] - 'a');
+                                               return 0;
+                                       }
+                                       break;
+                               }
+                       }
+               }
+       }
+       /*
+        * Now try the OpenFirmware name
+        */
+       l = strlen(name);
+       for (cp = name + l; --cp >= name;)
+               if (*cp == '/' || *cp == ':')
+                       break;
+       if (cp >= name && *cp == ':')
+               *cp++ = 0;
+       else
+               cp = name + l;
+       part = *cp >= 'a' && *cp < 'a' + MAXPARTITIONS
+               ? *cp - 'a'
+               : -1;
+       while (--cp >= name && *cp != '@');
+       if (cp - 4 < name || bcmp(cp - 4, "disk", 4))
+               unit = -1;
+       else {
+               for (unit = 0; *++cp >= '0' && *cp <= '9';)
+                       unit = unit * 10 + *cp - '0';
+       }
+
+       if ((phandle = OF_finddevice(name)) != -1) {
+               for (od = ofb_head.lh_first; od; od = od->ofb_list.le_next) {
+                       if (phandle == od->ofb_phandle) {
+                               /* Check for matching units */
+                               if (od->ofb_dk
+                                   && od->ofb_unit != unit)
+                                       continue;
+                               dk_setroot(od, part);
+                               return 0;
+                       }
+               }
+       }
+       return ENODEV;
+}
+
+void
+ofrootfound()
+{
+       int node;
+       struct ofprobe probe;
+
+       if (!(node = OF_peer(0)))
+               panic("No PROM root");
+       probe.phandle = node;
+       if (!config_rootfound("ofroot", &probe))
+               panic("ofroot not configured");
+}
diff --git a/sys/arch/powerpc/powerpc/ofwreal.S b/sys/arch/powerpc/powerpc/ofwreal.S
new file mode 100644 (file)
index 0000000..fa16ebe
--- /dev/null
@@ -0,0 +1,340 @@
+/*     $NetBSD: ofwreal.S,v 1.1 1996/09/30 16:34:51 ws Exp $   */
+
+/*
+ * Copyright (C) 1996 Wolfgang Solfrank.
+ * Copyright (C) 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file provides a real-mode client interface on machines, that
+ * (incorrectly) only implement virtual mode client interface.
+ *
+ * It assumes though, that any actual memory in the machine is
+ * mapped 1:1 even by the virtual mode OpenFirmware.
+ * Furthermore it assumes that addresses returned by OpenFirmware are not
+ * accessed by the client.
+ *
+ * TODO: handle set-callback specially
+ */
+#include <machine/asm.h>
+#include <machine/psl.h>
+#include <machine/trap.h>
+
+#define        CACHELINE       32              /* Note that this value is really hardwired */
+
+       .data
+ofentry:       .long   0               /* actual entry to firmware in virtual mode */
+
+#define        BATSIZE         (8*8)
+#define        SRSIZE          (16*4)
+#define        SPRGSIZE        (4*4)
+#define        SDR1SIZE        4
+#define        SI1SIZE         (2*256)
+#define        SI2SIZE         (3*256)
+#define        SVSIZE          (BATSIZE+SRSIZE+SPRGSIZE+SDR1SIZE+SI1SIZE+SI2SIZE)
+
+.lcomm fwsave,SVSIZE,8
+.lcomm clsave,SVSIZE,8
+
+_ENTRY(_C_LABEL(ofwr_init))
+       mflr    31                      /* save return address */
+
+       mr      13,6                    /* save args (only pointer used) */
+       lis     8,ofentry@ha
+       stw     5,ofentry@l(8)          /* save virtual mode firmware entry */
+
+       lis     3,fwsave@ha             /* save the mmu values of the firmware */
+       addi    3,3,fwsave@l
+       bl      savemmu
+
+       lis     5,fwentry@ha            /* get new firmware entry */
+       addi    5,5,fwentry@l
+
+       mr      6,13                    /* restore args pointer */
+       mtlr    31                      /* restore return address */
+       blr
+
+/*
+ * Emulated firmware entry.
+ */
+fwentry:
+       mflr    0                       /* save return address */
+       stw     0,4(1)
+       stwu    1,-16(1)                /* setup stack frame */
+       stw     3,8(1)                  /* save arg */
+
+       lis     3,clsave@ha             /* save mmu values of client */
+       addi    3,3,clsave@l
+       bl      savemmu
+
+       lis     3,fwsave@ha             /* restore mmu values of firmware */
+       addi    3,3,fwsave@l
+       bl      restoremmu
+
+       lis     3,ofentry@ha
+       lwz     3,ofentry@l(3)          /* get actual firmware entry */
+       mtlr    3
+
+       mfmsr   4
+       ori     4,4,PSL_IR|PSL_DR       /* turn on MMU */
+       mtmsr   4
+       isync
+
+       lwz     3,8(1)                  /* restore arg */
+       blrl                            /* do actual firmware call */
+
+       stw     3,8(1)                  /* save return value */
+
+       mfmsr   4
+       andi.   4,4,~(PSL_IR|PSL_DR)    /* turn off MMU */
+       mtmsr   4
+       isync
+
+       lis     3,fwsave@ha             /* save mmu values of firmare */
+       addi    3,3,fwsave@l            /* (might not be necessary, but... */
+       bl      savemmu
+
+       lis     3,clsave@ha             /* restore mmu values of client */
+       addi    3,3,clsave@l
+       bl      restoremmu
+
+       lwz     3,8(1)                  /* restore return value */
+       lwz     1,0(1)                  /* and return */
+       lwz     0,4(1)
+       mtlr    0
+       blr
+
+/*
+ * Save everyting related to the mmu to the saveare pointed to by r3.
+ */
+savemmu:
+
+       mfibatl 4,0                     /* save BATs */
+       stw     4,0(3)
+       mfibatu 4,0
+       stw     4,4(3)
+       mfibatl 4,1
+       stw     4,8(3)
+       mfibatu 4,1
+       stw     4,12(3)
+       mfibatl 4,2
+       stw     4,16(3)
+       mfibatu 4,2
+       stw     4,20(3)
+       mfibatl 4,3
+       stw     4,24(3)
+       mfibatu 4,3
+       stw     4,28(3)
+       mfdbatl 4,0
+       stw     4,32(3)
+       mfdbatu 4,0
+       stw     4,36(3)
+       mfdbatl 4,1
+       stw     4,40(3)
+       mfdbatu 4,1
+       stw     4,44(3)
+       mfdbatl 4,2
+       stw     4,48(3)
+       mfdbatu 4,2
+       stw     4,52(3)
+       mfdbatl 4,3
+       stw     4,56(3)
+       mfdbatu 4,3
+       stwu    4,60(3)
+
+       li      4,0                     /* save SRs */
+1:
+       addis   4,4,-0x10000000@ha
+       or.     4,4,4
+       mfsrin  5,4
+       stwu    5,4(3)
+       bne     1b
+
+       mfsprg  4,0                     /* save SPRGs */
+       stw     4,4(3)
+       mfsprg  4,1
+       stw     4,8(3)
+       mfsprg  4,2
+       stw     4,12(3)
+       mfsprg  4,3
+       stw     4,16(3)
+
+       mfsdr1  4                       /* save SDR1 */
+       stw     4,20(3)
+
+       addi    4,3,24
+       mflr    11
+       li      3,EXC_DSI               /* save DSI/ISI trap vectors */
+       li      5,SI1SIZE
+       bl      copy
+
+       mtlr    11
+       li      3,EXC_IMISS             /* save MISS trap vectors */
+       li      5,SI2SIZE
+
+copy:
+       li      6,CACHELINE
+1:
+       lwz     7,0(3)
+       lwz     8,4(3)
+       lwz     9,8(3)
+       lwz     10,12(3)
+       stw     7,0(4)
+       stw     8,4(4)
+       stw     9,8(4)
+       stw     10,12(4)
+       lwz     7,16(3)
+       lwz     8,20(3)
+       lwz     9,24(3)
+       lwz     10,28(3)
+       stw     7,16(4)
+       stw     8,20(4)
+       stw     9,24(4)
+       stw     10,28(4)
+       dcbst   0,4
+       icbi    0,4
+       add     3,3,6
+       add     4,4,6
+       subf.   5,6,5
+       bgt     1b
+
+       dcbst   0,4
+       icbi    0,4
+
+       sync
+       isync
+
+       blr
+
+/*
+ * Restore everyting related to the mmu from the saveare pointed to by r3.
+ */
+restoremmu:
+
+       li      4,0                     /* first, invalidate BATs */
+       mtibatu 0,4
+       mtibatu 1,4
+       mtibatu 2,4
+       mtibatu 3,4
+       mtdbatu 0,4
+       mtdbatu 1,4
+       mtdbatu 2,4
+       mtdbatu 3,4
+
+       lwz     4,0(3)
+       mtibatl 0,4                     /* restore BATs */
+       lwz     4,4(3)
+       mtibatu 0,4
+       lwz     4,8(3)
+       mtibatl 1,4
+       lwz     4,12(3)
+       mtibatu 1,4
+       lwz     4,16(3)
+       mtibatl 2,4
+       lwz     4,20(3)
+       mtibatu 2,4
+       lwz     4,24(3)
+       mtibatl 3,4
+       lwz     4,28(3)
+       mtibatu 3,4
+       lwz     4,32(3)
+       mtdbatl 0,4
+       lwz     4,36(3)
+       mtdbatu 0,4
+       lwz     4,40(3)
+       mtdbatl 1,4
+       lwz     4,44(3)
+       mtdbatu 1,4
+       lwz     4,48(3)
+       mtdbatl 2,4
+       lwz     4,52(3)
+       mtdbatu 2,4
+       lwz     4,56(3)
+       mtdbatl 3,4
+       lwzu    4,60(3)
+       mtdbatu 3,4
+
+       li      4,0                     /* restore SRs */
+1:
+       lwzu    5,4(3)
+       addis   4,4,-0x10000000@ha
+       or.     4,4,4
+       mtsrin  5,4
+       bne     1b
+
+       lwz     4,4(3)
+       mtsprg  0,4                     /* restore SPRGs */
+       lwz     4,8(3)
+       mtsprg  1,4
+       lwz     4,12(3)
+       mtsprg  2,4
+       lwz     4,16(3)
+       mtsprg  3,4
+
+       sync                            /* remove everything from tlb */
+       lis     4,0x40000@ha
+       li      5,0x1000
+1:
+       subf.   4,5,4
+       tlbie   4
+       bne     1b
+
+       sync
+       tlbsync
+       sync
+
+       lwz     4,20(3)
+       sync
+       mtsdr1  4                       /* restore SDR1 */
+
+       addi    3,3,24
+       mflr    11
+       li      4,EXC_DSI               /* restore DSI/ISI trap vectors */
+       li      5,SI1SIZE
+       bl      copy
+
+       li      4,EXC_IMISS             /* restore MISS trap vectors */
+       li      5,SI2SIZE
+       bl      copy
+
+       /* tlbia */
+       sync
+       li      3,0x40
+       mtctr   3
+       li      4,0
+    1:
+       tlbie   4
+       addi    4,4,0x1000
+       bdnz    1b
+       sync
+       tlbsync
+       sync
+
+       mtlr    11
+       blr
diff --git a/sys/arch/powerpc/powerpc/openfirm.c b/sys/arch/powerpc/powerpc/openfirm.c
new file mode 100644 (file)
index 0000000..e282c09
--- /dev/null
@@ -0,0 +1,610 @@
+/*     $NetBSD: openfirm.c,v 1.1 1996/09/30 16:34:52 ws Exp $  */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/param.h>
+
+#include <machine/psl.h>
+#include <machine/stdarg.h>
+
+#include <dev/ofw/openfirm.h>
+
+char *OF_buf;
+
+extern void ofw_stack __P((void));
+extern void ofbcopy __P((const void *, void *, size_t));
+
+int
+OF_peer(phandle)
+       int phandle;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int phandle;
+               int sibling;
+       } args = {
+               "peer",
+               1,
+               1,
+       };
+       
+       ofw_stack();
+       args.phandle = phandle;
+       if (openfirmware(&args) == -1)
+               return 0;
+       return args.sibling;
+}
+
+int
+OF_child(phandle)
+       int phandle;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int phandle;
+               int child;
+       } args = {
+               "child",
+               1,
+               1,
+       };
+       
+       ofw_stack();
+       args.phandle = phandle;
+       if (openfirmware(&args) == -1)
+               return 0;
+       return args.child;
+}
+
+int
+OF_parent(phandle)
+       int phandle;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int phandle;
+               int parent;
+       } args = {
+               "parent",
+               1,
+               1,
+       };
+       
+       ofw_stack();
+       args.phandle = phandle;
+       if (openfirmware(&args) == -1)
+               return 0;
+       return args.parent;
+}
+
+int
+OF_instance_to_package(ihandle)
+       int ihandle;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int ihandle;
+               int phandle;
+       } args = {
+               "instance-to-package",
+               1,
+               1,
+       };
+
+       ofw_stack();
+       args.ihandle = ihandle;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.phandle;
+}
+
+int
+OF_getprop(handle, prop, buf, buflen)
+       int handle;
+       char *prop;
+       void *buf;
+       int buflen;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int phandle;
+               char *prop;
+               void *buf;
+               int buflen;
+               int size;
+       } args = {
+               "getprop",
+               4,
+               1,
+       };
+
+       ofw_stack();
+       if (buflen > NBPG)
+               return -1;
+       args.phandle = handle;
+       args.prop = prop;
+       args.buf = OF_buf;
+       args.buflen = buflen;
+       if (openfirmware(&args) == -1)
+               return -1;
+       if (args.size > 0)
+               ofbcopy(OF_buf, buf, args.size);
+       return args.size;
+}
+
+int
+OF_finddevice(name)
+       char *name;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               char *device;
+               int phandle;
+       } args = {
+               "finddevice",
+               1,
+               1,
+       };      
+
+       ofw_stack();
+       args.device = name;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.phandle;
+}
+
+int
+OF_instance_to_path(ihandle, buf, buflen)
+       int ihandle;
+       char *buf;
+       int buflen;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int ihandle;
+               char *buf;
+               int buflen;
+               int length;
+       } args = {
+               "instance-to-path",
+               3,
+               1,
+       };
+
+       if (buflen > NBPG)
+               return -1;
+       args.ihandle = ihandle;
+       args.buf = OF_buf;
+       args.buflen = buflen;
+       if (openfirmware(&args) < 0)
+               return -1;
+       if (args.length > 0)
+               ofbcopy(OF_buf, buf, args.length);
+       return args.length;
+}
+
+int
+OF_package_to_path(phandle, buf, buflen)
+       int phandle;
+       char *buf;
+       int buflen;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int phandle;
+               char *buf;
+               int buflen;
+               int length;
+       } args = {
+               "package-to-path",
+               3,
+               1,
+       };
+       
+       ofw_stack();
+       if (buflen > NBPG)
+               return -1;
+       args.phandle = phandle;
+       args.buf = OF_buf;
+       args.buflen = buflen;
+       if (openfirmware(&args) < 0)
+               return -1;
+       if (args.length > 0)
+               ofbcopy(OF_buf, buf, args.length);
+       return args.length;
+}
+
+int
+#ifdef __STDC__
+OF_call_method(char *method, int ihandle, int nargs, int nreturns, ...)
+#else
+OF_call_method(method, ihandle, nargs, nreturns, va_alist)
+       char *method;
+       int ihandle;
+       int nargs;
+       int nreturns;
+       va_dcl
+#endif
+{
+       va_list ap;
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               char *method;
+               int ihandle;
+               int args_n_results[12];
+       } args = {
+               "call-method",
+               2,
+               1,
+       };
+       int *ip, n;
+       
+       if (nargs > 6)
+               return -1;
+       args.nargs = nargs + 2;
+       args.nreturns = nreturns + 1;
+       args.method = method;
+       args.ihandle = ihandle;
+       va_start(ap, nreturns);
+       for (ip = args.args_n_results + (n = nargs); --n >= 0;)
+               *--ip = va_arg(ap, int);
+       ofw_stack();
+       if (openfirmware(&args) == -1)
+               return -1;
+       if (args.args_n_results[nargs])
+               return args.args_n_results[nargs];
+       for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
+               *va_arg(ap, int *) = *--ip;
+       va_end(ap);
+       return 0;
+}
+
+int
+#ifdef __STDC__
+OF_call_method_1(char *method, int ihandle, int nargs, ...)
+#else
+OF_call_method_1(method, ihandle, nargs, va_alist)
+       char *method;
+       int ihandle;
+       int nargs;
+       va_dcl
+#endif
+{
+       va_list ap;
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               char *method;
+               int ihandle;
+               int args_n_results[8];
+       } args = {
+               "call-method",
+               2,
+               2,
+       };
+       int *ip, n;
+       
+       if (nargs > 6)
+               return -1;
+       args.nargs = nargs + 2;
+       args.method = method;
+       args.ihandle = ihandle;
+       va_start(ap, nargs);
+       for (ip = args.args_n_results + (n = nargs); --n >= 0;)
+               *--ip = va_arg(ap, int);
+       va_end(ap);
+       ofw_stack();
+       if (openfirmware(&args) == -1)
+               return -1;
+       if (args.args_n_results[nargs])
+               return -1;
+       return args.args_n_results[nargs + 1];
+}
+
+int
+OF_open(dname)
+       char *dname;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               char *dname;
+               int handle;
+       } args = {
+               "open",
+               1,
+               1,
+       };
+       int l;
+       
+       ofw_stack();
+       if ((l = strlen(dname)) >= NBPG)
+               return -1;
+       ofbcopy(dname, OF_buf, l + 1);
+       args.dname = OF_buf;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.handle;
+}
+
+void
+OF_close(handle)
+       int handle;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int handle;
+       } args = {
+               "close",
+               1,
+               0,
+       };
+
+       ofw_stack();
+       args.handle = handle;
+       openfirmware(&args);
+}
+
+/* 
+ * This assumes that character devices don't read in multiples of NBPG.
+ */
+int
+OF_read(handle, addr, len)
+       int handle;
+       void *addr;
+       int len;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int ihandle;
+               void *addr;
+               int len;
+               int actual;
+       } args = {
+               "read",
+               3,
+               1,
+       };
+       int l, act = 0;
+       
+       ofw_stack();
+       args.ihandle = handle;
+       args.addr = OF_buf;
+       for (; len > 0; len -= l, addr += l) {
+               l = min(NBPG, len);
+               args.len = l;
+               if (openfirmware(&args) == -1)
+                       return -1;
+               if (args.actual > 0) {
+                       ofbcopy(OF_buf, addr, args.actual);
+                       act += args.actual;
+               }
+               if (args.actual < l)
+                       if (act)
+                               return act;
+                       else
+                               return args.actual;
+       }
+       return act;
+}
+
+int
+OF_write(handle, addr, len)
+       int handle;
+       void *addr;
+       int len;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int ihandle;
+               void *addr;
+               int len;
+               int actual;
+       } args = {
+               "write",
+               3,
+               1,
+       };
+       int l, act = 0;
+       
+       ofw_stack();
+       args.ihandle = handle;
+       args.addr = OF_buf;
+       for (; len > 0; len -= l, addr += l) {
+               l = min(NBPG, len);
+               ofbcopy(addr, OF_buf, l);
+               args.len = l;
+               if (openfirmware(&args) == -1)
+                       return -1;
+               l = args.actual;
+               act += l;
+       }
+       return act;
+}
+
+int
+OF_seek(handle, pos)
+       int handle;
+       u_quad_t pos;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int handle;
+               int poshi;
+               int poslo;
+               int status;
+       } args = {
+               "seek",
+               3,
+               1,
+       };
+
+       ofw_stack();
+       args.handle = handle;
+       args.poshi = (int)(pos >> 32);
+       args.poslo = (int)pos;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.status;
+}
+
+void
+OF_boot(bootspec)
+       char *bootspec;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               char *bootspec;
+       } args = {
+               "boot",
+               1,
+               0,
+       };
+       int l;
+       
+       if ((l = strlen(bootspec)) >= NBPG)
+               panic("OF_boot");
+       ofw_stack();
+       ofbcopy(bootspec, OF_buf, l + 1);
+       args.bootspec = OF_buf;
+       openfirmware(&args);
+       while (1);                      /* just in case */
+}
+
+void
+OF_enter()
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+       } args = {
+               "enter",
+               0,
+               0,
+       };
+
+       ofw_stack();
+       openfirmware(&args);
+}
+
+void
+OF_exit()
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+       } args = {
+               "exit",
+               0,
+               0,
+       };
+
+       ofw_stack();
+       openfirmware(&args);
+       while (1);                      /* just in case */
+}
+
+void
+(*OF_set_callback(newfunc))()
+       void (*newfunc)();
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               void (*newfunc)();
+               void (*oldfunc)();
+       } args = {
+               "set-callback",
+               1,
+               1,
+       };
+
+       ofw_stack();
+       args.newfunc = newfunc;
+       if (openfirmware(&args) == -1)
+               return 0;
+       return args.oldfunc;
+}
+
+/*
+ * This version of bcopy doesn't work for overlapping regions!
+ */
+void
+ofbcopy(src, dst, len)
+       const void *src;
+       void *dst;
+       size_t len;
+{
+       const char *sp = src;
+       char *dp = dst;
+
+       if (src == dst)
+               return;
+       
+       /*
+        * Do some optimization?                                                XXX
+        */
+       while (len-- > 0)
+               *dp++ = *sp++;
+}
diff --git a/sys/arch/powerpc/powerpc/pmap.c b/sys/arch/powerpc/powerpc/pmap.c
new file mode 100644 (file)
index 0000000..2ff4e0c
--- /dev/null
@@ -0,0 +1,1302 @@
+/*     $NetBSD: pmap.c,v 1.1 1996/09/30 16:34:52 ws Exp $      */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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/malloc.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+
+#include <machine/pcb.h>
+#include <machine/powerpc.h>
+
+pte_t *ptable;
+int ptab_cnt = HTABENTS;
+u_int ptab_mask;
+#define        HTABSIZE        (ptab_cnt * 64)
+
+struct pte_ovfl {
+       LIST_ENTRY(pte_ovfl) po_list;   /* Linked list of overflow entries */
+       struct pte po_pte;              /* PTE for this mapping */
+};
+
+LIST_HEAD(pte_ovtab, pte_ovfl) *potable; /* Overflow entries for ptable */
+
+struct pmap kernel_pmap_;
+
+int physmem;
+static int npgs;
+static u_int nextavail;
+
+static struct mem_region *mem, *avail;
+
+/*
+ * This is a cache of referenced/modified bits.
+ * Bits herein are shifted by ATTRSHFT.
+ */
+static char *pmap_attrib;
+#define        ATTRSHFT        4
+
+struct pv_entry {
+       struct pv_entry *pv_next;       /* Linked list of mappings */
+       int pv_idx;                     /* Index into ptable */
+       vm_offset_t pv_va;              /* virtual address of mapping */
+};
+
+struct pv_entry *pv_table;
+
+struct pv_page;
+struct pv_page_info {
+       LIST_ENTRY(pv_page) pgi_list;
+       struct pv_entry *pgi_freelist;
+       int pgi_nfree;
+};
+#define        NPVPPG  ((NBPG - sizeof(struct pv_page_info)) / sizeof(struct pv_entry))
+struct pv_page {
+       struct pv_page_info pvp_pgi;
+       struct pv_entry pvp_pv[NPVPPG];
+};
+LIST_HEAD(pv_page_list, pv_page) pv_page_freelist;
+int pv_nfree;
+int pv_pcnt;
+static struct pv_entry *pmap_alloc_pv __P((void));
+static void pmap_free_pv __P((struct pv_entry *));
+
+struct po_page;
+struct po_page_info {
+       LIST_ENTRY(po_page) pgi_list;
+       vm_page_t pgi_page;
+       LIST_HEAD(po_freelist, pte_ovfl) pgi_freelist;
+       int pgi_nfree;
+};
+#define        NPOPPG  ((NBPG - sizeof(struct po_page_info)) / sizeof(struct pte_ovfl))
+struct po_page {
+       struct po_page_info pop_pgi;
+       struct pte_ovfl pop_po[NPOPPG];
+};
+LIST_HEAD(po_page_list, po_page) po_page_freelist;
+int po_nfree;
+int po_pcnt;
+static struct pte_ovfl *poalloc __P((void));
+static void pofree __P((struct pte_ovfl *, int));
+
+static u_int usedsr[NPMAPS / sizeof(u_int) / 8];
+
+static int pmap_initialized;
+
+/*
+ * These small routines may have to be replaced,
+ * if/when we support processors other that the 604.
+ */
+static inline void
+tlbie(ea)
+       caddr_t ea;
+{
+       asm volatile ("tlbie %0" :: "r"(ea));
+}
+
+static inline void
+tlbsync()
+{
+       asm volatile ("sync; tlbsync; sync");
+}
+
+static void
+tlbia()
+{
+       caddr_t i;
+       
+       asm volatile ("sync");
+       for (i = 0; i < (caddr_t)0x00040000; i += 0x00001000)
+               tlbie(i);
+       tlbsync();
+}
+
+static inline int
+ptesr(sr, addr)
+       sr_t *sr;
+       vm_offset_t addr;
+{
+       return sr[(u_int)addr >> ADDR_SR_SHFT];
+}
+
+static inline int
+pteidx(sr, addr)
+       sr_t sr;
+       vm_offset_t addr;
+{
+       int hash;
+       
+       hash = (sr & SR_VSID) ^ (((u_int)addr & ADDR_PIDX) >> ADDR_PIDX_SHFT);
+       return hash & ptab_mask;
+}
+
+static inline int
+ptematch(ptp, sr, va, which)
+       pte_t *ptp;
+       sr_t sr;
+       vm_offset_t va;
+       int which;
+{
+       return ptp->pte_hi
+               == (((sr & SR_VSID) << PTE_VSID_SHFT)
+                   | (((u_int)va >> ADDR_API_SHFT) & PTE_API)
+                   | which);
+}
+
+/*
+ * Try to insert page table entry *pt into the ptable at idx.
+ *
+ * Note: *pt mustn't have PTE_VALID set.
+ * This is done here as required by Book III, 4.12.
+ */
+static int
+pte_insert(idx, pt)
+       int idx;
+       pte_t *pt;
+{
+       pte_t *ptp;
+       int i;
+       
+       /*
+        * First try primary hash.
+        */
+       for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++)
+               if (!(ptp->pte_hi & PTE_VALID)) {
+                       *ptp = *pt;
+                       ptp->pte_hi &= ~PTE_HID;
+                       asm volatile ("sync");
+                       ptp->pte_hi |= PTE_VALID;
+                       return 1;
+               }
+       idx ^= ptab_mask;
+       for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++)
+               if (!(ptp->pte_hi & PTE_VALID)) {
+                       *ptp = *pt;
+                       ptp->pte_hi |= PTE_HID;
+                       asm volatile ("sync");
+                       ptp->pte_hi |= PTE_VALID;
+                       return 1;
+               }
+       return 0;
+}
+
+/*
+ * Spill handler.
+ *
+ * Tries to spill a page table entry from the overflow area.
+ * Note that this routine runs in real mode on a separate stack,
+ * with interrupts disabled.
+ */
+int
+pte_spill(addr)
+       vm_offset_t addr;
+{
+       int idx, i;
+       sr_t sr;
+       struct pte_ovfl *po;
+       pte_t ps;
+       pte_t *pt;
+
+       asm ("mfsrin %0,%1" : "=r"(sr) : "r"(addr));
+       idx = pteidx(sr, addr);
+       for (po = potable[idx].lh_first; po; po = po->po_list.le_next)
+               if (ptematch(&po->po_pte, sr, addr, 0)) {
+                       /*
+                        * Now found an entry to be spilled into the real ptable.
+                        */
+                       if (pte_insert(idx, &po->po_pte)) {
+                               LIST_REMOVE(po, po_list);
+                               pofree(po, 0);
+                               return 1;
+                       }
+                       /*
+                        * Have to substitute some entry. Use the primary hash for this.
+                        *
+                        * Use low bits of timebase as random generator
+                        */
+                       asm ("mftb %0" : "=r"(i));
+                       pt = ptable + idx * 8 + (i & 7);
+                       pt->pte_hi &= ~PTE_VALID;
+                       ps = *pt;
+                       asm volatile ("sync");
+                       tlbie(addr);
+                       tlbsync();
+                       *pt = po->po_pte;
+                       asm volatile ("sync");
+                       pt->pte_hi |= PTE_VALID;
+                       po->po_pte = ps;
+                       if (ps.pte_hi & PTE_HID) {
+                               /*
+                                * We took an entry that was on the alternate hash
+                                * chain, so move it to it's original chain.
+                                */
+                               po->po_pte.pte_hi &= ~PTE_HID;
+                               LIST_REMOVE(po, po_list);
+                               LIST_INSERT_HEAD(potable + (idx ^ ptab_mask),
+                                                po, po_list);
+                       }
+                       return 1;
+               }
+       return 0;
+}
+
+int avail_start __asm__ ("_avail_start");
+int avail_end __asm__ ("_avail_end");
+/*
+ * This is called during initppc, before the system is really initialized.
+ */
+void
+pmap_bootstrap(kernelstart, kernelend)
+       u_int kernelstart, kernelend;
+{
+       struct mem_region *mp, *mp1;
+       int cnt, i;
+       u_int s, sz;
+
+       /*
+        * Get memory.
+        */
+       mem_regions(&mem, &avail);
+       for (mp = mem; mp->size; mp++)
+               physmem += btoc(mp->size);
+
+       /*
+        * Count the number of available entries.
+        */
+       for (cnt = 0, mp = avail; mp->size; mp++)
+               cnt++;
+
+       /*
+        * Page align all regions.
+        * Non-page memory isn't very interesting to us.
+        * Also, sort the entries for ascending addresses.
+        */
+       kernelstart &= ~PGOFSET;
+       kernelend = (kernelend + PGOFSET) & ~PGOFSET;
+       for (mp = avail; mp->size; mp++) {
+               /*
+                * Check whether this region holds all of the kernel.
+                */
+               s = mp->start + mp->size;
+               if (mp->start < kernelstart && s > kernelend) {
+                       avail[cnt].start = kernelend;
+                       avail[cnt++].size = s - kernelend;
+                       mp->size = kernelstart - mp->start;
+               }
+               /*
+                * Look whether this regions starts within the kernel.
+                */
+               if (mp->start >= kernelstart && mp->start < kernelend) {
+                       s = kernelend - mp->start;
+                       if (mp->size > s)
+                               mp->size -= s;
+                       else
+                               mp->size = 0;
+                       mp->start = kernelend;
+               }
+               /*
+                * Now look whether this region ends within the kernel.
+                */
+               s = mp->start + mp->size;
+               if (s > kernelstart && s < kernelend)
+                       mp->size -= s - kernelstart;
+               /*
+                * Now page align the start of the region.
+                */
+               s = mp->start % NBPG;
+               if (mp->size >= s) {
+                       mp->size -= s;
+                       mp->start += s;
+               }
+               /*
+                * And now align the size of the region.
+                */
+               mp->size -= mp->size % NBPG;
+               /*
+                * Check whether some memory is left here.
+                */
+               if (mp->size == 0) {
+                       bcopy(mp + 1, mp,
+                             (cnt - (mp - avail)) * sizeof *mp);
+                       cnt--;
+                       mp--;
+                       continue;
+               }
+               s = mp->start;
+               sz = mp->size;
+               npgs += btoc(sz);
+               for (mp1 = avail; mp1 < mp; mp1++)
+                       if (s < mp1->start)
+                               break;
+               if (mp1 < mp) {
+                       bcopy(mp1, mp1 + 1, (void *)mp - (void *)mp1);
+                       mp1->start = s;
+                       mp1->size = sz;
+               }
+       }
+avail_start = 0;
+avail_end = npgs * NBPG;
+       /*
+        * Find suitably aligned memory for HTAB.
+        */
+       for (mp = avail; mp->size; mp++) {
+               s = mp->size % HTABSIZE;
+               if (mp->size < s + HTABSIZE)
+                       continue;
+               ptable = (pte_t *)(mp->start + s);
+               if (mp->size == s + HTABSIZE) {
+                       if (s)
+                               mp->size = s;
+                       else {
+                               bcopy(mp + 1, mp,
+                                     (cnt - (mp - avail)) * sizeof *mp);
+                               mp = avail;
+                       }
+                       break;
+               }
+               if (s != 0) {
+                       bcopy(mp, mp + 1,
+                             (cnt - (mp - avail)) * sizeof *mp);
+                       mp++->size = s;
+               }
+               mp->start += s + HTABSIZE;
+               mp->size -= s + HTABSIZE;
+               break;
+       }
+       if (!mp->size)
+               panic("not enough memory?");
+       bzero((void *)ptable, HTABSIZE);
+       ptab_mask = ptab_cnt - 1;
+       
+       /*
+        * We cannot do pmap_steal_memory here,
+        * since we don't run with translation enabled yet.
+        */
+       s = sizeof(struct pte_ovtab) * ptab_cnt;
+       sz = round_page(s);
+       for (mp = avail; mp->size; mp++)
+               if (mp->size >= sz)
+                       break;
+       if (!mp->size)
+               panic("not enough memory?");
+       potable = (struct pte_ovtab *)mp->start;
+       mp->size -= sz;
+       mp->start += sz;
+       if (mp->size <= 0)
+               bcopy(mp + 1, mp, (cnt - (mp - avail)) * sizeof *mp);
+       for (i = 0; i < ptab_cnt; i++)
+               LIST_INIT(potable + i);
+       LIST_INIT(&pv_page_freelist);
+       
+       /*
+        * Initialize kernel pmap and hardware.
+        */
+#if NPMAPS >= KERNEL_SEGMENT / 16
+       usedsr[KERNEL_SEGMENT / 16 / (sizeof usedsr[0] * 8)]
+               |= 1 << ((KERNEL_SEGMENT / 16) % (sizeof usedsr[0] * 8));
+#endif
+       for (i = 0; i < 16; i++) {
+               pmap_kernel()->pm_sr[i] = EMPTY_SEGMENT;
+               asm volatile ("mtsrin %0,%1"
+                             :: "r"(i << ADDR_SR_SHFT), "r"(EMPTY_SEGMENT));
+       }
+       pmap_kernel()->pm_sr[KERNEL_SR] = KERNEL_SEGMENT;
+       asm volatile ("mtsr %0,%1"
+                     :: "n"(KERNEL_SR), "r"(KERNEL_SEGMENT));
+       asm volatile ("sync; mtsdr1 %0; isync"
+                     :: "r"((u_int)ptable | (ptab_mask >> 10)));
+       tlbia();
+       nextavail = avail->start;
+}
+
+/*
+ * Restrict given range to physical memory
+ */
+void
+pmap_real_memory(start, size)
+       vm_offset_t *start;
+       vm_size_t *size;
+{
+       struct mem_region *mp;
+       
+       for (mp = mem; mp->size; mp++) {
+               if (*start + *size > mp->start
+                   && *start < mp->start + mp->size) {
+                       if (*start < mp->start) {
+                               *size -= mp->start - *start;
+                               *start = mp->start;
+                       }
+                       if (*start + *size > mp->start + mp->size)
+                               *size = mp->start + mp->size - *start;
+                       return;
+               }
+       }
+       *size = 0;
+}
+
+/*
+ * Initialize anything else for pmap handling.
+ * Called during vm_init().
+ */
+void
+pmap_init()
+{
+       struct pv_entry *pv;
+       vm_size_t sz;
+       vm_offset_t addr;
+       int i, s;
+       
+       sz = (vm_size_t)((sizeof(struct pv_entry) + 1) * npgs);
+       sz = round_page(sz);
+       addr = (vm_offset_t)kmem_alloc(kernel_map, sz);
+       s = splimp();
+       pv = pv_table = (struct pv_entry *)addr;
+       for (i = npgs; --i >= 0;)
+               pv++->pv_idx = -1;
+       LIST_INIT(&pv_page_freelist);
+       pmap_attrib = (char *)pv;
+       bzero(pv, npgs);
+       pmap_initialized = 1;
+       splx(s);
+}
+
+/*
+ * Return the index of the given page in terms of pmap_next_page() calls.
+ */
+int
+pmap_page_index(pa)
+       vm_offset_t pa;
+{
+       struct mem_region *mp;
+       vm_size_t pre;
+       
+       pa &= ~PGOFSET;
+       for (pre = 0, mp = avail; mp->size; mp++) {
+               if (pa >= mp->start
+                   && pa < mp->start + mp->size)
+                       return btoc(pre + (pa - mp->start));
+               pre += mp->size;
+       }
+       return -1;
+}
+
+/*
+ * How much virtual space is available to the kernel?
+ */
+void
+pmap_virtual_space(start, end)
+       vm_offset_t *start, *end;
+{
+       /*
+        * Reserve one segment for kernel virtual memory
+        */
+       *start = (vm_offset_t)(KERNEL_SR << ADDR_SR_SHFT);
+       *end = *start + SEGMENT_LENGTH;
+}
+
+/*
+ * Return the number of possible page indices returned
+ * from pmap_page_index for any page provided by pmap_next_page.
+ */
+u_int
+pmap_free_pages()
+{
+       return npgs;
+}
+
+/*
+ * If there are still physical pages available, put the address of
+ * the next available one at paddr and return TRUE.  Otherwise,
+ * return FALSE to indicate that there are no more free pages.
+ */
+int
+pmap_next_page(paddr)
+       vm_offset_t *paddr;
+{
+       static int lastidx = -1;
+       
+       if (lastidx < 0
+           || nextavail >= avail[lastidx].start + avail[lastidx].size) {
+               if (avail[++lastidx].size == 0)
+                       return FALSE;
+               nextavail = avail[lastidx].start;
+       }
+       *paddr = nextavail;
+       nextavail += NBPG;
+       return TRUE;
+}
+
+/*
+ * Create and return a physical map.
+ */
+struct pmap *
+pmap_create(size)
+       vm_size_t size;
+{
+       struct pmap *pm;
+       
+       pm = (struct pmap *)malloc(sizeof *pm, M_VMPMAP, M_WAITOK);
+       bzero((caddr_t)pm, sizeof *pm);
+       pmap_pinit(pm);
+       return pm;
+}
+
+/*
+ * Initialize a preallocated and zeroed pmap structure.
+ */
+void
+pmap_pinit(pm)
+       struct pmap *pm;
+{
+       int i, j;
+       
+       /*
+        * Allocate some segment registers for this pmap.
+        */
+       pm->pm_refs = 1;
+       for (i = 0; i < sizeof usedsr / sizeof usedsr[0]; i++)
+               if (usedsr[i] != 0xffffffff) {
+                       j = ffs(~usedsr[i]) - 1;
+                       usedsr[i] |= 1 << j;
+                       pm->pm_sr[0] = (i * sizeof usedsr[0] * 8 + j) * 16;
+                       for (i = 1; i < 16; i++)
+                               pm->pm_sr[i] = pm->pm_sr[i - 1] + 1;
+                       return;
+               }
+       panic("out of segments");
+}
+
+/*
+ * Add a reference to the given pmap.
+ */
+void
+pmap_reference(pm)
+       struct pmap *pm;
+{
+       pm->pm_refs++;
+}
+
+/*
+ * Retire the given pmap from service.
+ * Should only be called if the map contains no valid mappings.
+ */
+void
+pmap_destroy(pm)
+       struct pmap *pm;
+{
+       if (--pm->pm_refs == 0) {
+               pmap_release(pm);
+               free((caddr_t)pm, M_VMPMAP);
+       }
+}
+
+/*
+ * Release any resources held by the given physical map.
+ * Called when a pmap initialized by pmap_pinit is being released.
+ */
+void
+pmap_release(pm)
+       struct pmap *pm;
+{
+       int i, j;
+       
+       if (!pm->pm_sr[0])
+               panic("pmap_release");
+       i = pm->pm_sr[0] / 16;
+       j = i % (sizeof usedsr[0] * 8);
+       i /= sizeof usedsr[0] * 8;
+       usedsr[i] &= ~(1 << j);
+}
+
+/*
+ * Copy the 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)
+       struct pmap *dst_pmap, *src_pmap;
+       vm_offset_t dst_addr, src_addr;
+       vm_size_t len;
+{
+}
+
+/*
+ * Require that all active physical maps contain no
+ * incorrect entries NOW.
+ */
+void
+pmap_update()
+{
+}
+
+/*
+ * 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(pm)
+       struct pmap *pm;
+{
+}
+
+/*
+ * Make the specified pages pageable or not as requested.
+ *
+ * This routine is merely advisory.
+ */
+void
+pmap_pageable(pm, start, end, pageable)
+       struct pmap *pm;
+       vm_offset_t start, end;
+       int pageable;
+{
+}
+
+/*
+ * Fill the given physical page with zeroes.
+ */
+void
+pmap_zero_page(pa)
+       vm_offset_t pa;
+{
+       bzero((caddr_t)pa, NBPG);
+}
+
+/*
+ * Copy the given physical source page to its destination.
+ */
+void
+pmap_copy_page(src, dst)
+       vm_offset_t src, dst;
+{
+       bcopy((caddr_t)src, (caddr_t)dst, NBPG);
+}
+
+static struct pv_entry *
+pmap_alloc_pv()
+{
+       struct pv_page *pvp;
+       struct pv_entry *pv;
+       int i;
+       
+       if (pv_nfree == 0) {
+               if (!(pvp = (struct pv_page *)kmem_alloc(kernel_map, NBPG)))
+                       panic("pmap_alloc_pv: kmem_alloc() failed");
+               pv_pcnt++;
+               pvp->pvp_pgi.pgi_freelist = pv = &pvp->pvp_pv[1];
+               for (i = NPVPPG - 2; --i >= 0; pv++)
+                       pv->pv_next = pv + 1;
+               pv->pv_next = 0;
+               pv_nfree += pvp->pvp_pgi.pgi_nfree = NPVPPG - 1;
+               LIST_INSERT_HEAD(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
+               pv = pvp->pvp_pv;
+       } else {
+               pv_nfree--;
+               pvp = pv_page_freelist.lh_first;
+               if (--pvp->pvp_pgi.pgi_nfree <= 0)
+                       LIST_REMOVE(pvp, pvp_pgi.pgi_list);
+               pv = pvp->pvp_pgi.pgi_freelist;
+               pvp->pvp_pgi.pgi_freelist = pv->pv_next;
+       }
+       return pv;
+}
+
+static 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:
+               LIST_INSERT_HEAD(&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;
+               pv_pcnt--;
+               LIST_REMOVE(pvp, pvp_pgi.pgi_list);
+               kmem_free(kernel_map, (vm_offset_t)pvp, NBPG);
+               break;
+       }
+}
+
+/*
+ * We really hope that we don't need overflow entries
+ * before the VM system is initialized!                                                        XXX
+ */
+static struct pte_ovfl *
+poalloc()
+{
+       struct po_page *pop;
+       struct pte_ovfl *po;
+       vm_page_t mem;
+       int i;
+       
+       if (!pmap_initialized)
+               panic("poalloc");
+       
+       if (po_nfree == 0) {
+               /*
+                * Since we cannot use maps for potable allocation,
+                * we have to steal some memory from the VM system.                     XXX
+                */
+               mem = vm_page_alloc(NULL, NULL);
+               po_pcnt++;
+               pop = (struct po_page *)VM_PAGE_TO_PHYS(mem);
+               pop->pop_pgi.pgi_page = mem;
+               LIST_INIT(&pop->pop_pgi.pgi_freelist);
+               for (i = NPOPPG - 1, po = pop->pop_po + 1; --i >= 0; po++)
+                       LIST_INSERT_HEAD(&pop->pop_pgi.pgi_freelist, po, po_list);
+               po_nfree += pop->pop_pgi.pgi_nfree = NPOPPG - 1;
+               LIST_INSERT_HEAD(&po_page_freelist, pop, pop_pgi.pgi_list);
+               po = pop->pop_po;
+       } else {
+               po_nfree--;
+               pop = po_page_freelist.lh_first;
+               if (--pop->pop_pgi.pgi_nfree <= 0)
+                       LIST_REMOVE(pop, pop_pgi.pgi_list);
+               po = pop->pop_pgi.pgi_freelist.lh_first;
+               LIST_REMOVE(po, po_list);
+       }
+       return po;
+}
+
+static void
+pofree(po, freepage)
+       struct pte_ovfl *po;
+       int freepage;
+{
+       struct po_page *pop;
+       
+       pop = (struct po_page *)trunc_page(po);
+       switch (++pop->pop_pgi.pgi_nfree) {
+       case NPOPPG:
+               if (!freepage)
+                       break;
+               po_nfree -= NPOPPG - 1;
+               po_pcnt--;
+               LIST_REMOVE(pop, pop_pgi.pgi_list);
+               vm_page_free(pop->pop_pgi.pgi_page);
+               return;
+       case 1:
+               LIST_INSERT_HEAD(&po_page_freelist, pop, pop_pgi.pgi_list);
+       default:
+               break;
+       }
+       LIST_INSERT_HEAD(&pop->pop_pgi.pgi_freelist, po, po_list);
+       po_nfree++;
+}
+
+/*
+ * This returns whether this is the first mapping of a page.
+ */
+static inline int
+pmap_enter_pv(pteidx, va, pind)
+       int pteidx;
+       vm_offset_t va;
+       u_int pind;
+{
+       struct pv_entry *pv, *npv;
+       int s, first;
+       
+       if (!pmap_initialized)
+               return 0;
+
+       s = splimp();
+
+       pv = &pv_table[pind];
+       if (first = pv->pv_idx == -1) {
+               /*
+                * No entries yet, use header as the first entry.
+                */
+               pv->pv_va = va;
+               pv->pv_idx = pteidx;
+               pv->pv_next = NULL;
+       } else {
+               /*
+                * There is at least one other VA mapping this page.
+                * Place this entry after the header.
+                */
+               npv = pmap_alloc_pv();
+               npv->pv_va = va;
+               npv->pv_idx = pteidx;
+               npv->pv_next = pv->pv_next;
+               pv->pv_next = npv;
+       }
+       splx(s);
+       return first;
+}
+
+static void
+pmap_remove_pv(pteidx, va, pind, pte)
+       int pteidx;
+       vm_offset_t va;
+       int pind;
+       struct pte *pte;
+{
+       struct pv_entry *pv, *npv;
+
+       if (pind < 0)
+               return;
+
+       /*
+        * First transfer reference/change bits to cache.
+        */
+       pmap_attrib[pind] |= (pte->pte_lo & (PTE_REF | PTE_CHG)) >> ATTRSHFT;
+       
+       /*
+        * Remove from the PV table.
+        */
+       pv = &pv_table[pind];
+       
+       /*
+        * 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 (pteidx == pv->pv_idx && va == pv->pv_va) {
+               npv = pv->pv_next;
+               if (npv) {
+                       *pv = *npv;
+                       pmap_free_pv(npv);
+               } else
+                       pv->pv_idx = -1;
+       } else {
+               for (; npv = pv->pv_next; pv = npv)
+                       if (pteidx == npv->pv_idx && va == npv->pv_va)
+                               break;
+               if (npv) {
+                       pv->pv_next = npv->pv_next;
+                       pmap_free_pv(npv);
+               }
+#ifdef DIAGNOSTIC
+               else
+                       panic("pmap_remove_pv: not on list\n");
+#endif
+       }
+}
+
+/*
+ * Insert physical page at pa into the given pmap at virtual address va.
+ */
+void
+pmap_enter(pm, va, pa, prot, wired)
+       struct pmap *pm;
+       vm_offset_t va, pa;
+       vm_prot_t prot;
+       int wired;
+{
+       sr_t sr;
+       int idx, i, s;
+       pte_t pte;
+       struct pte_ovfl *po;
+       struct mem_region *mp;
+
+       /*
+        * Have to remove any existing mapping first.
+        */
+       pmap_remove(pm, va, va + NBPG - 1);
+       
+       /*
+        * Compute the HTAB index.
+        */
+       idx = pteidx(sr = ptesr(pm->pm_sr, va), va);
+       /*
+        * Construct the PTE.
+        *
+        * Note: Don't set the valid bit for correct operation of tlb update.
+        */
+       pte.pte_hi = ((sr & SR_VSID) << PTE_VSID_SHFT)
+               | ((va & ADDR_PIDX) >> ADDR_API_SHFT);
+       pte.pte_lo = (pa & PTE_RPGN) | PTE_M | PTE_I | PTE_G;
+       for (mp = mem; mp->size; mp++) {
+               if (pa >= mp->start && pa < mp->start + mp->size) {
+                       pte.pte_lo &= ~(PTE_I | PTE_G);
+                       break;
+               }
+       }
+       if (prot & VM_PROT_WRITE)
+               pte.pte_lo |= PTE_RW;
+       else
+               pte.pte_lo |= PTE_RO;
+       
+       /*
+        * Now record mapping for later back-translation.
+        */
+       if (pmap_initialized && (i = pmap_page_index(pa)) != -1)
+               if (pmap_enter_pv(idx, va, i)) {
+                       /* 
+                        * Flush the real memory from the cache.
+                        */
+                       syncicache((void *)pa, NBPG);
+               }
+       
+       s = splimp();
+       /*
+        * Try to insert directly into HTAB.
+        */
+       if (pte_insert(idx, &pte)) {
+               splx(s);
+               return;
+       }
+       
+       /*
+        * Have to allocate overflow entry.
+        *
+        * Note, that we must use real addresses for these.
+        */
+       po = poalloc();
+       po->po_pte = pte;
+       LIST_INSERT_HEAD(potable + idx, po, po_list);
+       splx(s);
+}
+
+/*
+ * Remove the given range of mapping entries.
+ */
+void
+pmap_remove(pm, va, endva)
+       struct pmap *pm;
+       vm_offset_t va, endva;
+{
+       int idx, i, s;
+       sr_t sr;
+       pte_t *ptp;
+       struct pte_ovfl *po, *npo;
+       
+       s = splimp();
+       while (va < endva) {
+               idx = pteidx(sr = ptesr(pm->pm_sr, va), va);
+               for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++)
+                       if (ptematch(ptp, sr, va, PTE_VALID)) {
+                               pmap_remove_pv(idx, va, pmap_page_index(ptp->pte_lo), ptp);
+                               ptp->pte_hi &= ~PTE_VALID;
+                               asm volatile ("sync");
+                               tlbie(va);
+                               tlbsync();
+                       }
+               for (ptp = ptable + (idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++)
+                       if (ptematch(ptp, sr, va, PTE_VALID | PTE_HID)) {
+                               pmap_remove_pv(idx, va, pmap_page_index(ptp->pte_lo), ptp);
+                               ptp->pte_hi &= ~PTE_VALID;
+                               asm volatile ("sync");
+                               tlbie(va);
+                               tlbsync();
+                       }
+               for (po = potable[idx].lh_first; po; po = npo) {
+                       npo = po->po_list.le_next;
+                       if (ptematch(&po->po_pte, sr, va, 0)) {
+                               pmap_remove_pv(idx, va, pmap_page_index(po->po_pte.pte_lo),
+                                              &po->po_pte);
+                               LIST_REMOVE(po, po_list);
+                               pofree(po, 1);
+                       }
+               }
+               va += NBPG;
+       }
+       splx(s);
+}
+
+static pte_t *
+pte_find(pm, va)
+       struct pmap *pm;
+       vm_offset_t va;
+{
+       int idx, i;
+       sr_t sr;
+       pte_t *ptp;
+       struct pte_ovfl *po;
+
+       idx = pteidx(sr = ptesr(pm->pm_sr, va), va);
+       for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++)
+               if (ptematch(ptp, sr, va, PTE_VALID))
+                       return ptp;
+       for (ptp = ptable + (idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++)
+               if (ptematch(ptp, sr, va, PTE_VALID | PTE_HID))
+                       return ptp;
+       for (po = potable[idx].lh_first; po; po = po->po_list.le_next)
+               if (ptematch(&po->po_pte, sr, va, 0))
+                       return &po->po_pte;
+       return 0;
+}
+
+/*
+ * Get the physical page address for the given pmap/virtual address.
+ */
+vm_offset_t
+pmap_extract(pm, va)
+       struct pmap *pm;
+       vm_offset_t va;
+{
+       pte_t *ptp;
+       vm_offset_t o;
+       int s = splimp();
+       
+       if (!(ptp = pte_find(pm, va))) {
+               splx(s);
+               return 0;
+       }
+       o = (ptp->pte_lo & PTE_RPGN) | (va & ADDR_POFF);
+       splx(s);
+       return o;
+}
+
+/*
+ * Lower the protection on the specified range of this pmap.
+ *
+ * There are only two cases: either the protection is going to 0,
+ * or it is going to read-only.
+ */
+void
+pmap_protect(pm, sva, eva, prot)
+       struct pmap *pm;
+       vm_offset_t sva, eva;
+       vm_prot_t prot;
+{
+       pte_t *ptp;
+       int valid, s;
+       
+       if (prot & VM_PROT_READ) {
+               s = splimp();
+               while (sva < eva) {
+                       if (ptp = pte_find(pm, sva)) {
+                               valid = ptp->pte_hi & PTE_VALID;
+                               ptp->pte_hi &= ~PTE_VALID;
+                               asm volatile ("sync");
+                               tlbie(sva);
+                               tlbsync();
+                               ptp->pte_lo &= ~PTE_PP;
+                               ptp->pte_lo |= PTE_RO;
+                               asm volatile ("sync");
+                               ptp->pte_hi |= valid;
+                       }
+                       sva += NBPG;
+               }
+               splx(s);
+               return;
+       }
+       pmap_remove(pm, sva, eva);
+}
+
+void
+ptemodify(pa, mask, val)
+       vm_offset_t pa;
+       u_int mask;
+       u_int val;
+{
+       struct pv_entry *pv;
+       pte_t *ptp;
+       struct pte_ovfl *po;
+       int i, s;
+       
+       i = pmap_page_index(pa);
+       if (i < 0)
+               return;
+
+       /*
+        * First modify bits in cache.
+        */
+       pmap_attrib[i] &= ~mask >> ATTRSHFT;
+       pmap_attrib[i] |= val >> ATTRSHFT;
+       
+       pv = pv_table + i;
+       if (pv->pv_idx < 0)
+               return;
+
+       s = splimp();
+       for (; pv; pv = pv->pv_next) {
+               for (ptp = ptable + pv->pv_idx * 8, i = 8; --i >= 0; ptp++)
+                       if ((ptp->pte_hi & PTE_VALID)
+                           && (ptp->pte_lo & PTE_RPGN) == pa) {
+                               ptp->pte_hi &= ~PTE_VALID;
+                               asm volatile ("sync");
+                               tlbie(pv->pv_va);
+                               tlbsync();
+                               ptp->pte_lo &= ~mask;
+                               ptp->pte_lo |= val;
+                               asm volatile ("sync");
+                               ptp->pte_hi |= PTE_VALID;
+                       }
+               for (ptp = ptable + (pv->pv_idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++)
+                       if ((ptp->pte_hi & PTE_VALID)
+                           && (ptp->pte_lo & PTE_RPGN) == pa) {
+                               ptp->pte_hi &= ~PTE_VALID;
+                               asm volatile ("sync");
+                               tlbie(pv->pv_va);
+                               tlbsync();
+                               ptp->pte_lo &= ~mask;
+                               ptp->pte_lo |= val;
+                               asm volatile ("sync");
+                               ptp->pte_hi |= PTE_VALID;
+                       }
+               for (po = potable[pv->pv_idx].lh_first; po; po = po->po_list.le_next)
+                       if ((po->po_pte.pte_lo & PTE_RPGN) == pa) {
+                               po->po_pte.pte_lo &= ~mask;
+                               po->po_pte.pte_lo |= val;
+                       }
+       }
+       splx(s);
+}
+
+int
+ptebits(pa, bit)
+       vm_offset_t pa;
+       int bit;
+{
+       struct pv_entry *pv;
+       pte_t *ptp;
+       struct pte_ovfl *po;
+       int i, s, bits = 0;
+
+       i = pmap_page_index(pa);
+       if (i < 0)
+               return 0;
+
+       /*
+        * First try the cache.
+        */
+       bits |= (pmap_attrib[i] << ATTRSHFT) & bit;
+       if (bits == bit)
+               return bits;
+
+       pv = pv_table + i;
+       if (pv->pv_idx < 0)
+               return 0;
+       
+       s = splimp();
+       for (; pv; pv = pv->pv_next) {
+               for (ptp = ptable + pv->pv_idx * 8, i = 8; --i >= 0; ptp++)
+                       if ((ptp->pte_hi & PTE_VALID)
+                           && (ptp->pte_lo & PTE_RPGN) == pa) {
+                               bits |= ptp->pte_lo & bit;
+                               if (bits == bit) {
+                                       splx(s);
+                                       return bits;
+                               }
+                       }
+               for (ptp = ptable + (pv->pv_idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++)
+                       if ((ptp->pte_hi & PTE_VALID)
+                           && (ptp->pte_lo & PTE_RPGN) == pa) {
+                               bits |= ptp->pte_lo & bit;
+                               if (bits == bit) {
+                                       splx(s);
+                                       return bits;
+                               }
+                       }
+               for (po = potable[pv->pv_idx].lh_first; po; po = po->po_list.le_next)
+                       if ((po->po_pte.pte_lo & PTE_RPGN) == pa) {
+                               bits |= po->po_pte.pte_lo & bit;
+                               if (bits == bit) {
+                                       splx(s);
+                                       return bits;
+                               }
+                       }
+       }
+       splx(s);
+       return bits;
+}
+
+/*
+ * Lower the protection on the specified physical page.
+ *
+ * There are only two cases: either the protection is going to 0,
+ * or it is going to read-only.
+ */
+void
+pmap_page_protect(pa, prot)
+       vm_offset_t pa;
+       vm_prot_t prot;
+{
+       vm_offset_t va;
+       pte_t *ptp;
+       struct pte_ovfl *po, *npo;
+       int i, s, pind, idx;
+       
+       pa &= ~ADDR_POFF;
+       if (prot & VM_PROT_READ) {
+               ptemodify(pa, PTE_PP, PTE_RO);
+               return;
+       }
+
+       pind = pmap_page_index(pa);
+       if (pind < 0)
+               return;
+
+       s = splimp();
+       while (pv_table[pind].pv_idx >= 0) {
+               idx = pv_table[pind].pv_idx;
+               va = pv_table[pind].pv_va;
+               for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++)
+                       if ((ptp->pte_hi & PTE_VALID)
+                           && (ptp->pte_lo & PTE_RPGN) == pa) {
+                               pmap_remove_pv(idx, va, pind, ptp);
+                               ptp->pte_hi &= ~PTE_VALID;
+                               asm volatile ("sync");
+                               tlbie(va);
+                               tlbsync();
+                       }
+               for (ptp = ptable + (idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++)
+                       if ((ptp->pte_hi & PTE_VALID)
+                           && (ptp->pte_lo & PTE_RPGN) == pa) {
+                               pmap_remove_pv(idx, va, pind, ptp);
+                               ptp->pte_hi &= ~PTE_VALID;
+                               asm volatile ("sync");
+                               tlbie(va);
+                               tlbsync();
+                       }
+               for (po = potable[idx].lh_first; po; po = npo) {
+                       npo = po->po_list.le_next;
+                       if ((po->po_pte.pte_lo & PTE_RPGN) == pa) {
+                               pmap_remove_pv(idx, va, pind, &po->po_pte);
+                               LIST_REMOVE(po, po_list);
+                               pofree(po, 1);
+                       }
+               }
+       }
+       splx(s);
+}
diff --git a/sys/arch/powerpc/powerpc/process_machdep.c b/sys/arch/powerpc/powerpc/process_machdep.c
new file mode 100644 (file)
index 0000000..ab956e4
--- /dev/null
@@ -0,0 +1,62 @@
+/*     $NetBSD: process_machdep.c,v 1.1 1996/09/30 16:34:53 ws Exp $   */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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/proc.h>
+
+/*
+ * Set the process's program counter.
+ */
+int
+process_set_pc(p, addr)
+       struct proc *p;
+       caddr_t addr;
+{
+       struct trapframe *tf = trapframe(p);
+       
+       tf->srr0 = (int)addr;
+       return 0;
+}
+
+int
+process_sstep(p, sstep)
+       struct proc *p;
+       int sstep;
+{
+       struct trapframe *tf = trapframe(p);
+       
+       if (sstep)
+               tf->srr1 |= PSL_SE;
+       else
+               tf->srr1 &= ~PSL_SE;
+       return 0;
+}
diff --git a/sys/arch/powerpc/powerpc/random.c b/sys/arch/powerpc/powerpc/random.c
new file mode 100644 (file)
index 0000000..814136c
--- /dev/null
@@ -0,0 +1,89 @@
+/*     $OpenBSD: random.c,v 1.1.1.1 1996/12/21 20:35:58 rahnds Exp $   */
+/*     $NetBSD: random.s,v 1.5 1995/01/15 22:32:35 mycroft Exp $       */
+
+/*
+ * 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: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Here is a very good random number generator.  This implementation is
+ * based on ``Two Fast Implementations of the "Minimal Standard" Random
+ * Number Generator'', David G. Carta, Communications of the ACM, Jan 1990,
+ * Vol 33 No 1.  Do NOT modify this code unless you have a very thorough
+ * understanding of the algorithm.  It's trickier than you think.  If
+ * you do change it, make sure that its 10,000'th invocation returns
+ * 1043618065.
+ *
+ * Here is easier-to-decipher pseudocode:
+ *
+ * p = (16807*seed)<30:0>      # e.g., the low 31 bits of the product
+ * q = (16807*seed)<62:31>     # e.g., the high 31 bits starting at bit 32
+ * if (p + q < 2^31)
+ *     seed = p + q
+ * else
+ *     seed = ((p + q) & (2^31 - 1)) + 1
+ * return (seed);
+ *
+ * The result is in (0,2^31), e.g., it's always positive.
+ */
+#if 0
+#include <machine/asm.h>
+
+       .data
+       .globl  _C_SYMBOL(_randseed)
+_C_SYMBOL(_randseed):
+       .long   1
+       .text
+ENTRY(random)
+#      movl    #16807, d0
+       lis     r5, 1
+       ori     r5, r5, 0x6807
+       lis     r4, _C_SYMBOL(_randseed)@h
+       lwz     r6, _C_SYMBOL(_randseed)@l(r4)
+#      mulsl   __randseed, d1:d0
+       mulhw   r7, r6, r5
+       mulhw   r8, r6, r5
+
+#      lsll    #1, d0
+#      roxll   #2, d1
+#      addl    d1, d0
+#      moveql  #1, d1
+#      addxl   d1, d0
+#      lsrl    #1, d0
+       lis     r4, _C_SYMBOL(_randseed)@h
+       stw     r6, _C_SYMBOL(_randseed)@l(r4)
+#      movl    d0, __randseed
+#      rts
+#endif
+
+extern int _randseed;
+int
+random()
+{
+       long long value;
+       int p, q;
+       value = 16807 * _randseed;
+       p = value & (long long) (0xffffffff);
+       q = (value >> 32) & (long long) (0xffffffff);
+       if (((long long) p + q) < 0x3fffffff) {
+               _randseed = p + q;
+       } else {
+               _randseed = (int)(((long long)p + q ) & 0x3ffffffe) +1;
+       }
+       return _randseed;
+}
diff --git a/sys/arch/powerpc/powerpc/setjmp.S b/sys/arch/powerpc/powerpc/setjmp.S
new file mode 100644 (file)
index 0000000..022e458
--- /dev/null
@@ -0,0 +1,100 @@
+/* kernel version of this file, does not have signal goop */
+/* int setjmp(jmp_buf env) */
+
+#define JMP_r1 0x04
+#define JMP_r14        0x08
+#define JMP_r15        0x0c
+#define JMP_r16        0x10
+#define JMP_r17        0x14
+#define JMP_r18        0x18
+#define JMP_r19        0x1c
+#define JMP_r20        0x20
+#define JMP_r21        0x24
+#define JMP_r22        0x28
+#define JMP_r23        0x2c
+#define JMP_r24        0x30
+#define JMP_r25        0x34
+#define JMP_r26        0x38
+#define JMP_r27        0x3c
+#define JMP_r28        0x40
+#define JMP_r29        0x44
+#define JMP_r30        0x48
+#define JMP_r31        0x4c
+#define JMP_lr  0x50
+#define JMP_cr  0x54
+#define JMP_ctr        0x58
+#define JMP_xer        0x5c
+#define JMP_sig        0x60
+
+
+.globl setjmp
+setjmp:
+       stw 31, JMP_r31(3)
+       /* r1, r14-r30 */
+       stw 1,  JMP_r1 (3)
+       stw 14, JMP_r14(3)
+       stw 15, JMP_r15(3)
+       stw 16, JMP_r16(3)
+       stw 17, JMP_r17(3)
+       stw 18, JMP_r18(3)
+       stw 19, JMP_r19(3)
+       stw 20, JMP_r20(3)
+       stw 21, JMP_r21(3)
+       stw 22, JMP_r22(3)
+       stw 23, JMP_r23(3)
+       stw 24, JMP_r24(3)
+       stw 25, JMP_r25(3)
+       stw 26, JMP_r26(3)
+       stw 27, JMP_r27(3)
+       stw 28, JMP_r28(3)
+       stw 29, JMP_r29(3)
+       stw 30, JMP_r30(3)
+       /* cr, lr, ctr, xer */
+       mfcr 0
+       stw 0, JMP_cr(3)
+       mflr 0
+       stw 0, JMP_lr(3)
+       mfctr 0
+       stw 0, JMP_ctr(3)
+       mfxer 0
+       stw 0, JMP_xer(3)
+       /* f14-f31, fpscr */
+       li 3, 0
+       blr
+
+
+.extern sigsetmask
+.globl longjmp
+longjmp:
+       lwz 31, JMP_r31(3)
+       /* r1, r14-r30 */
+       lwz 1,  JMP_r1 (3)
+       lwz 14, JMP_r14(3)
+       lwz 15, JMP_r15(3)
+       lwz 16, JMP_r16(3)
+       lwz 17, JMP_r17(3)
+       lwz 18, JMP_r18(3)
+       lwz 19, JMP_r19(3)
+       lwz 20, JMP_r20(3)
+       lwz 21, JMP_r21(3)
+       lwz 22, JMP_r22(3)
+       lwz 23, JMP_r23(3)
+       lwz 24, JMP_r24(3)
+       lwz 25, JMP_r25(3)
+       lwz 26, JMP_r26(3)
+       lwz 27, JMP_r27(3)
+       lwz 28, JMP_r28(3)
+       lwz 29, JMP_r29(3)
+       lwz 30, JMP_r30(3)
+       /* cr, lr, ctr, xer */
+       lwz 0, JMP_cr(3)
+       mtcr 0
+       lwz 0, JMP_lr(3)
+       mtlr 0
+       lwz 0, JMP_ctr(3)
+       mtctr 0
+       lwz 0, JMP_xer(3)
+       mtxer 0
+       /* f14-f31, fpscr */
+       mr 3, 4
+       blr
diff --git a/sys/arch/powerpc/powerpc/subyte.c b/sys/arch/powerpc/powerpc/subyte.c
new file mode 100644 (file)
index 0000000..df71a0c
--- /dev/null
@@ -0,0 +1,45 @@
+/*     $NetBSD: subyte.c,v 1.1 1996/09/30 16:34:54 ws Exp $    */
+
+/*-
+ * Copyright (C) 1993 Wolfgang Solfrank.
+ * Copyright (C) 1993 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+
+/*
+ * Emulate subyte.
+ */
+int
+subyte(addr,c)
+char *addr;
+unsigned char c;
+{
+       if (copyout(&c,addr,sizeof(c)))
+               return -1;
+       return 0;
+}
diff --git a/sys/arch/powerpc/powerpc/suswintr.c b/sys/arch/powerpc/powerpc/suswintr.c
new file mode 100644 (file)
index 0000000..8706660
--- /dev/null
@@ -0,0 +1,45 @@
+/*     $NetBSD: suswintr.c,v 1.1 1996/09/30 16:34:54 ws Exp $  */
+
+/*-
+ * Copyright (C) 1994 Wolfgang Solfrank.
+ * Copyright (C) 1994 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+
+/*
+ * Emulate suswintr
+ *
+ * Simply return fault for all cases
+ */
+int
+suswintr(addr,s)
+       char *addr;
+       unsigned short s;
+{
+       return -1;
+}
diff --git a/sys/arch/powerpc/powerpc/suword.c b/sys/arch/powerpc/powerpc/suword.c
new file mode 100644 (file)
index 0000000..a4ba796
--- /dev/null
@@ -0,0 +1,45 @@
+/*     $NetBSD: suword.c,v 1.1 1996/09/30 16:34:55 ws Exp $    */
+
+/*-
+ * Copyright (C) 1993 Wolfgang Solfrank.
+ * Copyright (C) 1993 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+
+/*
+ * Emulate suword
+ */
+int
+suword(addr,l)
+char *addr;
+unsigned long l;
+{
+       if (copyout(&l,addr,sizeof(l)))
+               return -1;
+       return 0;
+}
diff --git a/sys/arch/powerpc/powerpc/swapgeneric.c b/sys/arch/powerpc/powerpc/swapgeneric.c
new file mode 100644 (file)
index 0000000..a22c2d9
--- /dev/null
@@ -0,0 +1,53 @@
+/*     $NetBSD: swapgeneric.c,v 1.1 1996/09/30 16:34:55 ws Exp $       */
+
+/*-
+ * Copyright (c) 1994
+ *      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.
+ *
+ *      @(#)swapgeneric.c       8.2 (Berkeley) 3/21/94
+ */
+
+/*
+ * fake swapgeneric.c -- should do this differently.
+ */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+
+int (*mountroot) __P((void *)) = NULL; /* tells autoconf.c that we are "generic" */
+
+dev_t  rootdev = NODEV;
+dev_t  dumpdev = NODEV;
+
+struct swdevt swdevt[] = {
+       { NODEV, 0, 0 },                /* Setup by autoconf.c/disksubr.c */
+       { NODEV, 0, 0 }
+};
diff --git a/sys/arch/powerpc/powerpc/sys_machdep.c b/sys/arch/powerpc/powerpc/sys_machdep.c
new file mode 100644 (file)
index 0000000..653ce49
--- /dev/null
@@ -0,0 +1,46 @@
+/*     $NetBSD: sys_machdep.c,v 1.1 1996/09/30 16:34:56 ws Exp $       */
+
+/*
+ * Copyright (C) 1996 Wolfgang Solfrank.
+ * Copyright (C) 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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>
+
+int
+sys_sysarch(p, v, retval)
+       struct proc *p;
+       void *v;
+       register_t *retval;
+{
+       /*
+        * Currently no special system calls
+        */
+       return EINVAL;
+}
diff --git a/sys/arch/powerpc/powerpc/trap.c b/sys/arch/powerpc/powerpc/trap.c
new file mode 100644 (file)
index 0000000..d099272
--- /dev/null
@@ -0,0 +1,403 @@
+/*     $NetBSD: trap.c,v 1.3 1996/10/13 03:31:37 christos Exp $        */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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/proc.h>
+#include <sys/reboot.h>
+#include <sys/syscall.h>
+#include <sys/systm.h>
+#include <sys/user.h>
+#include <sys/ktrace.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+#include <machine/pmap.h>
+#include <machine/psl.h>
+#include <machine/trap.h>
+
+/* These definitions should probably be somewhere else                         XXX */
+#define        FIRSTARG        3               /* first argument is in reg 3 */
+#define        NARGREG         8               /* 8 args are in registers */
+#define        MOREARGS(sp)    ((caddr_t)((int)(sp) + 8)) /* more args go here */
+
+volatile int astpending;
+volatile int want_resched;
+
+void
+trap(frame)
+       struct trapframe *frame;
+{
+       struct proc *p = curproc;
+       int type = frame->exc;
+       u_quad_t sticks;
+
+       if (frame->srr1 & PSL_PR) {
+               type |= EXC_USER;
+               sticks = p->p_sticks;
+       }
+
+       switch (type) {
+       case EXC_TRC|EXC_USER:          /* Temporarily!                                 XXX */
+               printf("TRC: %x\n", frame->srr0);
+               break;
+       case EXC_DSI:
+               {
+                       vm_map_t map;
+                       vm_offset_t va;
+                       int ftype;
+                       faultbuf *fb;
+                       
+                       map = kernel_map;
+                       va = frame->dar;
+                       if ((va >> ADDR_SR_SHFT) == USER_SR) {
+                               sr_t user_sr;
+                               
+                               asm ("mfsr %0, %1"
+                                    : "=r"(user_sr) : "K"(USER_SR));
+                               va &= ADDR_PIDX | ADDR_POFF;
+                               va |= user_sr << ADDR_SR_SHFT;
+                               map = &p->p_vmspace->vm_map;
+                       }
+                       if (frame->dsisr & DSISR_STORE)
+                               ftype = VM_PROT_READ | VM_PROT_WRITE;
+                       else
+                               ftype = VM_PROT_READ;
+                       if (vm_fault(map, trunc_page(va), ftype, FALSE)
+                           == KERN_SUCCESS)
+                               break;
+                       if (fb = p->p_addr->u_pcb.pcb_onfault) {
+                               frame->srr0 = (*fb)[0];
+                               frame->fixreg[1] = (*fb)[1];
+                               frame->cr = (*fb)[2];
+                               bcopy(&(*fb)[3], &frame->fixreg[13], 19);
+                               return;
+                       }
+                       map = kernel_map;
+               }
+               goto brain_damage;
+       case EXC_DSI|EXC_USER:
+               {
+                       int ftype;
+                       
+                       if (frame->dsisr & DSISR_STORE)
+                               ftype = VM_PROT_READ | VM_PROT_WRITE;
+                       else
+                               ftype = VM_PROT_READ;
+                       if (vm_fault(&p->p_vmspace->vm_map,
+                                    trunc_page(frame->dar), ftype, FALSE)
+                           == KERN_SUCCESS)
+                               break;
+               }
+printf("dsi on addr %x iar %x\n", frame->dsisr, frame->srr0);
+               trapsignal(p, SIGSEGV, EXC_DSI);
+               break;
+       case EXC_ISI|EXC_USER:
+               {
+                       int ftype;
+                       
+                       ftype = VM_PROT_READ | VM_PROT_EXECUTE;
+                       if (vm_fault(&p->p_vmspace->vm_map,
+                                    trunc_page(frame->srr0), ftype, FALSE)
+                           == KERN_SUCCESS)
+                               break;
+               }
+printf("isi iar %x\n", frame->srr0);
+               trapsignal(p, SIGSEGV, EXC_ISI);
+               break;
+       case EXC_SC|EXC_USER:
+               {
+                       struct sysent *callp;
+                       size_t argsize;
+                       register_t code, error;
+                       register_t *params, rval[2];
+                       int nsys, n;
+                       register_t args[10];
+                       
+                       cnt.v_syscall++;
+                       
+                       nsys = p->p_emul->e_nsysent;
+                       callp = p->p_emul->e_sysent;
+                       
+                       code = frame->fixreg[0];
+                       params = frame->fixreg + FIRSTARG;
+                       
+                       switch (code) {
+                       case SYS_syscall:
+                               /*
+                                * code is first argument,
+                                * followed by actual args.
+                                */
+                               code = *params++;
+                               break;
+                       case SYS___syscall:
+                               /*
+                                * Like syscall, but code is a quad,
+                                * so as to maintain quad alignment
+                                * for the rest of the args.
+                                */
+                               if (callp != sysent)
+                                       break;
+                               params++;
+                               code = *params++;
+                               break;
+                       default:
+                               break;
+                       }
+                       if (code < 0 || code >= nsys)
+                               callp += p->p_emul->e_nosys;
+                       else
+                               callp += code;
+                       argsize = callp->sy_argsize;
+                       n = NARGREG - (params - (frame->fixreg + FIRSTARG));
+                       if (argsize > n * sizeof(register_t)) {
+                               bcopy(params, args, n * sizeof(register_t));
+                               if (error = copyin(MOREARGS(frame->fixreg[1]),
+                                                  args + n,
+                                                  argsize - n * sizeof(register_t))) {
+#ifdef KTRACE
+                                       /* Can't get all the arguments! */
+                                       if (KTRPOINT(p, KTR_SYSCALL))
+                                               ktrsyscall(p->p_tracep, code,
+                                                          argsize, args);
+#endif
+                                       goto syscall_bad;
+                               }
+                               params = args;
+                       }
+#ifdef KTRACE
+                       if (KTRPOINT(p, KTR_SYSCALL))
+                               ktrsyscall(p->p_tracep, code, argsize, params);
+#endif
+                       rval[0] = 0;
+                       rval[1] = frame->fixreg[FIRSTARG + 1];
+
+#ifdef SYSCALL_DEBUG
+       scdebug_call(p, code, params);
+#endif
+
+                       
+                       switch (error = (*callp->sy_call)(p, params, rval)) {
+                       case 0:
+                               frame->fixreg[0] = error;
+                               frame->fixreg[FIRSTARG] = rval[0];
+                               frame->fixreg[FIRSTARG + 1] = rval[1];
+                               frame->cr &= ~0x10000000;
+                               break;
+                       case ERESTART:
+                               /*
+                                * Set user's pc back to redo the system call.
+                                */
+                               frame->srr0 -= 4;
+                               break;
+                       case EJUSTRETURN:
+                               /* nothing to do */
+                               break;
+                       default:
+syscall_bad:
+                               if (p->p_emul->e_errno)
+                                       error = p->p_emul->e_errno[error];
+                               frame->fixreg[0] = error;
+                               frame->fixreg[FIRSTARG] = error;
+                               frame->cr |= 0x10000000;
+                               break;
+                       }
+#ifdef SYSCALL_DEBUG
+        scdebug_ret(p, code, error, rval); 
+#endif  
+#ifdef KTRACE
+                       if (KTRPOINT(p, KTR_SYSRET))
+                               ktrsysret(p->p_tracep, code, error, rval[0]);
+#endif
+               }
+               break;
+
+       case EXC_FPU|EXC_USER:
+               if (fpuproc)
+                       save_fpu(fpuproc);
+               fpuproc = p;
+               enable_fpu(p);
+               break;
+
+       default:
+       
+brain_damage:
+               printf("trap type %x at %x\n", type, frame->srr0);
+               panic("trap");
+
+       case EXC_PGM|EXC_USER:
+printf("pgm iar %x\n", frame->srr0);
+               trapsignal(p, SIGILL,EXC_PGM);
+               break;
+       case EXC_AST|EXC_USER:
+               /* This is just here that we trap */
+               break;
+       }
+
+       astpending = 0;         /* we are about to do it */
+
+       cnt.v_soft++;
+
+       if (p->p_flag & P_OWEUPC) {
+               p->p_flag &= ~P_OWEUPC;
+               ADDUPROF(p);
+       }
+
+       /* take pending signals */
+       {
+               int sig;
+
+               while (sig = CURSIG(p))
+                       postsig(sig);
+       }
+
+       p->p_priority = p->p_usrpri;
+       if (want_resched) {
+               int s, sig;
+
+               /*
+                * Since we are curproc, a clock interrupt could
+                * change our priority without changing run queues
+                * (the running process is not kept on a run queue).
+                * If this happened after we setrunqueue ourselves but
+                * before 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))
+                       postsig(sig);
+       }
+
+       /*
+        * If profiling, charge recent system time to the trapped pc.
+        */
+       if (p->p_flag & P_PROFIL) {
+               extern int psratio;
+
+               addupc_task(p, frame->srr0,
+                           (int)(p->p_sticks - sticks) * psratio);
+       }
+       /*
+        * If someone stole the fpu while we were away, disable it
+        */
+       if (p != fpuproc)
+               frame->srr1 &= ~PSL_FP;
+       curpriority = p->p_priority;
+}
+
+void
+child_return(p)
+       struct proc *p;
+{
+       struct trapframe *tf = trapframe(p);
+
+       tf->fixreg[0] = 0;
+       tf->fixreg[FIRSTARG] = 0;
+       tf->fixreg[FIRSTARG + 1] = 1;
+       tf->cr &= ~0x10000000;
+       tf->srr1 &= ~PSL_FP;    /* Disable FPU, as we can't be fpuproc */
+#ifdef KTRACE
+       if (KTRPOINT(p, KTR_SYSRET))
+               ktrsysret(p->p_tracep, SYS_fork, 0, 0);
+#endif
+       /* Profiling?                                                   XXX */
+       curpriority = p->p_priority;
+}
+
+static inline void
+setusr(content)
+       int content;
+{
+       asm volatile ("isync; mtsr %0,%1; isync"
+                     :: "n"(USER_SR), "r"(content));
+}
+
+int
+copyin(udaddr, kaddr, len)
+       void *udaddr;
+       void *kaddr;
+       size_t len;
+{
+       void *p;
+       size_t l;
+       faultbuf env;
+
+       if (setfault(env))
+               return EACCES;
+       while (len > 0) {
+               p = USER_ADDR + ((u_int)udaddr & ~SEGMENT_MASK);
+               l = (USER_ADDR + SEGMENT_LENGTH) - p;
+               if (l > len)
+                       l = len;
+               setusr(curpcb->pcb_pm->pm_sr[(u_int)udaddr >> ADDR_SR_SHFT]);
+               bcopy(p, kaddr, l);
+               udaddr += l;
+               kaddr += l;
+               len -= l;
+       }
+       curpcb->pcb_onfault = 0;
+       return 0;
+}
+
+int
+copyout(kaddr, udaddr, len)
+       void *kaddr;
+       void *udaddr;
+       size_t len;
+{
+       void *p;
+       size_t l;
+       faultbuf env;
+
+       if (setfault(env))
+               return EACCES;
+       while (len > 0) {
+               p = USER_ADDR + ((u_int)udaddr & ~SEGMENT_MASK);
+               l = (USER_ADDR + SEGMENT_LENGTH) - p;
+               if (l > len)
+                       l = len;
+               setusr(curpcb->pcb_pm->pm_sr[(u_int)udaddr >> ADDR_SR_SHFT]);
+               bcopy(kaddr, p, l);
+               udaddr += l;
+               kaddr += l;
+               len -= l;
+       }
+       curpcb->pcb_onfault = 0;
+       return 0;
+}
diff --git a/sys/arch/powerpc/powerpc/trap.c.swp b/sys/arch/powerpc/powerpc/trap.c.swp
new file mode 100644 (file)
index 0000000..caf7756
Binary files /dev/null and b/sys/arch/powerpc/powerpc/trap.c.swp differ
diff --git a/sys/arch/powerpc/powerpc/vm_machdep.c b/sys/arch/powerpc/powerpc/vm_machdep.c
new file mode 100644 (file)
index 0000000..7a27d8d
--- /dev/null
@@ -0,0 +1,257 @@
+/*     $NetBSD: vm_machdep.c,v 1.1 1996/09/30 16:34:57 ws Exp $        */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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/core.h>
+#include <sys/exec.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/vnode.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+
+#include <machine/pcb.h>
+
+/*
+ * Finish a fork operation, with process p2 nearly set up.
+ */
+void
+cpu_fork(p1, p2)
+       struct proc *p1, *p2;
+{
+       struct trapframe *tf;
+       struct callframe *cf;
+       struct switchframe *sf;
+       caddr_t stktop1, stktop2;
+       extern void fork_trampoline __P((void));
+       extern void child_return __P((struct proc *));
+       struct pcb *pcb = &p2->p_addr->u_pcb;
+
+       if (p1 == fpuproc)
+               save_fpu(p1);
+       *pcb = p1->p_addr->u_pcb;
+       
+       pcb->pcb_pm = &p2->p_vmspace->vm_pmap;
+       pcb->pcb_pmreal = (struct pmap *)pmap_extract(pmap_kernel(), (vm_offset_t)pcb->pcb_pm);
+       
+       /*
+        * Setup the trap frame for the new process
+        */
+       stktop1 = (caddr_t)trapframe(p1);
+       stktop2 = (caddr_t)trapframe(p2);
+       bcopy(stktop1, stktop2, sizeof(struct trapframe));
+       stktop2 = (caddr_t)((u_long)stktop2 & ~15);     /* Align stack pointer */
+       
+       /*
+        * There happens to be a callframe, too.
+        */
+       cf = (struct callframe *)stktop2;
+       cf->lr = (int)fork_trampoline;
+       
+       /*
+        * Below the trap frame, there is another call frame:
+        */
+       stktop2 -= 16;
+       cf = (struct callframe *)stktop2;
+       cf->r31 = (register_t)child_return;
+       cf->r30 = (register_t)p2;
+       
+       /*
+        * Below that, we allocate the switch frame:
+        */
+       stktop2 -= roundup(sizeof *sf, 16);     /* must match SFRAMELEN in genassym */
+       sf = (struct switchframe *)stktop2;
+       bzero((void *)sf, sizeof *sf);          /* just in case */
+       sf->sp = (int)cf;
+       sf->user_sr = pmap_kernel()->pm_sr[USER_SR]; /* again, just in case */
+       pcb->pcb_sp = (int)stktop2;
+       pcb->pcb_spl = 0;
+}
+
+/*
+ * Set initial pc of process forked by above.
+ */
+void
+cpu_set_kpc(p, pc)
+       struct proc *p;
+       u_long pc;
+{
+       struct switchframe *sf = (struct switchframe *)p->p_addr->u_pcb.pcb_sp;
+       struct callframe *cf = (struct callframe *)sf->sp;
+       
+       cf->r30 = (int)p;
+       cf->r31 = pc;
+       cf++->lr = pc;
+}
+
+void
+cpu_swapin(p)
+       struct proc *p;
+{
+       struct pcb *pcb = &p->p_addr->u_pcb;
+       
+       pcb->pcb_pmreal = (struct pmap *)pmap_extract(pmap_kernel(), (vm_offset_t)pcb->pcb_pm);
+}
+
+/*
+ * Move pages from one kernel virtual address to another.
+ */
+void
+pagemove(from, to, size)
+       caddr_t from, to;
+       size_t size;
+{
+       vm_offset_t pa, va;
+       
+       for (va = (vm_offset_t)from; size > 0; size -= NBPG) {
+               pa = pmap_extract(pmap_kernel(), va);
+               pmap_remove(pmap_kernel(), va, va + NBPG);
+               pmap_enter(pmap_kernel(), (vm_offset_t)to, pa,
+                          VM_PROT_READ | VM_PROT_WRITE, 1);
+               va += NBPG;
+               to += NBPG;
+       }
+}
+
+/*
+ * cpu_exit is called as the last action during exit.
+ * We release the address space and machine-dependent resources,
+ * including the memory for the user structure and kernel stack.
+ *
+ * Since we don't have curproc anymore, we cannot sleep, and therefor
+ * this is at least incorrect for the multiprocessor version.
+ * Not sure whether we can get away with this in the single proc version.              XXX
+ */
+void
+cpu_exit(p)
+       struct proc *p;
+{
+       if (p == fpuproc)       /* release the fpu */
+               fpuproc = 0;
+       
+       vmspace_free(p->p_vmspace);
+       switchexit(kernel_map, p->p_addr, USPACE);
+}
+
+/*
+ * Write the machine-dependent part of a core dump.
+ */
+int
+cpu_coredump(p, vp, cred, chdr)
+       struct proc *p;
+       struct vnode *vp;
+       struct ucred *cred;
+       struct core *chdr;
+{
+       struct coreseg cseg;
+       struct md_coredump md_core;
+       struct trapframe *tf;
+       int error;
+       
+#if 0
+       CORE_SETMAGIC(*chdr, COREMAGIC, MID_POWERPC, 0);
+       chdr->c_hdrsize = ALIGN(sizeof *chdr);
+       chdr->c_seghdrsize = ALIGN(sizeof cseg);
+       chdr->c_cpusize = sizeof md_core;
+
+       tf = trapframe(p);
+       bcopy(tf, &md_core.frame, sizeof md_core.frame);
+       
+       CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_POWERPC, CORE_CPU);
+       cseg.c_addr = 0;
+       cseg.c_size = chdr->c_cpusize;
+
+       if (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))
+               return error;
+       if (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))
+               return error;
+
+       chdr->c_nseg++;
+#endif
+       return 0;
+}
+
+/*
+ * Map an IO request into kernel virtual address space.
+ */
+void
+vmapbuf(bp, len)
+       struct buf *bp;
+       vm_size_t len;
+{
+       vm_offset_t faddr, taddr, off;
+       vm_offset_t pa;
+       
+#ifdef DIAGNOSTIC
+       if (!(bp->b_flags & B_PHYS))
+               panic("vmapbuf");
+#endif
+       faddr = trunc_page(bp->b_saveaddr = bp->b_data);
+       off = (vm_offset_t)bp->b_data - faddr;
+       len = round_page(off + len);
+       taddr = kmem_alloc_wait(phys_map, len);
+       bp->b_data = (caddr_t)(taddr + off);
+       for (; len > 0; len -= NBPG) {
+               pa = pmap_extract(vm_map_pmap(&bp->b_proc->p_vmspace->vm_map), faddr);
+               pmap_enter(vm_map_pmap(phys_map), taddr, pa,
+                          VM_PROT_READ | VM_PROT_WRITE, 1);
+               faddr += NBPG;
+               taddr += NBPG;
+       }
+}
+
+/*
+ * Free the io map addresses associated with this IO operation.
+ */
+void
+vunmapbuf(bp, len)
+       struct buf *bp;
+       vm_size_t len;
+{
+       vm_offset_t addr, off;
+       
+#ifdef DIAGNOSTIC
+       if (!(bp->b_flags & B_PHYS))
+               panic("vunmapbuf");
+#endif
+       addr = trunc_page(bp->b_data);
+       off = (vm_offset_t)bp->b_data - addr;
+       len = round_page(off + len);
+       kmem_free_wakeup(phys_map, addr, len);
+       bp->b_data = bp->b_saveaddr;
+       bp->b_saveaddr = 0;
+}
diff --git a/sys/arch/powerpc/stand/Locore.c b/sys/arch/powerpc/stand/Locore.c
new file mode 100644 (file)
index 0000000..97b5070
--- /dev/null
@@ -0,0 +1,472 @@
+/*     $NetBSD: Locore.c,v 1.1 1996/09/30 16:34:58 ws Exp $    */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stand.h>
+#include <openfirm.h>
+
+#include <machine/cpu.h>
+
+static int (*openfirmware)(void *);
+
+static void
+setup();
+
+#define __dead
+
+__dead void
+_start(vpd, res, openfirm, arg, argl)
+       void *vpd;
+       int res;
+       int (*openfirm)(void *);
+       char *arg;
+       int argl;
+{
+       extern char etext;
+
+#ifdef FIREPOWERBUGS
+       syncicache((void *)RELOC, &etext - (char *)RELOC);
+#endif
+       openfirmware = openfirm;        /* Save entry to Open Firmware */
+       setup();
+       main(arg, argl);
+       exit();
+}
+
+__dead void
+_rtt()
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+       } args = {
+               "exit",
+               0,
+               0
+       };
+
+       openfirmware(&args);
+       while (1);                      /* just in case */
+}
+
+int
+OF_finddevice(name)
+       char *name;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               char *device;
+               int phandle;
+       } args = {
+               "finddevice",
+               1,
+               1,
+       };      
+       
+       args.device = name;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.phandle;
+}
+
+int
+OF_instance_to_package(ihandle)
+       int ihandle;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int ihandle;
+               int phandle;
+       } args = {
+               "instance-to-package",
+               1,
+               1,
+       };
+       
+       args.ihandle = ihandle;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.phandle;
+}
+
+int
+OF_getprop(handle, prop, buf, buflen)
+       int handle;
+       char *prop;
+       void *buf;
+       int buflen;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int phandle;
+               char *prop;
+               void *buf;
+               int buflen;
+               int size;
+       } args = {
+               "getprop",
+               4,
+               1,
+       };
+       
+       args.phandle = handle;
+       args.prop = prop;
+       args.buf = buf;
+       args.buflen = buflen;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.size;
+}
+
+#ifdef __notyet__      /* Has a bug on FirePower */
+int
+OF_setprop(handle, prop, buf, len)
+       int handle;
+       char *prop;
+       void *buf;
+       int len;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int phandle;
+               char *prop;
+               void *buf;
+               int len;
+               int size;
+       } args = {
+               "setprop",
+               4,
+               1,
+       };
+       
+       args.phandle = handle;
+       args.prop = prop;
+       args.buf = buf;
+       args.len = len;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.size;
+}
+#endif
+
+int
+OF_open(dname)
+       char *dname;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               char *dname;
+               int handle;
+       } args = {
+               "open",
+               1,
+               1,
+       };
+       
+       args.dname = dname;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.handle;
+}
+
+void
+OF_close(handle)
+       int handle;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int handle;
+       } args = {
+               "close",
+               1,
+               0,
+       };
+       
+       args.handle = handle;
+       openfirmware(&args);
+}
+
+int
+OF_write(handle, addr, len)
+       int handle;
+       void *addr;
+       int len;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int ihandle;
+               void *addr;
+               int len;
+               int actual;
+       } args = {
+               "write",
+               3,
+               1,
+       };
+
+       args.ihandle = handle;
+       args.addr = addr;
+       args.len = len;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.actual;
+}
+
+int
+OF_read(handle, addr, len)
+       int handle;
+       void *addr;
+       int len;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int ihandle;
+               void *addr;
+               int len;
+               int actual;
+       } args = {
+               "read",
+               3,
+               1,
+       };
+
+       args.ihandle = handle;
+       args.addr = addr;
+       args.len = len;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.actual;
+}
+
+int
+OF_seek(handle, pos)
+       int handle;
+       u_quad_t pos;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int handle;
+               int poshi;
+               int poslo;
+               int status;
+       } args = {
+               "seek",
+               3,
+               1,
+       };
+       
+       args.handle = handle;
+       args.poshi = (int)(pos >> 32);
+       args.poslo = (int)pos;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.status;
+}
+
+void *
+OF_claim(virt, size, align)
+       void *virt;
+       u_int size;
+       u_int align;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               void *virt;
+               u_int size;
+               u_int align;
+               void *baseaddr;
+       } args = {
+               "claim",
+               3,
+               1,
+       };
+
+#ifdef FIREPOWERBUGS
+       /*
+        * Bug with FirePower machines (actually Firmworks OFW)
+        */
+       if (virt)
+               return virt;
+#endif
+       args.virt = virt;
+       args.size = size;
+       args.align = align;
+       if (openfirmware(&args) == -1)
+               return (void *)-1;
+       return args.baseaddr;
+}
+
+void
+OF_release(virt, size)
+       void *virt;
+       u_int size;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               void *virt;
+               u_int size;
+       } args = {
+               "release",
+               2,
+               0,
+       };
+       
+       args.virt = virt;
+       args.size = size;
+       openfirmware(&args);
+}
+
+int
+OF_milliseconds()
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int ms;
+       } args = {
+               "milliseconds",
+               0,
+               1,
+       };
+       
+       openfirmware(&args);
+       return args.ms;
+}
+
+#ifdef __notyet__
+void
+OF_chain(virt, size, entry, arg, len)
+       void *virt;
+       u_int size;
+       void (*entry)();
+       void *arg;
+       u_int len;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               void *virt;
+               u_int size;
+               void (*entry)();
+               void *arg;
+               u_int len;
+       } args = {
+               "chain",
+               5,
+               0,
+       };
+
+       args.virt = virt;
+       args.size = size;
+       args.entry = entry;
+       args.arg = arg;
+       args.len = len;
+       openfirmware(&args);
+}
+#else
+void
+OF_chain(virt, size, entry, arg, len)
+       void *virt;
+       u_int size;
+       void (*entry)();
+       void *arg;
+       u_int len;
+{
+       /*
+        * This is a REALLY dirty hack till the firmware gets this going
+        */
+       OF_release(virt, size);
+       entry(0, 0, openfirmware, arg, len);
+}
+#endif
+
+static int stdin;
+static int stdout;
+
+static void
+setup()
+{
+       int chosen;
+       
+       if ((chosen = OF_finddevice("/chosen")) == -1)
+               _rtt();
+       if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) != sizeof(stdin)
+           || OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) != sizeof(stdout))
+               _rtt();
+}
+
+void
+putchar(c)
+       int c;
+{
+       char ch = c;
+
+       if (c == '\n')
+               putchar('\r');
+       OF_write(stdout, &ch, 1);
+}
+
+int
+getchar()
+{
+       unsigned char ch;
+       int l;
+
+       while ((l = OF_read(stdin, &ch, 1)) != 1)
+               if (l != -2)
+                       return -1;
+       return ch;
+}
diff --git a/sys/arch/powerpc/stand/Makefile b/sys/arch/powerpc/stand/Makefile
new file mode 100644 (file)
index 0000000..7a66144
--- /dev/null
@@ -0,0 +1,28 @@
+#      $NetBSD: Makefile,v 1.1 1996/09/30 16:34:59 ws Exp $
+
+SUBDIR=        boot
+
+SAREL=
+KERNREL=
+KERN_AS=library
+
+.include "Makefile.inc"
+.include "$S/lib/libsa/Makefile.inc"
+.include "$S/lib/libkern/Makefile.inc"
+
+all:   $(SALIB) ${KERNLIB} _SUBDIRUSE
+
+libdep:
+       @echo $(SALIB) $(KERNLIB)
+
+
+${PROG}:       
+
+clean::        _SUBDIRUSE
+
+cleandir:      _SUBDIRUSE
+
+depend::       _SUBDIRUSE
+
+.include <bsd.obj.mk>
+.include <bsd.subdir.mk>
diff --git a/sys/arch/powerpc/stand/Makefile.inc b/sys/arch/powerpc/stand/Makefile.inc
new file mode 100644 (file)
index 0000000..6ea10de
--- /dev/null
@@ -0,0 +1,32 @@
+#      $NetBSD: Makefile.inc,v 1.1 1996/09/30 16:34:59 ws Exp $
+
+.if !defined(__stand_makefile_inc)
+__stand_makefile_inc=1
+
+KERN_AS=       library
+
+S=$(.CURDIR)/../../../$(R)
+
+.if !make(libdep) && !make(sadep) && !make(salibdir) && !make(kernlibdir) && !make(obj)
+.BEGIN:
+       @([ -h machine ] || ln -s $(S)/arch/$(MACHINE)/include machine)
+.endif
+
+# for now
+RELOC?=                4000
+LOADADDR?=     100000
+#
+EXTRACFLAGS=   -msoft-float
+REAL_VIRT?=    -v
+ENTRY?=        _start
+
+INCLUDES+=     -I. -I$(.CURDIR)/.. -I$(S)/arch -I$(S) -I$(S)/lib/libsa
+DEFS+=         -DSTANDALONE -DRELOC=0x$(RELOC) -DLOADADDR=0x$(LOADADDR) \
+               -DFIREPOWERBUGS
+CFLAGS+=       $(INCLUDES) $(DEFS) $(EXTRACFLAGS)
+LDFLAGS=       -X -N -Ttext $(RELOC) -e $(ENTRY)
+
+cleandir:
+       rm -rf lib machine
+
+.endif
diff --git a/sys/arch/powerpc/stand/alloc.c b/sys/arch/powerpc/stand/alloc.c
new file mode 100644 (file)
index 0000000..3ad956f
--- /dev/null
@@ -0,0 +1,179 @@
+/*     $NetBSD: alloc.c,v 1.1 1996/09/30 16:35:00 ws Exp $     */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+
+/*
+ * Substitute alloc.c for Openfirmware machines
+ */
+#include <sys/param.h>
+
+#include <openfirm.h>
+#include <stand.h>
+
+/*
+ * al tracks the allocated regions, fl tracks the free list
+ */
+struct ml {
+       struct ml *next;
+       unsigned int size;
+} *al, *fl;
+
+void *
+alloc(size)
+       unsigned size;
+{
+       struct ml **fp, *f;
+       unsigned rsz;
+       
+       size = ALIGN(size) + ALIGN(sizeof(struct ml));
+       for (fp = &fl; f = *fp; fp = &f->next)
+               if (f->size >= size)
+                       break;
+       if (!f) {
+               rsz = roundup(size, NBPG);
+               f = OF_claim(0, rsz, NBPG);
+               if (f == (void *)-1)
+                       panic("alloc");
+               f->size = rsz;
+       } else
+               *fp = f->next;
+               
+       f->next = al;
+       al = f;
+       return (void *)f + ALIGN(sizeof(struct ml));
+}
+
+void
+free(ptr, size)
+       void *ptr;
+       unsigned size;
+{
+       struct ml *f = (struct ml *)(ptr - ALIGN(sizeof(struct ml)));
+       
+       if (f->size != roundup(ALIGN(size) + ALIGN(sizeof(struct ml)), NBPG))
+               panic("free: wrong size (%x != %x)",
+                     f->size,
+                     roundup(ALIGN(size) + ALIGN(sizeof(struct ml)), NBPG));
+       f->next = fl;
+       fl = f;
+}
+
+void
+freeall()
+{
+#ifdef __notyet__              /* looks like there is a bug in Motorola OFW */
+       struct ml *m1, *m2;
+
+       for (m1 = fl; m1; m1 = m2) {
+               m2 = m1->next;
+               OF_release(m1, m1->size);
+       }
+       for (m1 = al; m1; m1 = m2) {
+               m2 = m1->next;
+               OF_release(m1, m1->size);
+       }
+#endif
+}
+
+#ifdef __notdef__
+#ifdef FIREPOWERBUGS
+/*
+ * Since firmware insists on running virtual, we manage memory ourselves,
+ * hoping that OpenFirmware will not need extra memory.
+ * (But then, the callbacks don't work anyway).
+ */
+#define        OFMEM_REGIONS   32
+static struct {
+       u_int start;
+       u_int size;
+} OFavail[OFMEM_REGIONS];
+
+void *
+OF_claim(virt, size, align)
+       void *virt;
+       u_int size, align;
+{
+       static int init;
+       int i;
+       u_int addr = -1;
+       
+       if (!init) {
+               int phandle;
+               
+               init = 1;
+
+               if ((phandle = OF_finddevice("/memory")) == -1
+                   || OF_getprop(phandle, "available",
+                                 OFavail, sizeof OFavail) <= 0)
+                       return (void *)-1;
+       }
+       if (align) {
+               /* Due to the above, anything is page aligned here */
+               for (i = 0; i < OFMEM_REGIONS; i++) {
+                       if (!OFavail[i].size)
+                               break;
+                       if (OFavail[i].size > size) {
+                               addr = OFavail[i].start;
+                               OFavail[i].start += size;
+                               OFavail[i].size -= size;
+                               break;
+                       }
+               }
+       } else {
+               addr = (u_int)virt;
+               for (i = 0; i < OFMEM_REGIONS; i++) {
+                       if (!OFavail[i].size) {
+                               addr = -1;
+                               break;
+                       }
+                       if (OFavail[i].start <= addr
+                           && addr + size - OFavail[i].start <= OFavail[i].size) {
+                               /* Be lazy here, just cut off anything below addr */
+                               size += addr - OFavail[i].start;
+                               OFavail[i].start += size;
+                               OFavail[i].size -= size;
+                               break;
+                       }
+               }
+       }
+       return (void *)addr;
+}
+
+/* Since this is called solely immediately before chain, we ignore it. */
+void
+OF_release(virt, size)
+       void *virt;
+       u_int size;
+{
+}
+#endif /* FIREPOWERBUGS */
+#endif
diff --git a/sys/arch/powerpc/stand/boot.c b/sys/arch/powerpc/stand/boot.c
new file mode 100644 (file)
index 0000000..df2969d
--- /dev/null
@@ -0,0 +1,285 @@
+/*     $NetBSD: boot.c,v 1.2 1996/10/07 21:43:02 cgd Exp $     */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+/*
+ * First try for the boot code
+ *
+ * Input syntax is:
+ *     [promdev[{:|,}partition]]/[filename] [flags]
+ */
+#include <stand.h>
+
+#include <sys/exec.h>
+#include <sys/reboot.h>
+#include <sys/disklabel.h>
+
+#include <sys/exec_elf.h>
+#include <machine/cpu.h>
+
+#include "ofdev.h"
+#include "openfirm.h"
+
+char bootdev[128];
+char bootfile[128];
+int boothowto;
+int debug;
+
+static void
+prom2boot(dev)
+       char *dev;
+{
+       char *cp, *lp = 0;
+       int handle;
+       char devtype[16];
+       
+       for (cp = dev; *cp; cp++)
+               if (*cp == ':')
+                       lp = cp;
+       if (!lp)
+               lp = cp;
+       *lp = 0;
+}
+
+static void
+parseargs(str, howtop)
+       char *str;
+       int *howtop;
+{
+       char *cp;
+       
+       *howtop = 0;
+       for (cp = str; *cp; cp++)
+               if (*cp == ' ' || *cp == '-')
+                       break;
+       if (!*cp)
+               return;
+       
+       *cp++ = 0;
+       while (*cp) {
+               switch (*cp++) {
+               case 'a':
+                       *howtop |= RB_ASKNAME;
+                       break;
+               case 's':
+                       *howtop |= RB_SINGLE;
+                       break;
+               case 'd':
+                       *howtop |= RB_KDB;
+                       debug = 1;
+                       break;
+               }
+       }
+}
+
+static void
+chain(entry, args)
+       void (*entry)();
+       char *args;
+{
+       extern end;
+
+       freeall();
+       OF_chain((void *)RELOC, (void *)&end - (void *)RELOC,
+                entry, args, strlen(args) + 1);
+       panic("chain");
+}
+
+static void
+loadfile(fd, addr, args)
+       int fd;
+       void *addr;
+       char *args;
+{
+       struct exec hdr;
+       int n;
+       int *paddr;
+       void *exec_addr;
+       
+       if (read(fd, &hdr, sizeof hdr) != sizeof(hdr))
+               panic("short a.out file");
+       if (
+#if defined (EXEC_AOUT)
+               (N_BADMAG(hdr) || N_GETMID(hdr) != MID_POWERPC)
+#endif
+#if defined(EXEC_AOUT) && defined (EXEC_ELF)
+               &&
+#endif
+#if defined (EXEC_ELF)
+               (((u_int *)&hdr)[0] != 0x7f454c46) /* 0x7f E L F */
+#endif
+               )
+       {
+               panic("invalid executable format");
+       }
+#ifdef EXEC_AOUT
+       if (N_GETMID(hdr) == MID_POWERPC) {
+               n = hdr.a_text + hdr.a_data + hdr.a_bss + hdr.a_syms
+                       + sizeof(int);
+               if ((paddr = OF_claim(addr, n, 0)) == (int *)-1)
+                       panic("cannot claim memory");
+               lseek(fd, N_TXTOFF(hdr), SEEK_SET);
+               if (read(fd, paddr, hdr.a_text + hdr.a_data) !=
+                       hdr.a_text + hdr.a_data)
+               {
+                       panic("short a.out file");
+               }
+               bzero((void *)paddr + hdr.a_text + hdr.a_data, hdr.a_bss);
+               paddr = (int *)((void *)paddr + hdr.a_text + hdr.a_data
+                       + hdr.a_bss);
+               *paddr++ = hdr.a_syms;
+               if (hdr.a_syms) {
+                       if (read(fd, paddr, hdr.a_syms) != hdr.a_syms)
+                               panic("short a.out file");
+                       paddr = (int *)((void *)paddr + hdr.a_syms);
+                       if (read(fd, &n, sizeof(int)) != sizeof(int))
+                               panic("short a.out file");
+                       if (OF_claim((void *)paddr, n + sizeof(int), 0) ==
+                               (void *)-1)
+                       {
+                               panic("cannot claim memory");
+                       }
+                       *paddr++ = n;
+                       if (read(fd, paddr, n - sizeof(int)) != n - sizeof(int))
+                       {
+                               panic("short a.out file");
+                       }
+               }
+               exec_addr = hdr.a_text;
+       }
+#endif
+#ifdef EXEC_ELF
+       if (((u_int *)&hdr)[0] == 0x7f454c46) /* 0x7f E L F */ {
+               Elf32_Ehdr ehdr;
+               Elf32_Phdr phdr;
+               int loc_phdr;
+               int i;
+
+               lseek (fd, 0, SEEK_SET);
+               read (fd, &ehdr, sizeof (ehdr));
+               loc_phdr = ehdr.e_phoff;
+               for (i = 1; i <=ehdr.e_phnum; i++) {
+                       lseek(fd, loc_phdr, SEEK_SET);
+                       read (fd, &phdr, sizeof(phdr));
+                       loc_phdr += sizeof(phdr);
+                       
+                       if (phdr.p_type == PT_LOAD) {
+                               printf("phseg %d addr %x  size %x\n", i,
+                                       phdr.p_vaddr, phdr.p_memsz);
+                               lseek(fd, phdr.p_offset, SEEK_SET);
+                               paddr = (int *)phdr.p_vaddr;
+                               n = phdr.p_memsz;
+                               if (OF_claim((void *)paddr, n , 0) == (int *)-1)
+                                       panic("cannot claim memory");
+                               read (fd, paddr, phdr.p_filesz);
+                               if (phdr.p_filesz != phdr.p_memsz) {
+                                       bzero (addr + n,
+                                               phdr.p_memsz - phdr.p_filesz);
+                               }
+                       }
+               }
+               exec_addr = ehdr.e_entry;
+       }
+#endif
+       close(fd);
+       syncicache(addr, exec_addr);
+       if (floppyboot) {
+               printf("Please insert root disk and press ENTER ");
+               getchar();
+               printf("\n");
+       }
+       chain((void *)exec_addr, args);
+}
+
+char bootline[512];
+void
+main()
+{
+       int chosen;
+       char *cp;
+       int fd;
+       
+       printf(">> NetBSD BOOT\n");
+
+       /*
+        * Get the boot arguments from Openfirmware
+        */
+       if ((chosen = OF_finddevice("/chosen")) == -1
+           || OF_getprop(chosen, "bootpath", bootdev, sizeof bootdev) < 0
+           || OF_getprop(chosen, "bootargs", bootline, sizeof bootline) < 0) {
+               printf("Invalid Openfirmware environment\n");
+               exit();
+       }
+       prom2boot(bootdev);
+       parseargs(bootline, &boothowto);
+       for (;;) {
+               if (boothowto & RB_ASKNAME) {
+                       printf("Boot: ");
+                       gets(bootline);
+                       parseargs(bootline, &boothowto);
+               }
+               if ((fd = open(bootline, 0)) >= 0)
+                       break;
+               if (errno)
+                       printf("open %s: %s\n", opened_name, strerror(errno));
+               boothowto |= RB_ASKNAME;
+       }
+       printf("Booting %s @ 0x%x\n", opened_name, LOADADDR);
+#ifdef __notyet__
+       OF_setprop(chosen, "bootpath", opened_name, strlen(opened_name) + 1);
+       cp = bootline;
+#else
+       strncpy(bootline, opened_name, 512);
+       cp = bootline + strlen(bootline);
+       *cp++ = ' ';
+#endif
+       *cp = '-';
+       if (boothowto & RB_ASKNAME)
+               *++cp = 'a';
+       if (boothowto & RB_SINGLE)
+               *++cp = 's';
+       if (boothowto & RB_KDB)
+               *++cp = 'd';
+       if (*cp == '-')
+#ifdef __notyet__
+               *cp = 0;
+#else
+               *--cp = 0;
+#endif
+       else
+               *++cp = 0;
+#ifdef __notyet__
+       OF_setprop(chosen, "bootargs", bootline, strlen(bootline) + 1);
+#endif
+       loadfile(fd, LOADADDR, bootline);
+
+       _rtt();
+}
diff --git a/sys/arch/powerpc/stand/boot/Makefile b/sys/arch/powerpc/stand/boot/Makefile
new file mode 100644 (file)
index 0000000..d593771
--- /dev/null
@@ -0,0 +1,20 @@
+#       $NetBSD: Makefile,v 1.1 1996/09/30 16:35:05 ws Exp $
+
+R=              ..
+.PATH:          $(.CURDIR)/$(R)
+PROG=           boot.ppc
+SRCS=           Locore.c boot.c ofdev.c net.c netif_of.c alloc.c
+#CFLAGS+=       -DDEBUG -DNETIF_DEBUG
+CFLAGS+=       -DEXEC_ELF
+NOMAN=
+STRIP=
+MAKEELF=        makeelf
+BINDIR=         /usr/mdec
+
+LIBS!=          cd $(.CURDIR)/$(R); $(MAKE) libdep
+
+$(PROG):        $(OBJS) $(LIBS)
+       $(LD) $(LDFLAGS) $(OBJS) $(LIBS) -o ${.TARGET}
+#      ${MAKEELF} $(REAL_VIRT) a.out $(.TARGET)
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/powerpc/stand/net.c b/sys/arch/powerpc/stand/net.c
new file mode 100644 (file)
index 0000000..d78e8e9
--- /dev/null
@@ -0,0 +1,152 @@
+/*     $NetBSD: net.c,v 1.1 1996/09/30 16:35:01 ws Exp $       */
+
+/*
+ * Copyright (C) 1995 Wolfgang Solfrank.
+ * Copyright (C) 1995 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This module implements a "raw device" interface suitable for
+ * use by the stand-alone I/O library NFS code.  This interface
+ * does not support any "block" access, and exists only for the
+ * purpose of initializing the network interface, getting boot
+ * parameters, and performing the NFS mount.
+ *
+ * At open time, this does:
+ *
+ * find interface      - netif_open()
+ * BOOTP               - bootp()
+ * RPC/mountd          - nfs_mount()
+ *
+ * The root file handle from mountd is saved in a global
+ * for use by the NFS open code (NFS/lookup).
+ *
+ * Note: this is based in part on sys/arch/sparc/stand/net.c
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+
+char   rootpath[FNAME_SIZE];
+
+static int netdev_sock = -1;
+static int open_count;
+
+/*
+ * Called by devopen after it sets f->f_dev to our devsw entry.
+ * This opens the low-level device and sets f->f_devdata.
+ */
+int
+net_open(op)
+       struct of_dev *op;
+{
+       int error = 0;
+       
+       /*
+        * On first open, do netif open, mount, etc.
+        */
+       if (open_count == 0) {
+               /* Find network interface. */
+               if ((netdev_sock = netif_open(op)) < 0) {
+                       error = errno;
+                       goto bad;
+               }
+               if ((error = net_mountroot()) != 0)
+                       goto bad;
+       }
+       open_count++;
+bad:
+       if (netdev_sock >= 0 && open_count == 0) {
+               netif_close(netdev_sock);
+               netdev_sock = -1;
+       }
+       return error;
+}
+
+int
+net_close(op)
+       struct of_dev *op;
+{
+       /*
+        * On last close, do netif close, etc.
+        */
+       if (open_count > 0)
+               if (--open_count == 0) {
+                       netif_close(netdev_sock);
+                       netdev_sock = -1;
+               }
+}
+
+int
+net_mountroot()
+{
+
+#ifdef DEBUG
+       printf("net_mountroot\n");
+#endif
+       
+       /*
+        * Get info for NFS boot: our IP address, out hostname,
+        * server IP address, and our root path on the server.
+        * We use BOOTP (RFC951, RFC1532) exclusively as mandated
+        * by PowerPC Reference Platform Specification I.4.2
+        */
+       
+       bootp(netdev_sock);
+       
+       if (myip.s_addr == 0)
+               return ETIMEDOUT;
+       
+       printf("Using IP address: %s\n", inet_ntoa(myip));
+       
+#ifdef DEBUG
+       printf("myip: %s (%s)", hostname, inet_ntoa(myip));
+       if (gateip.s_addr)
+               printf(", gateip: %s", inet_ntoa(gateip));
+       if (netmask)
+               printf(", netmask: %s", intoa(netmask));
+       printf("\n");
+#endif
+       printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath);
+       
+       /*
+        * Get the NFS file handle (mount).
+        */
+       if (nfs_mount(netdev_sock, rootip, rootpath) < 0)
+               return errno;
+       return 0;
+}
diff --git a/sys/arch/powerpc/stand/netif_of.c b/sys/arch/powerpc/stand/netif_of.c
new file mode 100644 (file)
index 0000000..11fce71
--- /dev/null
@@ -0,0 +1,241 @@
+/*     $NetBSD: netif_of.c,v 1.1 1996/09/30 16:35:02 ws Exp $  */
+
+/*
+ * Copyright (C) 1995 Wolfgang Solfrank.
+ * Copyright (C) 1995 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+
+/*
+ * Open Firmware does most of the job for interfacing to the hardware,
+ * so it is easiest to just replace the netif module with
+ * this adaptation to the PROM network interface.
+ *
+ * Note: this is based in part on sys/arch/sparc/stand/netif_sun.c
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <time.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+
+#include "ofdev.h"
+#include "openfirm.h"
+
+static struct netif netif_of;
+
+struct iodesc sockets[SOPEN_MAX];
+
+struct iodesc *
+socktodesc(sock)
+       int sock;
+{
+       if (sock != 0)
+               return NULL;
+       return sockets;
+}
+
+int
+netif_open(machdep_hint)
+       void *machdep_hint;
+{
+       struct of_dev *op = machdep_hint;
+       struct iodesc *io;
+       int fd, error;
+       char addr[32];
+       
+#ifdef NETIF_DEBUG
+       printf("netif_open...");
+#endif
+       /* find a free socket */
+       io = sockets;
+       if (io->io_netif) {
+#ifdef NETIF_DEBUG
+               printf("device busy\n");
+#endif
+               errno = ENFILE;
+               return -1;
+       }
+       bzero(io, sizeof *io);
+
+       netif_of.nif_devdata = op;
+       io->io_netif = &netif_of;
+       
+       /* Put our ethernet address in io->myea */
+       OF_getprop(OF_instance_to_package(op->handle),
+                  "mac-address", io->myea, sizeof io->myea);
+
+#ifdef NETIF_DEBUG
+       printf("OK\n");
+#endif
+       return 0;
+}
+
+int
+netif_close(fd)
+       int fd;
+{
+       struct iodesc *io;
+       struct netif *ni;
+
+#ifdef NETIF_DEBUG
+       printf("netif_close(%x)...", fd);
+#endif
+       if (fd != 0) {
+#ifdef NETIF_DEBUG
+               printf("EBADF\n");
+#endif
+               errno = EBADF;
+               return -1;
+       }
+
+       io = &sockets[fd];
+       ni = io->io_netif;
+       if (ni != NULL) {
+               ni->nif_devdata = NULL;
+               io->io_netif = NULL;
+       }
+#ifdef NETIF_DEBUG
+       printf("OK\n");
+#endif
+       return 0;
+}
+
+/*
+ * Send a packet.  The ether header is already there.
+ * Return the length sent (or -1 on error).
+ */
+ssize_t
+netif_put(desc, pkt, len)
+       struct iodesc *desc;
+       void *pkt;
+       size_t len;
+{
+       struct of_dev *op;
+       ssize_t rv;
+       size_t sendlen;
+
+       op = desc->io_netif->nif_devdata;
+
+#ifdef NETIF_DEBUG
+       {
+               struct ether_header *eh;
+
+               printf("netif_put: desc=0x%x pkt=0x%x len=%d\n",
+                      desc, pkt, len);
+               eh = pkt;
+               printf("dst: %s ", ether_sprintf(eh->ether_dhost));
+               printf("src: %s ", ether_sprintf(eh->ether_shost));
+               printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
+       }
+#endif
+
+       sendlen = len;
+       if (sendlen < 60) {
+               sendlen = 60;
+#ifdef NETIF_DEBUG
+               printf("netif_put: length padded to %d\n", sendlen);
+#endif
+       }
+
+       rv = OF_write(op->handle, pkt, sendlen);
+
+#ifdef NETIF_DEBUG
+       printf("netif_put: xmit returned %d\n", rv);
+#endif
+
+       return rv;
+}
+
+/*
+ * Receive a packet, including the ether header.
+ * Return the total length received (or -1 on error).
+ */
+ssize_t
+netif_get(desc, pkt, maxlen, timo)
+       struct iodesc *desc;
+       void *pkt;
+       size_t maxlen;
+       time_t timo;
+{
+       struct of_dev *op;
+       int tick0, tmo_ms;
+       int len;
+
+       op = desc->io_netif->nif_devdata;
+
+#ifdef NETIF_DEBUG
+       printf("netif_get: pkt=0x%x, maxlen=%d, tmo=%d\n",
+              pkt, maxlen, timo);
+#endif
+
+       tmo_ms = timo * 1000;
+       tick0 = OF_milliseconds();
+
+       do {
+               len = OF_read(op->handle, pkt, maxlen);
+       } while ((len == -2) && ((OF_milliseconds() - tick0) < tmo_ms));
+
+#ifdef NETIF_DEBUG
+       printf("netif_get: received len=%d\n", len);
+#endif
+
+       if (len < 12)
+               return -1;
+
+#ifdef NETIF_DEBUG
+       {
+               struct ether_header *eh = pkt;
+
+               printf("dst: %s ", ether_sprintf(eh->ether_dhost));
+               printf("src: %s ", ether_sprintf(eh->ether_shost));
+               printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
+       }
+#endif
+
+       return len;
+}
+
+/*
+ * Shouldn't really be here, but is used solely for networking, so...
+ */
+time_t
+getsecs()
+{
+       return OF_milliseconds() / 1000;
+}
diff --git a/sys/arch/powerpc/stand/ofdev.c b/sys/arch/powerpc/stand/ofdev.c
new file mode 100644 (file)
index 0000000..e1868ae
--- /dev/null
@@ -0,0 +1,337 @@
+/*     $NetBSD: ofdev.c,v 1.1 1996/09/30 16:35:03 ws Exp $     */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Device I/O routines using Open Firmware
+ */
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include <netinet/in.h>
+
+#include <stand.h>
+#include <ufs.h>
+#include <cd9660.h>
+#include <nfs.h>
+
+#include "ofdev.h"
+
+extern char bootdev[];
+
+static char *
+filename(str, ppart)
+       char *str;
+       char *ppart;
+{
+       char *cp, *lp;
+       char savec;
+       int dhandle;
+       char devtype[16];
+       
+       lp = str;
+       devtype[0] = 0;
+       *ppart = 0;
+       for (cp = str; *cp; lp = cp) {
+               /* For each component of the path name... */
+               while (*++cp && *cp != '/');
+               savec = *cp;
+               *cp = 0;
+               /* ...look whether there is a device with this name */
+               dhandle = OF_finddevice(str);
+               *cp = savec;
+               if (dhandle == -1) {
+                       /* if not, lp is the delimiter between device and path */
+                       /* if the last component was a block device... */
+                       if (!strcmp(devtype, "block")) {
+                               /* search for arguments */
+                               for (cp = lp;
+                                    --cp >= str && *cp != '/' && *cp != ':';);
+                               if (cp >= str && *cp == ':') {
+                                       /* found arguments, make firmware ignore them */
+                                       *cp = 0;
+                                       for (cp = lp; *--cp && *cp != ',';);
+                                       if (*++cp >= 'a' && *cp <= 'a' + MAXPARTITIONS)
+                                               *ppart = *cp;
+                               }
+                       }
+                       return lp;
+               } else if (OF_getprop(dhandle, "device_type", devtype, sizeof devtype) < 0)
+                       devtype[0] = 0;
+       }
+       return 0;
+}
+
+static int
+strategy(devdata, rw, blk, size, buf, rsize)
+       void *devdata;
+       int rw;
+       daddr_t blk;
+       size_t size;
+       void *buf;
+       size_t *rsize;
+{
+       struct of_dev *dev = devdata;
+       u_quad_t pos;
+       int n;
+       
+       if (rw != F_READ)
+               return EPERM;
+       if (dev->type != OFDEV_DISK)
+               panic("strategy");
+       
+       pos = (u_quad_t)(blk + dev->partoff) * dev->bsize;
+       
+       for (;;) {
+               if (OF_seek(dev->handle, pos) < 0)
+                       break;
+               n = OF_read(dev->handle, buf, size);
+               if (n == -2)
+                       continue;
+               if (n < 0)
+                       break;
+               *rsize = n;
+               return 0;
+       }
+       return EIO;
+}
+
+static int
+devclose(of)
+       struct open_file *of;
+{
+       struct of_dev *op = of->f_devdata;
+       
+       if (op->type == OFDEV_NET)
+               net_close(op);
+       OF_close(op->handle);
+       op->handle = -1;
+}
+
+static struct devsw devsw[1] = {
+       "OpenFirmware",
+       strategy,
+       (int (*)__P((struct open_file *, ...)))nodev,
+       devclose,
+       noioctl
+};
+int ndevs = sizeof devsw / sizeof devsw[0];
+
+static struct fs_ops file_system_ufs = {
+       ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat
+};
+static struct fs_ops file_system_cd9660 = {
+       cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek, cd9660_stat
+};
+static struct fs_ops file_system_nfs = {
+       nfs_open, nfs_close, nfs_read, nfs_write, nfs_seek, nfs_stat
+};
+
+struct fs_ops file_system[2];
+int nfsys;
+
+static struct of_dev ofdev = {
+       -1,
+};
+
+char opened_name[256];
+int floppyboot;
+
+static u_long
+get_long(p)
+       const void *p;
+{
+       const unsigned char *cp = p;
+       
+       return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24);
+}
+
+/*
+ * Find a valid disklabel.
+ */
+static int
+search_label(devp, off, buf, lp, off0)
+       struct of_dev *devp;
+       u_long off;
+       char *buf;
+       struct disklabel *lp;
+       u_long off0;
+{
+       size_t read;
+       struct mbr_partition *p;
+       int i;
+       u_long poff;
+       static int recursion;
+       
+       if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
+           || read != DEV_BSIZE)
+               return ERDLAB;
+       
+       if (buf[510] != 0x55 || buf[511] != 0xaa)
+               return ERDLAB;
+
+       if (recursion++ <= 1)
+               off0 += off;
+       for (p = (struct mbr_partition *)(buf + MBRPARTOFF), i = 4;
+            --i >= 0; p++) {
+               if (p->mbr_type == MBR_NETBSD) {
+                       poff = get_long(&p->mbr_start) + off0;
+                       if (strategy(devp, F_READ, poff + LABELSECTOR,
+                                    DEV_BSIZE, buf, &read) == 0
+                           && read == DEV_BSIZE) {
+                               if (!getdisklabel(buf, lp)) {
+                                       recursion--;
+                                       return 0;
+                               }
+                       }
+                       if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
+                           || read != DEV_BSIZE) {
+                               recursion--;
+                               return ERDLAB;
+                       }
+               } else if (p->mbr_type == MBR_EXTENDED) {
+                       poff = get_long(&p->mbr_start);
+                       if (!search_label(devp, poff, buf, lp, off0)) {
+                               recursion--;
+                               return 0;
+                       }
+                       if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
+                           || read != DEV_BSIZE) {
+                               recursion--;
+                               return ERDLAB;
+                       }
+               }
+       }
+       recursion--;
+       return ERDLAB;
+}
+
+int
+devopen(of, name, file)
+       struct open_file *of;
+       const char *name;
+       char **file;
+{
+       char *cp;
+       char partition;
+       char fname[256];
+       char buf[DEV_BSIZE];
+       struct disklabel label;
+       int handle, part;
+       size_t read;
+       int error = 0;
+
+       if (ofdev.handle != -1)
+               panic("devopen");
+       if (of->f_flags != F_READ)
+               return EPERM;
+       strcpy(fname, name);
+       cp = filename(fname, &partition);
+       if (cp) {
+               strcpy(buf, cp);
+               *cp = 0;
+       }
+       if (!cp || !*buf)
+               strcpy(buf, DEFAULT_KERNEL);
+       if (!*fname)
+               strcpy(fname, bootdev);
+       strcpy(opened_name, fname);
+       if (partition) {
+               cp = opened_name + strlen(opened_name);
+               *cp++ = ':';
+               *cp++ = partition;
+               *cp = 0;
+       }
+       if (*buf != '/')
+               strcat(opened_name, "/");
+       strcat(opened_name, buf);
+       *file = opened_name + strlen(fname) + 1;
+       if ((handle = OF_finddevice(fname)) == -1)
+               return ENOENT;
+       if (OF_getprop(handle, "name", buf, sizeof buf) < 0)
+               return ENXIO;
+       floppyboot = !strcmp(buf, "floppy");
+       if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0)
+               return ENXIO;
+       if (!strcmp(buf, "block"))
+               /* For block devices, indicate raw partition (:0 in OpenFirmware) */
+               strcat(fname, ":0");
+       if ((handle = OF_open(fname)) == -1)
+               return ENXIO;
+       bzero(&ofdev, sizeof ofdev);
+       ofdev.handle = handle;
+       if (!strcmp(buf, "block")) {
+               ofdev.type = OFDEV_DISK;
+               ofdev.bsize = DEV_BSIZE;
+               /* First try to find a disklabel without MBR partitions */
+               if (strategy(&ofdev, F_READ,
+                            LABELSECTOR, DEV_BSIZE, buf, &read) != 0
+                   || read != DEV_BSIZE
+                   || getdisklabel(buf, &label)) {
+                       /* Else try MBR partitions */
+                       error = search_label(&ofdev, 0, buf, &label, 0);
+                       if (error && error != ERDLAB)
+                               goto bad;
+               }
+
+               if (error == ERDLAB) {
+                       if (partition)
+                               /* User specified a parititon, but there is none */
+                               goto bad;
+                       /* No, label, just use complete disk */
+                       ofdev.partoff = 0;
+               } else {
+                       part = partition ? partition - 'a' : 0;
+                       ofdev.partoff = label.d_partitions[part].p_offset;
+               }
+               
+               of->f_dev = devsw;
+               of->f_devdata = &ofdev;
+               bcopy(&file_system_ufs, file_system, sizeof file_system[0]);
+               bcopy(&file_system_cd9660, file_system + 1, sizeof file_system[0]);
+               nfsys = 2;
+               return 0;
+       }
+       if (!strcmp(buf, "network")) {
+               ofdev.type = OFDEV_NET;
+               of->f_dev = devsw;
+               of->f_devdata = &ofdev;
+               bcopy(&file_system_nfs, file_system, sizeof file_system[0]);
+               nfsys = 1;
+               if (error = net_open(&ofdev))
+                       goto bad;
+               return 0;
+       }
+       error = EFTYPE;
+bad:
+       OF_close(handle);
+       ofdev.handle = -1;
+       return error;
+}
diff --git a/sys/arch/powerpc/stand/ofdev.h b/sys/arch/powerpc/stand/ofdev.h
new file mode 100644 (file)
index 0000000..d6e0d52
--- /dev/null
@@ -0,0 +1,52 @@
+/*     $NetBSD: ofdev.h,v 1.1 1996/09/30 16:35:04 ws Exp $     */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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        _STAND_DEV_H_
+#define        _STAND_DEV_H_
+
+struct of_dev {
+       int handle;
+       int type;
+       u_long partoff;
+       int bsize;
+};
+
+/* Known types: */
+#define        OFDEV_NET       1
+#define        OFDEV_DISK      2
+
+#define        DEFAULT_KERNEL  "/netbsd"
+
+extern char opened_name[];
+extern int floppyboot;
+
+#endif
diff --git a/sys/arch/powerpc/stand/openfirm.h b/sys/arch/powerpc/stand/openfirm.h
new file mode 100644 (file)
index 0000000..e0f1ab1
--- /dev/null
@@ -0,0 +1,55 @@
+/*     $NetBSD: openfirm.h,v 1.1 1996/09/30 16:35:04 ws Exp $  */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+/*
+ * Prototypes for Openfirmware Interface Routines
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+int OF_finddevice __P((char *name));
+int OF_instance_to_package __P((int ihandle));
+int OF_getprop __P((int handle, char *prop, void *buf, int buflen));
+#ifdef __notyet__
+int OF_setprop __P((int handle, char *prop, void *buf, int len));
+#endif
+int OF_open __P((char *dname));
+void OF_close __P((int handle));
+int OF_write __P((int handle, void *addr, int len));
+int OF_read __P((int handle, void *addr, int len));
+int OF_seek __P((int handle, u_quad_t pos));
+void *OF_claim __P((void *virt, u_int size, u_int align));
+void OF_release __P((void *virt, u_int size));
+int OF_milliseconds __P((void));
+void OF_chain __P((void *addr, u_int size, void (*entry)(), void *parm, u_int parmlen));
+