From: rahnds Date: Sat, 21 Dec 1996 20:35:52 +0000 (+0000) Subject: Check-in of powerpc kernel support. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=47bc79e1bfa6761e3aba257d46cb381307aca871;p=openbsd Check-in of powerpc kernel support. NOTE: This will not work until the other pieces are checked in. This is primarily the NetBSD powerpc port, with modifications to support ELF. --- diff --git a/sys/arch/powerpc/Makefile b/sys/arch/powerpc/Makefile new file mode 100644 index 00000000000..ee2611fdecc --- /dev/null +++ b/sys/arch/powerpc/Makefile @@ -0,0 +1,8 @@ +NOPROG= noprog +NOMAN= noman + +SUBDIR= stand + +obj: _SUBDIRUSE + +.include diff --git a/sys/arch/powerpc/README b/sys/arch/powerpc/README new file mode 100644 index 00000000000..834bbee0663 --- /dev/null +++ b/sys/arch/powerpc/README @@ -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 index 00000000000..7a8afb7a31d --- /dev/null +++ b/sys/arch/powerpc/conf/GENERIC @@ -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 index 00000000000..aa1bfd47bee --- /dev/null +++ b/sys/arch/powerpc/conf/Makefile.powerpc @@ -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 index 00000000000..412dd991331 --- /dev/null +++ b/sys/arch/powerpc/conf/NFS @@ -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 index 00000000000..b8266623cd4 --- /dev/null +++ b/sys/arch/powerpc/conf/TST @@ -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 index 00000000000..31b09a7f273 --- /dev/null +++ b/sys/arch/powerpc/conf/TST.net @@ -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 index 00000000000..91538d31ef2 --- /dev/null +++ b/sys/arch/powerpc/conf/TST1 @@ -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 index 00000000000..9a92fda7329 --- /dev/null +++ b/sys/arch/powerpc/conf/TSTdbg @@ -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 index 00000000000..d39c334d57e --- /dev/null +++ b/sys/arch/powerpc/conf/files.powerpc @@ -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 index 00000000000..403bc133c6c --- /dev/null +++ b/sys/arch/powerpc/include/ansi.h @@ -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 index 00000000000..b1ea7fac77b --- /dev/null +++ b/sys/arch/powerpc/include/aout_machdep.h @@ -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 + +/* 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 index 00000000000..36f110da136 --- /dev/null +++ b/sys/arch/powerpc/include/asm.h @@ -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 index 00000000000..fc915eeb8a5 --- /dev/null +++ b/sys/arch/powerpc/include/bat.h @@ -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 index 00000000000..d8534e0fb26 --- /dev/null +++ b/sys/arch/powerpc/include/cdefs.h @@ -0,0 +1,42 @@ +/* $NetBSD: cdefs.h,v 1.1 1996/09/30 16:34:21 ws Exp $ */ + +/* + * Written by J.T. Conklin 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 index 00000000000..0ec9d59f944 --- /dev/null +++ b/sys/arch/powerpc/include/cpu.h @@ -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 + +struct machvec { + void (*splx) __P((int)); + void (*irq_establish) __P((int, int, void (*)(void *), void *)); +}; +extern struct machvec machine_interface; + +#include + +#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 index 00000000000..ffaa67cc24c --- /dev/null +++ b/sys/arch/powerpc/include/disklabel.h @@ -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 index 00000000000..6f5c4c62297 --- /dev/null +++ b/sys/arch/powerpc/include/endian.h @@ -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 + +__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 index 00000000000..36aa23455f7 --- /dev/null +++ b/sys/arch/powerpc/include/exec.h @@ -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 index 00000000000..62cd9f89505 --- /dev/null +++ b/sys/arch/powerpc/include/float.h @@ -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 + +__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 index 00000000000..e8cdb9c2dbf --- /dev/null +++ b/sys/arch/powerpc/include/fpu.h @@ -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 index 00000000000..a5b73d5f7ca --- /dev/null +++ b/sys/arch/powerpc/include/frame.h @@ -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 + +/* + * 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 index 00000000000..fe8339444a8 --- /dev/null +++ b/sys/arch/powerpc/include/ieee.h @@ -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 index 00000000000..da5f1a43b15 --- /dev/null +++ b/sys/arch/powerpc/include/ipkdb.h @@ -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 index 00000000000..47b2863f8ad --- /dev/null +++ b/sys/arch/powerpc/include/irq.h @@ -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 index 00000000000..236ef30f43c --- /dev/null +++ b/sys/arch/powerpc/include/kcore.h @@ -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 index 00000000000..a19695b42c9 --- /dev/null +++ b/sys/arch/powerpc/include/limits.h @@ -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 index 00000000000..7df158ca14f --- /dev/null +++ b/sys/arch/powerpc/include/param.h @@ -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 +#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 index 00000000000..58bf6a4f8f1 --- /dev/null +++ b/sys/arch/powerpc/include/pcb.h @@ -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 index 00000000000..6452c044006 --- /dev/null +++ b/sys/arch/powerpc/include/pmap.h @@ -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 + +/* + * 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 index 00000000000..4276f92b943 --- /dev/null +++ b/sys/arch/powerpc/include/powerpc.h @@ -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 index 00000000000..019cc2a7d98 --- /dev/null +++ b/sys/arch/powerpc/include/proc.h @@ -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 index 00000000000..6e695ac70f7 --- /dev/null +++ b/sys/arch/powerpc/include/profile.h @@ -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 index 00000000000..0868899339c --- /dev/null +++ b/sys/arch/powerpc/include/psl.h @@ -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 index 00000000000..98314ee367f --- /dev/null +++ b/sys/arch/powerpc/include/pte.h @@ -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 + +/* + * 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 index 00000000000..210c56c2025 --- /dev/null +++ b/sys/arch/powerpc/include/reloc.h @@ -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 index 00000000000..39a1f62c9b5 --- /dev/null +++ b/sys/arch/powerpc/include/setjmp.h @@ -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 index 00000000000..7f573209ac3 --- /dev/null +++ b/sys/arch/powerpc/include/signal.h @@ -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 + +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 index 00000000000..1f88825b79b --- /dev/null +++ b/sys/arch/powerpc/include/stdarg.h @@ -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 + +#ifndef _STDARG_H +#define _STDARG_H +#endif +#include + +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 index 00000000000..3087a3ff90e --- /dev/null +++ b/sys/arch/powerpc/include/trap.h @@ -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 index 00000000000..0097cc04d5e --- /dev/null +++ b/sys/arch/powerpc/include/types.h @@ -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 + +#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 index 00000000000..24bb8de1242 --- /dev/null +++ b/sys/arch/powerpc/include/va-ppc.h @@ -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 index 00000000000..ee015e0500b --- /dev/null +++ b/sys/arch/powerpc/include/varargs.h @@ -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 +#include + +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 index 00000000000..3cf36e06aec --- /dev/null +++ b/sys/arch/powerpc/include/vmparam.h @@ -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 index 00000000000..d4665a9dec9 --- /dev/null +++ b/sys/arch/powerpc/powerpc/Locore.c @@ -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 +#include + +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 index 00000000000..2b874ea3f87 --- /dev/null +++ b/sys/arch/powerpc/powerpc/autoconf.c @@ -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 +#include +#include +#include +#include + +#include + +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 index 00000000000..42b5b428bf9 --- /dev/null +++ b/sys/arch/powerpc/powerpc/bcopy.c @@ -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 +/* +#include +*/ +#include + +/* + * 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 index 00000000000..07a9655710d --- /dev/null +++ b/sys/arch/powerpc/powerpc/clock.c @@ -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 +#include + +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 index 00000000000..ec1791e2e1b --- /dev/null +++ b/sys/arch/powerpc/powerpc/conf.c @@ -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 +#include +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +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 + +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 index 00000000000..e8a2ea46dff --- /dev/null +++ b/sys/arch/powerpc/powerpc/copyinstr.c @@ -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 +#include + +/* + * 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 index 00000000000..730f16a01d6 --- /dev/null +++ b/sys/arch/powerpc/powerpc/copyoutstr.c @@ -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 +#include + +/* + * 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 index 00000000000..0a5976d38ee --- /dev/null +++ b/sys/arch/powerpc/powerpc/copystr.c @@ -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 +#include + +/* + * 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 index 00000000000..c856ea93e5f --- /dev/null +++ b/sys/arch/powerpc/powerpc/db_disasm.c @@ -0,0 +1,857 @@ + +#include +#include +#include + +#include + +#include +#include +#include +#include + +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 index 00000000000..e4b187612e7 --- /dev/null +++ b/sys/arch/powerpc/powerpc/db_interface.c @@ -0,0 +1,13 @@ + +#include +#include + +#include +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 index 00000000000..e0a6c1f9ae1 --- /dev/null +++ b/sys/arch/powerpc/powerpc/db_memrw.c @@ -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 +#include + +#include + +#include + +#include + +/* + * 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 index 00000000000..0dcba16e250 --- /dev/null +++ b/sys/arch/powerpc/powerpc/db_trace.c @@ -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 +#include + +#include + +#include +#include +#include + +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 index 00000000000..23a9969ad82 --- /dev/null +++ b/sys/arch/powerpc/powerpc/disksubr.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 index 00000000000..46e723d9370 --- /dev/null +++ b/sys/arch/powerpc/powerpc/fpu.c @@ -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 +#include +#include + +#include +#include + +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 index 00000000000..e19219fb983 --- /dev/null +++ b/sys/arch/powerpc/powerpc/fubyte.c @@ -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 index 00000000000..e97f743446d --- /dev/null +++ b/sys/arch/powerpc/powerpc/fuswintr.c @@ -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 index 00000000000..2b357d80dc3 --- /dev/null +++ b/sys/arch/powerpc/powerpc/genassym.c @@ -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 + +#include +#include +#include + +#include +#include + +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 index 00000000000..8992b3c7f56 --- /dev/null +++ b/sys/arch/powerpc/powerpc/in_cksum.c @@ -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 +#include + +/* + * 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 index 00000000000..a425049774e --- /dev/null +++ b/sys/arch/powerpc/powerpc/locore.S @@ -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 + +#include +#include +#include +#include +#include + +/* + * 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 + + +/* + * 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 + + +/* + * 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 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 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 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 index 00000000000..3dd3c98f7db --- /dev/null +++ b/sys/arch/powerpc/powerpc/machdep.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +/* + * 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 index 00000000000..d2e72b43e2a --- /dev/null +++ b/sys/arch/powerpc/powerpc/mem.c @@ -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 +#include +#include +#include +#include +#include + +#include + +/*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 index 00000000000..7dc784bcaeb --- /dev/null +++ b/sys/arch/powerpc/powerpc/ofw_machdep.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if defined(FFS) && defined(CD9660) +#include +#endif + +#include + +#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 index 00000000000..fa16ebec2f2 --- /dev/null +++ b/sys/arch/powerpc/powerpc/ofwreal.S @@ -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 +#include +#include + +#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 index 00000000000..e282c09cbb1 --- /dev/null +++ b/sys/arch/powerpc/powerpc/openfirm.c @@ -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 + +#include +#include + +#include + +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 index 00000000000..2ff4e0c2f36 --- /dev/null +++ b/sys/arch/powerpc/powerpc/pmap.c @@ -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 +#include +#include +#include + +#include +#include + +#include +#include + +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 index 00000000000..ab956e42c22 --- /dev/null +++ b/sys/arch/powerpc/powerpc/process_machdep.c @@ -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 +#include + +/* + * 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 index 00000000000..814136c7237 --- /dev/null +++ b/sys/arch/powerpc/powerpc/random.c @@ -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 + + .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 index 00000000000..022e4588e82 --- /dev/null +++ b/sys/arch/powerpc/powerpc/setjmp.S @@ -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 index 00000000000..df71a0cdbac --- /dev/null +++ b/sys/arch/powerpc/powerpc/subyte.c @@ -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 index 00000000000..87066604db8 --- /dev/null +++ b/sys/arch/powerpc/powerpc/suswintr.c @@ -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 index 00000000000..a4ba796d61a --- /dev/null +++ b/sys/arch/powerpc/powerpc/suword.c @@ -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 index 00000000000..a22c2d9638c --- /dev/null +++ b/sys/arch/powerpc/powerpc/swapgeneric.c @@ -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 +#include + +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 index 00000000000..653ce49acc9 --- /dev/null +++ b/sys/arch/powerpc/powerpc/sys_machdep.c @@ -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 + +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 index 00000000000..d09927293f5 --- /dev/null +++ b/sys/arch/powerpc/powerpc/trap.c @@ -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 +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +/* 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 index 00000000000..caf77563d91 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 index 00000000000..7a27d8dfc9f --- /dev/null +++ b/sys/arch/powerpc/powerpc/vm_machdep.c @@ -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 +#include +#include +#include +#include +#include + +#include +#include + +#include + +/* + * 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 index 00000000000..97b5070da65 --- /dev/null +++ b/sys/arch/powerpc/stand/Locore.c @@ -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 +#include + +#include + +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 index 00000000000..7a6614411ba --- /dev/null +++ b/sys/arch/powerpc/stand/Makefile @@ -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 +.include diff --git a/sys/arch/powerpc/stand/Makefile.inc b/sys/arch/powerpc/stand/Makefile.inc new file mode 100644 index 00000000000..6ea10deb092 --- /dev/null +++ b/sys/arch/powerpc/stand/Makefile.inc @@ -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 index 00000000000..3ad956fa164 --- /dev/null +++ b/sys/arch/powerpc/stand/alloc.c @@ -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 + +#include +#include + +/* + * 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 index 00000000000..df2969debc3 --- /dev/null +++ b/sys/arch/powerpc/stand/boot.c @@ -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 + +#include +#include +#include + +#include +#include + +#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 index 00000000000..d593771d01e --- /dev/null +++ b/sys/arch/powerpc/stand/boot/Makefile @@ -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 diff --git a/sys/arch/powerpc/stand/net.c b/sys/arch/powerpc/stand/net.c new file mode 100644 index 00000000000..d78e8e9d657 --- /dev/null +++ b/sys/arch/powerpc/stand/net.c @@ -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 +#include +#include +#include +#include +#include + +#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 index 00000000000..11fce71f85e --- /dev/null +++ b/sys/arch/powerpc/stand/netif_of.c @@ -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 +#include +#include +#include + +#include + +#include +#include +#include + +#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 index 00000000000..e1868ae8cb4 --- /dev/null +++ b/sys/arch/powerpc/stand/ofdev.c @@ -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 +#include +#include + +#include +#include +#include +#include + +#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 index 00000000000..d6e0d5231aa --- /dev/null +++ b/sys/arch/powerpc/stand/ofdev.h @@ -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 index 00000000000..e0f1ab1e923 --- /dev/null +++ b/sys/arch/powerpc/stand/openfirm.h @@ -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 +#include + +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)); +