diff -u --recursive --new-file pre2.0.7/linux/CREDITS linux/CREDITS
--- pre2.0.7/linux/CREDITS	Tue May 21 19:52:30 1996
+++ linux/CREDITS	Mon May 27 14:38:56 1996
@@ -163,6 +163,12 @@
 S: Amsterdam
 S: The Netherlands
 
+N: Ray Burr
+E: ryb@nightmare.com
+D: Original author of Amiga FFS filesystem
+S: Orlando, Florida
+S: USA
+
 N: Michael Callahan
 E: callahan@maths.ox.ac.uk
 D: PPP for Linux
@@ -518,7 +524,8 @@
 D: Selection mechanism
 
 N: Jochen Hein
-E: Hein@Informatik.TU-Clausthal.de
+E: jochen.hein@informatik.tu-clausthal.de
+P: 1024/4A27F015 25 72 FB E3 85 9F DE 3B  CB 0A DA DA 40 77 05 6C
 D: National Language Support
 D: German Support-Disks for SLS/Slackware called SLT
 D: Linux Internationalization Project
@@ -830,7 +837,7 @@
 N: Kevin E. Martin
 E: martin@cs.unc.edu
 D: Developed original accelerated X servers included in XFree86
-D: XF86_Mach64 (forthcoming -- please don't ask when)
+D: XF86_Mach64
 D: XF86_Mach32
 D: XF86_Mach8
 D: XF86_8514
diff -u --recursive --new-file pre2.0.7/linux/Documentation/Changes linux/Documentation/Changes
--- pre2.0.7/linux/Documentation/Changes	Tue May 21 19:52:30 1996
+++ linux/Documentation/Changes	Mon May 27 12:55:59 1996
@@ -373,12 +373,12 @@
 
 nfsd daemon doesn't work anymore
 ================================
-   The RedHat distribution 2.x and 3.x have a bug that they do
-route add -net 127.0.0.1 at startup. That is wrong. Correct is 
-route add -net 127.0.0.0. 
+   The Red Hat distributions 2.x, 3.x and Caldera 1.0 have a bug where
+they do "route add -net 127.0.0.1" at startup.  That is wrong.  The
+correct command is "route add -net 127.0.0.0". 
 
-Workaround: Change in /etc/sysconfig/network-scripts/ifcup-lo
-the "route add -net ${IPADDR}" into "route add -net 127.0.0.0"
+Workaround: Change in "/etc/sysconfig/network-scripts/ifup-lo" the
+"route add -net ${IPADDR}" into "route add -net 127.0.0.0".
   
 How to know the version of the installed programs
 *************************************************
diff -u --recursive --new-file pre2.0.7/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- pre2.0.7/linux/Documentation/Configure.help	Tue May 21 19:52:31 1996
+++ linux/Documentation/Configure.help	Mon May 27 12:10:24 1996
@@ -1086,7 +1086,7 @@
   use a low speed TNC (a Terminal Node Controller acts as a kind of
   modem connecting your computer's serial port to your radio's
   microphone input and speaker output) supporting the KISS protocol or
-  the various SCC cards that are supported by the Ottowa PI, the
+  the various SCC cards that are supported by the Ottawa PI, the
   Gracilis Packetwin and the generic Z8530 driver. Another option are
   the Baycom modem serial and parallel port hacks (supported by their
   own driver) and the other baycom cards (SCC) (supported by the Z8530
@@ -3511,7 +3511,7 @@
 /dev/dsp and /dev/audio support
 CONFIG_AUDIO
   Answering N disables /dev/dsp and /dev/audio, the A/D and D/A
-  converter devices.  Answer Y only if you know you will not need
+  converter devices.  Answer N only if you know you will not need
   the option.  They are usually required.  Answer Y.
 
 MIDI interface support
diff -u --recursive --new-file pre2.0.7/linux/Documentation/networking/arcnet.txt linux/Documentation/networking/arcnet.txt
--- pre2.0.7/linux/Documentation/networking/arcnet.txt	Thu Feb 15 09:21:15 1996
+++ linux/Documentation/networking/arcnet.txt	Mon May 27 14:22:44 1996
@@ -55,13 +55,8 @@
 Where do I discuss these drivers?
 ---------------------------------
 
-HEY!! - the linux-arcnet@807-city.on.ca mailing list is now so unstable
-that I can't recommend people even bother with it.  I no longer have an
-account on 807-CITY (though they still graciously forward my mail to me) so
-there's not much I can do.
-
-However, Tomasz Motylewski has been so kind as to set up a new and improved
-mailing list; subscribe by sending a message with the BODY "subscribe
+Tomasz Motylewski has been so kind as to set up a new and improved
+mailing list.  Subscribe by sending a message with the BODY "subscribe
 linux-arcnet YOUR REAL NAME" to listserv@tichy.ch.uj.edu.pl.  Then, to
 submit messages to the list, mail to linux-arcnet@tichy.ch.uj.edu.pl.
 
@@ -208,16 +203,19 @@
 	you're completely insane, and/or you need to build some kind of
 	hybrid network that uses both encapsulation types.
 
-OS2: Has not been tested.  The "correct" solution would be to buy either of
-	IBM's "TCP/IP for OS/2" or "Warp Connect" packages.  However,
-	ftp.microsoft.com also has a freeware Lan Manager for OS/2 client
+OS2: I've been told it works under Warp Connect with an ARCnet driver from
+	SMC.  You need to use the 'arc0e' interface for this.  If you get
+	the SMC driver to work with the TCP/IP stuff included in the
+	"normal" Warp Bonus Pack, let me know.
+
+	ftp.microsoft.com also has a freeware "Lan Manager for OS/2" client
 	which should use the same protocol as WfWg does.  I had no luck
 	installing it under Warp, however.  Please mail me with any results.
 
 NetBSD/AmiTCP: These use an old version of the Internet standard ARCnet
 	protocol (RFC1051) which is compatible with the Linux driver v2.10
 	ALPHA and above using the arc0s device. (See "Multiprotocol ARCnet"
-	below.)
+	below.)  ** Newer versions of NetBSD apparently support RFC1201.
 
 
 Using Multiprotocol ARCnet
@@ -281,14 +279,14 @@
    If you need only arc0, then the following commands should get you going:
    	ifconfig arc0 MY.IP.ADD.RESS
    	route add MY.IP.ADD.RESS arc0
-   	route add SUB.NET.ADD.RESS arc0
+   	route add -net SUB.NET.ADD.RESS arc0
    	[add other local routes here]
    	
    If you need arc0e (and only arc0e), it's a little different:
    	ifconfig arc0 MY.IP.ADD.RESS
    	ifconfig arc0e MY.IP.ADD.RESS
    	route add MY.IP.ADD.RESS arc0e
-   	route add SUB.NET.ADD.RESS arc0e
+   	route add -net SUB.NET.ADD.RESS arc0e
    
    arc0s works much the same way as arc0e.
 
diff -u --recursive --new-file pre2.0.7/linux/Makefile linux/Makefile
--- pre2.0.7/linux/Makefile	Tue May 21 19:52:31 1996
+++ linux/Makefile	Mon May 27 15:31:14 1996
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 99
-SUBLEVEL = 7
+SUBLEVEL = 8
 
 ARCH = i386
 
@@ -225,7 +225,7 @@
 	 else \
 	   echo \#define LINUX_COMPILE_DOMAIN ; \
 	 fi >> .ver
-	@echo \#define LINUX_COMPILER \"`$(HOSTCC) -v 2>&1 | tail -1`\" >> .ver
+	@echo \#define LINUX_COMPILER \"`$(CC) -v 2>&1 | tail -1`\" >> .ver
 	@mv -f .ver $@
 
 include/linux/version.h: ./Makefile
diff -u --recursive --new-file pre2.0.7/linux/arch/m68k/amiga/cyberfb.c linux/arch/m68k/amiga/cyberfb.c
--- pre2.0.7/linux/arch/m68k/amiga/cyberfb.c	Tue May 21 19:52:31 1996
+++ linux/arch/m68k/amiga/cyberfb.c	Tue May 21 19:51:42 1996
@@ -565,7 +565,7 @@
 
 
    /*
-    *    (Unb)Blank the screen
+    *    (Un)Blank the screen
     */
 
 void Cyber_blank(int blank)
@@ -663,7 +663,7 @@
 }
 
 /**************************************************************
- * Rectange Fill Solid
+ * Rectangle Fill Solid
  */
 void Cyber_RectFill (u_short x, u_short y, u_short width, u_short height,
                      u_short mode, u_short color)
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/Makefile linux/arch/ppc/Makefile
--- pre2.0.7/linux/arch/ppc/Makefile	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/Makefile	Mon May 27 12:00:57 1996
@@ -12,28 +12,29 @@
 #
 # Copyright (C) 1994 by Linus Torvalds
 # Changes for PPC by Gary Thomas
-# Modified by Cort Dougan
 #
+
 # PowerPC (cross) tools
-AS		= /usr/local/bin/as.ppc
-ASFLAGS		= 
-LD		= /u/cort/ppc-gcc/bin/ld.ppc
+AS		= as.ppc
+ASFLAGS		=
+LD		= ld.ppc
 #LINKFLAGS	= -T arch/ppc/ld.script -Ttext 0x90000000 -Map vmlinux.map
-LINKFLAGS	= -T arch/ppc/ld.script -Ttext 0x90000000 
+LINKFLAGS	= -T arch/ppc/ld.script -Ttext 0x90000000
 HOSTCC		= gcc
-CC		= /usr/local/bin/gcc.ppc 
+CC		= cc.ppc
 CFLAGS		= -D__KERNEL__ -I$(TOPDIR)/include \
-		-Wstrict-prototypes \
+		-Wall -Wstrict-prototypes \
+		-msoft-float \
 		-fomit-frame-pointer \
 		-fno-builtin \
 		-finhibit-size-directive \
-		-O2 -pipe
-#-Wall
+		-fsigned-char \
+		-O2
 CPP		= $(CC) -E $(CFLAGS)
-AR		= /u/cort/ppc-gcc/bin/ar.ppc
-RANLIB		= /u/cort/ppc-gcc/bin/ranlib.ppc
-STRIP		= /u/cort/ppc-gcc/bin/strip.ppc
-NM		= /u/cort/ppc-gcc/bin/nm.ppc
+AR		= ar.ppc
+RANLIB		= ranlib.ppc
+STRIP		= strip.ppc
+NM		= nm.ppc
 
 #
 # Set these to indicate how to link it..
@@ -61,19 +62,11 @@
 
 HEAD := arch/ppc/kernel/head.o
 
-ARCH_SUBDIRS = arch/ppc/kernel arch/ppc/mm
+ARCH_SUBDIRS = arch/ppc/kernel arch/ppc/mm arch/ppc/lib
 SUBDIRS := $(SUBDIRS) $(ARCH_SUBDIRS)
-ARCHIVES := arch/ppc/kernel/kernel.o arch/ppc/mm/mm.o $(ARCHIVES)
-
-## ifdef CONFIG_IBCS
-## SUBDIRS := $(SUBDIRS) arch/ppc/ibcs
-## DRIVERS := $(DRIVERS) arch/ppc/ibcs/ibcs.o
-## endif
-
-## ifdef CONFIG_MATH_EMULATION
-## SUBDIRS := $(SUBDIRS) arch/ppc/math-emu
-## DRIVERS := $(DRIVERS) arch/ppc/math-emu/math.a
-## endif
+ARCHIVES := arch/ppc/kernel/kernel.o arch/ppc/mm/mm.o arch/ppc/lib/lib.o $(ARCHIVES)
+NO_RD_ARCHIVES := arch/ppc/kernel/no_ramdisk.o $(ARCHIVES)
+ARCHIVES := arch/ppc/kernel/ramdisk.o $(ARCHIVES)
 
 arch/ppc/kernel: dummy
 	$(MAKE) linuxsubdirs SUBDIRS=arch/ppc/kernel
@@ -81,28 +74,44 @@
 arch/ppc/mm: dummy
 	$(MAKE) linuxsubdirs SUBDIRS=arch/ppc/mm
 
-## MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
-## 
-## zImage: vmlinux
-## 	@$(MAKEBOOT) zImage
+arch/ppc/lib: dummy
+	$(MAKE) linuxsubdirs SUBDIRS=arch/ppc/lib
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+vmlinux.no_ramdisk: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
+	$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o \
+		$(NO_RD_ARCHIVES) \
+		$(FILESYSTEMS) \
+		$(DRIVERS) \
+		$(LIBS) -o vmlinux.no_ramdisk
+
 ## 
+zImage: vmlinux
+	@$(MAKEBOOT) zImage
+
+tImage: vmlinux
+	@$(MAKEBOOT) tImage
+
+bImage: vmlinux.no_ramdisk
+	@$(MAKEBOOT) bImage
+
+bdisk: vmlinux.no_ramdisk
+	@$(MAKEBOOT) bdisk
+
 ## compressed: zImage
 ## 
 ## zlilo: vmlinux
 ## 	@$(MAKEBOOT) zlilo
 ## 
-## zdisk: vmlinux
-## 	@$(MAKEBOOT) zdisk
-## 
+zdisk: vmlinux
+	@$(MAKEBOOT) zdisk
+ 
 ## install: vmlinux
 ## 	@$(MAKEBOOT) install
 
 archclean:
-#	@$(MAKEBOOT) clean
-	/bin/rm -f arch/ppc/kernel/*.o arch/ppc/kernel/mk_defs arch/ppc/kernel/ppc_defs.h mm/*.o
-	/bin/rm -f arch/ppc/kernel/*~ arch/ppc/kernel/*~      
+	@$(MAKEBOOT) clean
 
 archdep:
 #	@$(MAKEBOOT) dep
-
-
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/boot/Makefile linux/arch/ppc/boot/Makefile
--- pre2.0.7/linux/arch/ppc/boot/Makefile	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/boot/Makefile	Mon May 27 12:00:57 1996
@@ -24,14 +24,48 @@
 
 all:	linux.boot
 
-linux.boot: $(TOPDIR)/vmlinux mkboot
-	mkboot $(TOPDIR)/vmlinux /u/cort/bootpd/vmlinux
+#zImage: $(CONFIGURE) bootsect setup compressed/vmlinux tools/build
+zImage: compressed/vmlinux mk_type41
+	mkboot compressed/vmlinux vmlinux 0
+	mk_type41 vmlinux zImage
+	cp compressed/vmlinux zBoot
+	rm -f vmlinux compressed/vmlinux
 
-mkboot : cortstrip.c
-	$(HOSTCC) -o mkboot cortstrip.c
+zdisk: zImage
+	dd if=zImage of=/dev/fd0 bs=36b	
 
+compressed/vmlinux: $(TOPDIR)/vmlinux
+	@$(MAKE) -C compressed vmlinux
+
+tImage: mk_type41 $(TOPDIR)/vmlinux
+	mkboot $(TOPDIR)/vmlinux vmlinux 0
+	mk_type41 vmlinux tImage
+	rm -f vmlinux
+
+bImage: mk_type41 $(TOPDIR)/vmlinux.no_ramdisk
+	mkboot $(TOPDIR)/vmlinux.no_ramdisk vmlinux 0
+	mk_type41 vmlinux bImage
+	rm -f vmlinux
+
+xImage: compressed/vmlinux.no_ramdisk
+	mkboot compressed/vmlinux.no_ramdisk vmlinux 0
+	mk_type41 vmlinux xImage
+	rm -f vmlinux compressed/vmlinux.no_ramdisk
+
+compressed/vmlinux.no_ramdisk: $(TOPDIR)/vmlinux.no_ramdisk
+	@$(MAKE) -C compressed vmlinux.no_ramdisk
+
+bdisk: xImage
+	dd if=xImage of=/dev/fd0 bs=36b
+	
+linux.boot: $(TOPDIR)/vmlinux
+	mkboot $(TOPDIR)/vmlinux $@ 0
+
+mk_type41: mk_type41.c
+	cc -o mk_type41 mk_type41.c
+	
 clean:
 	rm -f linux.boot 
 
 dep:
-
+fastdep:
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/boot/compressed/Makefile linux/arch/ppc/boot/compressed/Makefile
--- pre2.0.7/linux/arch/ppc/boot/compressed/Makefile	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/boot/compressed/Makefile	Mon May 27 12:00:57 1996
@@ -0,0 +1,53 @@
+#
+# linux/arch/i386/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+TOPDIR = ../../../..
+CC = cc.ppc
+AS = as.ppc
+LD = ld.ppc
+ZLINKFLAGS = -T ../../ld.script -Ttext 0x00400000
+HOSTCC = cc
+#GZIP_FLAGS = -9
+GZIP_FLAGS =
+
+HEAD = head.o
+SYSTEM = $(TOPDIR)/vmlinux
+
+OBJECTS = $(HEAD) inflate.o unzip.o misc.o
+
+CFLAGS = -O2 -DSTDC_HEADERS
+
+.c.s:
+	$(CC) $(CFLAGS) -S $<
+.s.o:
+	$(AS) -o $*.o $<
+.c.o:
+	$(CC) $(CFLAGS) -c $<
+
+all: vmlinux
+
+vmlinux: $(OBJECTS) $(SYSTEM) piggyback
+	mkboot $(TOPDIR)/vmlinux xx_boot 0
+	gzip ${GZIP_FLAGS} <xx_boot | ./piggyback | $(AS) -o piggy.o
+	$(LD) $(ZLINKFLAGS) -o vmlinux $(OBJECTS) piggy.o
+	rm -f piggy.o xx_boot
+
+vmlinux.no_ramdisk: $(OBJECTS) piggyback
+	mkboot $(TOPDIR)/vmlinux.no_ramdisk xx_boot 0
+	gzip ${GZIP_FLAGS} <xx_boot | ./piggyback | $(AS) -o piggy.o
+	$(LD) $(ZLINKFLAGS) -o vmlinux.no_ramdisk $(OBJECTS) piggy.o
+	rm -f piggy.o xx_boot
+
+head.o:	head.s
+
+head.s: head.S $(TOPDIR)/include/linux/tasks.h
+	$(CPP) -traditional head.S -o head.s
+
+piggyback: piggyback.c
+	$(HOSTCC) $(CFLAGS) -o piggyback piggyback.c
+
+clean:
+	rm -f piggyback vmlinux
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/boot/compressed/crypt.h linux/arch/ppc/boot/compressed/crypt.h
--- pre2.0.7/linux/arch/ppc/boot/compressed/crypt.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/boot/compressed/crypt.h	Mon May 27 12:00:57 1996
@@ -0,0 +1,12 @@
+/* crypt.h (dummy version) -- do not perform encryption
+ * Hardly worth copyrighting :-)
+ */
+
+#ifdef CRYPT
+#  undef CRYPT      /* dummy version */
+#endif
+
+#define RAND_HEAD_LEN  12  /* length of encryption random header */
+
+#define zencode
+#define zdecode
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/boot/compressed/gzip.h linux/arch/ppc/boot/compressed/gzip.h
--- pre2.0.7/linux/arch/ppc/boot/compressed/gzip.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/boot/compressed/gzip.h	Mon May 27 12:00:57 1996
@@ -0,0 +1,284 @@
+/* gzip.h -- common declarations for all gzip modules
+ * Copyright (C) 1992-1993 Jean-loup Gailly.
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License, see the file COPYING.
+ */
+
+#if defined(__STDC__) || defined(PROTO)
+#  define OF(args)  args
+#else
+#  define OF(args)  ()
+#endif
+
+#ifdef __STDC__
+   typedef void *voidp;
+#else
+   typedef char *voidp;
+#endif
+
+/* I don't like nested includes, but the string functions are used too often */
+#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
+#  include <string.h>
+#  define memzero(s, n)     memset ((s), 0, (n))
+#else
+#  include <strings.h>
+#  define strchr            index 
+#  define strrchr           rindex
+#  define memcpy(d, s, n)   bcopy((s), (d), (n)) 
+#  define memcmp(s1, s2, n) bcmp((s1), (s2), (n)) 
+#  define memzero(s, n)     bzero((s), (n))
+#endif
+
+#if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H)
+#  include <memory.h>
+#endif
+
+#ifndef RETSIGTYPE
+#  define RETSIGTYPE void
+#endif
+
+#define local static
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+/* Return codes from gzip */
+#define OK      0
+#define ERROR   1
+#define WARNING 2
+
+/* Compression methods (see algorithm.doc) */
+#define STORED     0
+#define COMPRESSED 1
+#define PACKED     2
+/* methods 3 to 7 reserved */
+#define DEFLATED   8
+extern int method;         /* compression method */
+
+/* To save memory for 16 bit systems, some arrays are overlayed between
+ * the various modules:
+ * deflate:  prev+head   window      d_buf  l_buf  outbuf
+ * unlzw:    tab_prefix  tab_suffix  stack  inbuf  outbuf
+ * inflate:              window             inbuf
+ * unpack:               window             inbuf
+ * For compression, input is done in window[]. For decompression, output
+ * is done in window except for unlzw.
+ */
+
+#ifndef	INBUFSIZ
+#  define INBUFSIZ  0x8000  /* input buffer size */
+#endif
+#define INBUF_EXTRA  64     /* required by unlzw() */
+
+#ifndef	OUTBUFSIZ
+#  define OUTBUFSIZ  16384  /* output buffer size */
+#endif
+#define OUTBUF_EXTRA 2048   /* required by unlzw() */
+
+#define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */
+
+#ifdef DYN_ALLOC
+#  define EXTERN(type, array)  extern type * near array
+#  define DECLARE(type, array, size)  type * near array
+#  define ALLOC(type, array, size) { \
+      array = (type*)fcalloc((unsigned)(((size)+1L)/2), 2*sizeof(type)); \
+      if (array == NULL) error("insufficient memory"); \
+   }
+#  define FREE(array) {if (array != NULL) fcfree(array), array=NULL;}
+#else
+#  define EXTERN(type, array)  extern type array[]
+#  define DECLARE(type, array, size)  type array[size]
+#  define ALLOC(type, array, size)
+#  define FREE(array)
+#endif
+
+EXTERN(uch, inbuf);          /* input buffer */
+EXTERN(uch, outbuf);         /* output buffer */
+EXTERN(ush, d_buf);          /* buffer for distances, see trees.c */
+EXTERN(uch, window);         /* Sliding window and suffix table (unlzw) */
+#define tab_suffix window
+#ifndef MAXSEG_64K
+#  define tab_prefix prev    /* hash link (see deflate.c) */
+#  define head (prev+WSIZE)  /* hash head (see deflate.c) */
+   EXTERN(ush, tab_prefix);  /* prefix code (see unlzw.c) */
+#else
+#  define tab_prefix0 prev
+#  define head tab_prefix1
+   EXTERN(ush, tab_prefix0); /* prefix for even codes */
+   EXTERN(ush, tab_prefix1); /* prefix for odd  codes */
+#endif
+
+extern unsigned insize; /* valid bytes in inbuf */
+extern unsigned inptr;  /* index of next byte to be processed in inbuf */
+extern unsigned outcnt; /* bytes in output buffer */
+
+extern long bytes_in;   /* number of input bytes */
+extern long bytes_out;  /* number of output bytes */
+extern long overhead;   /* number of bytes in gzip header */
+
+#define isize bytes_in
+/* for compatibility with old zip sources (to be cleaned) */
+
+extern int  ifd;        /* input file descriptor */
+extern int  ofd;        /* output file descriptor */
+extern char ifname[];   /* input filename or "stdin" */
+extern char ofname[];   /* output filename or "stdout" */
+
+extern ulg time_stamp;  /* original time stamp (modification time) */
+extern long ifile_size; /* input file size, -1 for devices (debug only) */
+
+extern int exit_code;   /* program exit code */
+
+typedef int file_t;     /* Do not use stdio */
+#define NO_FILE  (-1)   /* in memory compression */
+
+
+#define	GZIP_MAGIC     "\037\213" /* Magic header for gzip files, 1F 8B */
+#define	OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */
+#define	PKZIP_MAGIC  "PK\003\004" /* Magic header for pkzip files */
+#define	PACK_MAGIC     "\037\036" /* Magic header for packed files */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
+#define RESERVED     0xC0 /* bit 6,7:   reserved */
+
+/* internal file attribute */
+#define UNKNOWN (-1)
+#define BINARY  0
+#define ASCII   1
+
+#ifndef WSIZE
+#  define WSIZE 0x8000     /* window size--must be a power of two, and */
+#endif                     /*  at least 32K for zip's deflate method */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST  (WSIZE-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+extern int decrypt;        /* flag to turn on decryption */
+extern int save_orig_name; /* set if original name must be saved */
+extern int verbose;        /* be verbose (-v) */
+extern int level;          /* compression level */
+extern int test;           /* check .z file integrity */
+extern int to_stdout;      /* output to stdout (-c) */
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+
+/* put_byte is used for the compressed output, put_char for the
+ * uncompressed output. However unlzw() uses window for its
+ * suffix table instead of its output buffer, so it does not use put_char.
+ * (to be cleaned up).
+ */
+#define put_byte(c) {outbuf[outcnt++]=(uch)(c); if (outcnt==OUTBUFSIZ)\
+   flush_outbuf();}
+#define put_char(c) {window[outcnt++]=(uch)(c); if (outcnt==WSIZE)\
+   flush_window();}
+
+/* Output a 16 bit value, lsb first */
+#define put_short(w) \
+{ if (outcnt < OUTBUFSIZ-2) { \
+    outbuf[outcnt++] = (uch) ((w) & 0xff); \
+    outbuf[outcnt++] = (uch) ((ush)(w) >> 8); \
+  } else { \
+    put_byte((uch)((w) & 0xff)); \
+    put_byte((uch)((ush)(w) >> 8)); \
+  } \
+}
+
+/* Output a 32 bit value to the bit stream, lsb first */
+#define put_long(n) { \
+    put_short((n) & 0xffff); \
+    put_short(((ulg)(n)) >> 16); \
+}
+
+#define seekable()    0  /* force sequential output */
+#define translate_eol 0  /* no option -a yet */
+
+#define tolow(c)  (isupper(c) ? (c)-'A'+'a' : (c))    /* force to lower case */
+
+/* Macros for getting two-byte and four-byte header values */
+#define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8))
+#define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16))
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond,msg) {if(!(cond)) error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+	/* in zip.c: */
+extern void zip    OF((int in, int out));
+extern int file_read  OF((char *buf,  unsigned size));
+
+	/* in unzip.c */
+extern void unzip        OF((int in, int out));
+extern int check_zipfile OF((int in));
+
+	/* in unpack.c */
+extern void unpack        OF((int in, int out));
+
+	/* in gzip.c */
+RETSIGTYPE abort_gzip   OF((void));
+
+        /* in deflate.c */
+void lm_init OF((int pack_level, ush *flags));
+ulg  deflate OF((void));
+
+        /* in trees.c */
+void ct_init     OF((ush *attr, int *method));
+int  ct_tally    OF((int dist, int lc));
+ulg  flush_block OF((char *buf, ulg stored_len, int eof));
+
+        /* in bits.c */
+void     bi_init    OF((file_t zipfile));
+void     send_bits  OF((int value, int length));
+unsigned bi_reverse OF((unsigned value, int length));
+void     bi_windup  OF((void));
+void     copy_block OF((char *buf, unsigned len, int header));
+extern   int (*read_buf) OF((char *buf, unsigned size));
+
+	/* in util.c: */
+extern ulg  updcrc        OF((uch *s, unsigned n));
+extern void clear_bufs    OF((void));
+extern int  fill_inbuf    OF((void));
+extern void flush_outbuf  OF((void));
+extern void flush_window  OF((void));
+extern char *strlwr       OF((char *s));
+extern char *basename     OF((char *fname));
+extern char *add_envopt   OF((int *argcp, char ***argvp, char *env));
+extern void error         OF((char *m));
+extern void warn          OF((char *a, char *b));
+extern void read_error    OF((void));
+extern void write_error   OF((void));
+extern void display_ratio OF((long num, long den));
+extern voidp xmalloc      OF((unsigned int size));
+
+	/* in inflate.c */
+extern int inflate OF((void));
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/boot/compressed/head.S linux/arch/ppc/boot/compressed/head.S
--- pre2.0.7/linux/arch/ppc/boot/compressed/head.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/boot/compressed/head.S	Mon May 27 12:00:57 1996
@@ -0,0 +1,33 @@
+#include "ppc_defs.h"
+
+	.text
+/*
+ * This code may be executed by a bootstrap process.  If so, the
+ * purpose is to relocate the loaded image to it's final location
+ * in memory.
+ *    R3: End of image
+ *    R4: Start of image - 0x400
+ *
+ */
+	.globl	start
+start:
+	addi	r4,r4,0x400	/* Point at start of image */
+	lis	r5,start@h	/* Load address */
+	ori	r5,r5,start@l
+	subi	r4,r4,4		/* Adjust for auto-increment */
+	subi	r5,r5,4
+	subi	r3,r3,4
+00:	lwzu	r0,4(r4)	/* Fast move */
+	stwu	r0,4(r5)
+	cmp	0,r3,r4
+	bne	00b
+	lis	r5,continue@h	/* Actual code starts here */
+	ori	r5,r5,continue@l
+	mtlr	r5
+	blr
+
+continue:
+	bl	decompress_kernel
+	li	r5,0x100	/* Kernel code starts here */
+	mtlr	r5
+	blr	
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/boot/compressed/inflate.c linux/arch/ppc/boot/compressed/inflate.c
--- pre2.0.7/linux/arch/ppc/boot/compressed/inflate.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/boot/compressed/inflate.c	Mon May 27 12:00:57 1996
@@ -0,0 +1,810 @@
+#define DEBG(x)
+#define DEBG1(x)
+/* inflate.c -- Not copyrighted 1992 by Mark Adler
+   version c10p1, 10 January 1993 */
+
+/* 
+ * Adapted for booting Linux by Hannu Savolainen 1993
+ * based on gzip-1.0.3 
+ */
+
+#ifndef lint
+static char rcsid[] = "$Id: inflate.c,v 0.10 1993/02/04 13:21:06 jloup Exp $";
+#endif
+
+#include "gzip.h"
+#define slide window
+
+#if defined(STDC_HEADERS) || defined(HAVE_STDLIB_H)
+#  include <sys/types.h>
+#  include <stdlib.h>
+#endif
+
+struct huft {
+  uch e;                /* number of extra bits or operation */
+  uch b;                /* number of bits in this code or subcode */
+  union {
+    ush n;              /* literal, length base, or distance base */
+    struct huft *t;     /* pointer to next level of table */
+  } v;
+};
+
+
+/* Function prototypes */
+int huft_build OF((unsigned *, unsigned, unsigned, ush *, ush *,
+                   struct huft **, int *));
+int huft_free OF((struct huft *));
+int inflate_codes OF((struct huft *, struct huft *, int, int));
+int inflate_stored OF((void));
+int inflate_fixed OF((void));
+int inflate_dynamic OF((void));
+int inflate_block OF((int *));
+int inflate OF((void));
+
+
+#define wp outcnt
+#define flush_output(w) (wp=(w),flush_window())
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+static unsigned border[] = {    /* Order of the bit length code lengths */
+        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+static ush cplens[] = {         /* Copy lengths for literal codes 257..285 */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+        /* note: see note #13 above about the 258 in this list. */
+static ush cplext[] = {         /* Extra bits for literal codes 257..285 */
+        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */
+static ush cpdist[] = {         /* Copy offsets for distance codes 0..29 */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577};
+static ush cpdext[] = {         /* Extra bits for distance codes */
+        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+        12, 12, 13, 13};
+
+
+ulg bb;                         /* bit buffer */
+unsigned bk;                    /* bits in bit buffer */
+
+ush mask_bits[] = {
+    0x0000,
+    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+#ifdef CRYPT
+  uch cc;
+#  define NEXTBYTE() \
+     (decrypt ? (cc = get_byte(), zdecode(cc), cc) : get_byte())
+#else
+#  define NEXTBYTE()  (uch)get_byte()
+#endif
+#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}}
+#define DUMPBITS(n) {b>>=(n);k-=(n);}
+
+int lbits = 9;          /* bits in base literal/length lookup table */
+int dbits = 6;          /* bits in base distance lookup table */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
+#define BMAX 16         /* maximum bit length of any code (16 for explode) */
+#define N_MAX 288       /* maximum number of codes in any set */
+
+
+unsigned hufts;         /* track memory usage */
+
+
+int huft_build(b, n, s, d, e, t, m)
+unsigned *b;            /* code lengths in bits (all assumed <= BMAX) */
+unsigned n;             /* number of codes (assumed <= N_MAX) */
+unsigned s;             /* number of simple-valued codes (0..s-1) */
+ush *d;                 /* list of base values for non-simple codes */
+ush *e;                 /* list of extra bits for non-simple codes */
+struct huft **t;        /* result: starting table */
+int *m;                 /* maximum lookup bits, returns actual */
+/* Given a list of code lengths and a maximum table size, make a set of
+   tables to decode that set of codes.  Return zero on success, one if
+   the given code set is incomplete (the tables are still built in this
+   case), two if the input is invalid (all zero length codes or an
+   oversubscribed set of lengths), and three if not enough memory. */
+{
+  unsigned a;                   /* counter for codes of length k */
+  unsigned c[BMAX+1];           /* bit length count table */
+  unsigned f;                   /* i repeats in table every f entries */
+  int g;                        /* maximum code length */
+  int h;                        /* table level */
+  register unsigned i;          /* counter, current code */
+  register unsigned j;          /* counter */
+  register int k;               /* number of bits in current code */
+  int l;                        /* bits per table (returned in m) */
+  register unsigned *p;         /* pointer into c[], b[], or v[] */
+  register struct huft *q;      /* points to current table */
+  struct huft r;                /* table entry for structure assignment */
+  struct huft *u[BMAX];         /* table stack */
+  unsigned v[N_MAX];            /* values in order of bit length */
+  register int w;               /* bits before this table == (l * h) */
+  unsigned x[BMAX+1];           /* bit offsets, then code stack */
+  unsigned *xp;                 /* pointer into x */
+  int y;                        /* number of dummy codes added */
+  unsigned z;                   /* number of entries in current table */
+
+DEBG("huft1 ");
+
+  /* Generate counts for each bit length */
+  memzero(c, sizeof(c));
+  p = b;  i = n;
+  do {
+    c[*p++]++;                  /* assume all entries <= BMAX */
+  } while (--i);
+  if (c[0] == n)                /* null input--all zero length codes */
+  {
+    *t = (struct huft *)NULL;
+    *m = 0;
+    return 0;
+  }
+
+DEBG("huft2 ");
+
+  /* Find minimum and maximum length, bound *m by those */
+  l = *m;
+  for (j = 1; j <= BMAX; j++)
+    if (c[j])
+      break;
+  k = j;                        /* minimum code length */
+  if ((unsigned)l < j)
+    l = j;
+  for (i = BMAX; i; i--)
+    if (c[i])
+      break;
+  g = i;                        /* maximum code length */
+  if ((unsigned)l > i)
+    l = i;
+  *m = l;
+
+DEBG("huft3 ");
+
+  /* Adjust last length count to fill out codes, if needed */
+  for (y = 1 << j; j < i; j++, y <<= 1)
+    if ((y -= c[j]) < 0)
+      return 2;                 /* bad input: more codes than bits */
+  if ((y -= c[i]) < 0)
+    return 2;
+  c[i] += y;
+
+DEBG("huft4 ");
+
+  /* Generate starting offsets into the value table for each length */
+  x[1] = j = 0;
+  p = c + 1;  xp = x + 2;
+  while (--i) {                 /* note that i == g from above */
+    *xp++ = (j += *p++);
+  }
+
+DEBG("huft5 ");
+
+  /* Make a table of values in order of bit lengths */
+  p = b;  i = 0;
+  do {
+    if ((j = *p++) != 0)
+      v[x[j]++] = i;
+  } while (++i < n);
+
+DEBG("h6 ");
+
+  /* Generate the Huffman codes and for each, make the table entries */
+  x[0] = i = 0;                 /* first Huffman code is zero */
+  p = v;                        /* grab values in bit order */
+  h = -1;                       /* no tables yet--level -1 */
+  w = -l;                       /* bits decoded == (l * h) */
+  u[0] = (struct huft *)NULL;   /* just to keep compilers happy */
+  q = (struct huft *)NULL;      /* ditto */
+  z = 0;                        /* ditto */
+DEBG("h6a ");
+
+  /* go through the bit lengths (k already is bits in shortest code) */
+  for (; k <= g; k++)
+  {
+DEBG("h6b ");
+    a = c[k];
+    while (a--)
+    {
+DEBG("h6b1 ");
+      /* here i is the Huffman code of length k bits for value *p */
+      /* make tables up to required level */
+      while (k > w + l)
+      {
+DEBG1("1 ");
+        h++;
+        w += l;                 /* previous table always l bits */
+
+        /* compute minimum size table less than or equal to l bits */
+        z = (z = g - w) > (unsigned)l ? l : z;  /* upper limit on table size */
+        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
+        {                       /* too few codes for k-w bit table */
+DEBG1("2 ");
+          f -= a + 1;           /* deduct codes from patterns left */
+          xp = c + k;
+          while (++j < z)       /* try smaller tables up to z bits */
+          {
+            if ((f <<= 1) <= *++xp)
+              break;            /* enough codes to use up j bits */
+            f -= *xp;           /* else deduct codes from patterns */
+          }
+        }
+DEBG1("3 ");
+        z = 1 << j;             /* table entries for j-bit table */
+
+        /* allocate and link in new table */
+        q = (struct huft *)malloc((z + 1)*sizeof(struct huft));
+DEBG1("4 ");
+        hufts += z + 1;         /* track memory usage */
+        *t = q + 1;             /* link to list for huft_free() */
+        *(t = &(q->v.t)) = (struct huft *)NULL;
+        u[h] = ++q;             /* table starts after link */
+
+DEBG1("5 ");
+        /* connect to last table, if there is one */
+        if (h)
+        {
+          x[h] = i;             /* save pattern for backing up */
+          r.b = (uch)l;         /* bits to dump before this table */
+          r.e = (uch)(16 + j);  /* bits in this table */
+          r.v.t = q;            /* pointer to this table */
+          j = i >> (w - l);     /* (get around Turbo C bug) */
+          u[h-1][j] = r;        /* connect to last table */
+        }
+DEBG1("6 ");
+      }
+DEBG("h6c ");
+
+      /* set up table entry in r */
+      r.b = (uch)(k - w);
+      if (p >= v + n)
+        r.e = 99;               /* out of values--invalid code */
+      else if (*p < s)
+      {
+        r.e = (uch)(*p < 256 ? 16 : 15);    /* 256 is end-of-block code */
+        r.v.n = *p++;           /* simple code is just the value */
+      }
+      else
+      {
+        r.e = (uch)e[*p - s];   /* non-simple--look up in lists */
+        r.v.n = d[*p++ - s];
+      }
+DEBG("h6d ");
+
+      /* fill code-like entries with r */
+      f = 1 << (k - w);
+      for (j = i >> w; j < z; j += f)
+        q[j] = r;
+
+      /* backwards increment the k-bit code i */
+      for (j = 1 << (k - 1); i & j; j >>= 1)
+        i ^= j;
+      i ^= j;
+
+      /* backup over finished tables */
+      while ((i & ((1 << w) - 1)) != x[h])
+      {
+        h--;                    /* don't need to update q */
+        w -= l;
+      }
+DEBG("h6e ");
+    }
+DEBG("h6f ");
+  }
+
+DEBG("huft7 ");
+
+  /* Return true (1) if we were given an incomplete table */
+  return y != 0 && g != 1;
+}
+
+
+
+int huft_free(t)
+struct huft *t;         /* table to free */
+/* Free the malloc'ed tables built by huft_build(), which makes a linked
+   list of the tables it made, with the links in a dummy first entry of
+   each table. */
+{
+  register struct huft *p, *q;
+
+
+  /* Go through linked list, freeing from the malloced (t[-1]) address. */
+  p = t;
+  while (p != (struct huft *)NULL)
+  {
+    q = (--p)->v.t;
+    free(p);
+    p = q;
+  } 
+  return 0;
+}
+
+
+int inflate_codes(tl, td, bl, bd)
+struct huft *tl, *td;   /* literal/length and distance decoder tables */
+int bl, bd;             /* number of bits decoded by tl[] and td[] */
+/* inflate (decompress) the codes in a deflated (compressed) block.
+   Return an error code or zero if it all goes ok. */
+{
+  register unsigned e;  /* table entry flag/number of extra bits */
+  unsigned n, d;        /* length and index for copy */
+  unsigned w;           /* current window position */
+  struct huft *t;       /* pointer to table entry */
+  unsigned ml, md;      /* masks for bl and bd bits */
+  register ulg b;       /* bit buffer */
+  register unsigned k;  /* number of bits in bit buffer */
+
+
+  /* make local copies of globals */
+  b = bb;                       /* initialize bit buffer */
+  k = bk;
+  w = wp;                       /* initialize window position */
+
+  /* inflate the coded data */
+  ml = mask_bits[bl];           /* precompute masks for speed */
+  md = mask_bits[bd];
+  for (;;)                      /* do until end of block */
+  {
+    NEEDBITS((unsigned)bl)
+    if ((e = (t = tl + ((unsigned)b & ml))->e) > 16)
+      do {
+        if (e == 99)
+          return 1;
+        DUMPBITS(t->b)
+        e -= 16;
+        NEEDBITS(e)
+      } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16);
+    DUMPBITS(t->b)
+    if (e == 16)                /* then it's a literal */
+    {
+      slide[w++] = (uch)t->v.n;
+      if (w == WSIZE)
+      {
+        flush_output(w);
+        w = 0;
+      }
+    }
+    else                        /* it's an EOB or a length */
+    {
+      /* exit if end of block */
+      if (e == 15)
+        break;
+
+      /* get length of block to copy */
+      NEEDBITS(e)
+      n = t->v.n + ((unsigned)b & mask_bits[e]);
+      DUMPBITS(e);
+
+      /* decode distance of block to copy */
+      NEEDBITS((unsigned)bd)
+      if ((e = (t = td + ((unsigned)b & md))->e) > 16)
+        do {
+          if (e == 99)
+            return 1;
+          DUMPBITS(t->b)
+          e -= 16;
+          NEEDBITS(e)
+        } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16);
+      DUMPBITS(t->b)
+      NEEDBITS(e)
+      d = w - t->v.n - ((unsigned)b & mask_bits[e]);
+      DUMPBITS(e)
+
+      /* do the copy */
+      do {
+        n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
+#if !defined(NOMEMCPY) && !defined(DEBUG)
+        if (w - d >= e)         /* (this test assumes unsigned comparison) */
+        {
+          memcpy(slide + w, slide + d, e);
+          w += e;
+          d += e;
+        }
+        else                      /* do it slow to avoid memcpy() overlap */
+#endif /* !NOMEMCPY */
+          do {
+            slide[w++] = slide[d++];
+          } while (--e);
+        if (w == WSIZE)
+        {
+          flush_output(w);
+          w = 0;
+        }
+      } while (n);
+    }
+  }
+
+
+  /* restore the globals from the locals */
+  wp = w;                       /* restore global window pointer */
+  bb = b;                       /* restore global bit buffer */
+  bk = k;
+
+  /* done */
+  return 0;
+}
+
+
+
+int inflate_stored()
+/* "decompress" an inflated type 0 (stored) block. */
+{
+  unsigned n;           /* number of bytes in block */
+  unsigned w;           /* current window position */
+  register ulg b;       /* bit buffer */
+  register unsigned k;  /* number of bits in bit buffer */
+
+DEBG("<stor");
+
+  /* make local copies of globals */
+  b = bb;                       /* initialize bit buffer */
+  k = bk;
+  w = wp;                       /* initialize window position */
+
+
+  /* go to byte boundary */
+  n = k & 7;
+  DUMPBITS(n);
+
+
+  /* get the length and its complement */
+  NEEDBITS(16)
+  n = ((unsigned)b & 0xffff);
+  DUMPBITS(16)
+  NEEDBITS(16)
+  if (n != (unsigned)((~b) & 0xffff))
+    return 1;                   /* error in compressed data */
+  DUMPBITS(16)
+
+
+  /* read and output the compressed data */
+  while (n--)
+  {
+    NEEDBITS(8)
+    slide[w++] = (uch)b;
+    if (w == WSIZE)
+    {
+      flush_output(w);
+      w = 0;
+    }
+    DUMPBITS(8)
+  }
+
+
+  /* restore the globals from the locals */
+  wp = w;                       /* restore global window pointer */
+  bb = b;                       /* restore global bit buffer */
+  bk = k;
+
+  DEBG(">");
+  return 0;
+}
+
+
+
+int inflate_fixed()
+/* decompress an inflated type 1 (fixed Huffman codes) block.  We should
+   either replace this with a custom decoder, or at least precompute the
+   Huffman tables. */
+{
+  int i;                /* temporary variable */
+  struct huft *tl;      /* literal/length code table */
+  struct huft *td;      /* distance code table */
+  int bl;               /* lookup bits for tl */
+  int bd;               /* lookup bits for td */
+  unsigned l[288];      /* length list for huft_build */
+
+DEBG("<fix");
+
+  /* set up literal table */
+  for (i = 0; i < 144; i++)
+    l[i] = 8;
+  for (; i < 256; i++)
+    l[i] = 9;
+  for (; i < 280; i++)
+    l[i] = 7;
+  for (; i < 288; i++)          /* make a complete, but wrong code set */
+    l[i] = 8;
+  bl = 7;
+  if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0)
+    return i;
+
+
+  /* set up distance table */
+  for (i = 0; i < 30; i++)      /* make an incomplete code set */
+    l[i] = 5;
+  bd = 5;
+  if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1)
+  {
+    huft_free(tl);
+
+    DEBG(">");
+    return i;
+  }
+
+
+  /* decompress until an end-of-block code */
+  if (inflate_codes(tl, td, bl, bd))
+    return 1;
+
+
+  /* free the decoding tables, return */
+  huft_free(tl);
+  huft_free(td);
+  return 0;
+}
+
+
+
+int inflate_dynamic()
+/* decompress an inflated type 2 (dynamic Huffman codes) block. */
+{
+  int i;                /* temporary variables */
+  unsigned j;
+  unsigned l;           /* last length */
+  unsigned m;           /* mask for bit lengths table */
+  unsigned n;           /* number of lengths to get */
+  struct huft *tl;      /* literal/length code table */
+  struct huft *td;      /* distance code table */
+  int bl;               /* lookup bits for tl */
+  int bd;               /* lookup bits for td */
+  unsigned nb;          /* number of bit length codes */
+  unsigned nl;          /* number of literal/length codes */
+  unsigned nd;          /* number of distance codes */
+#ifdef PKZIP_BUG_WORKAROUND
+  unsigned ll[288+32];  /* literal/length and distance code lengths */
+#else
+  unsigned ll[286+30];  /* literal/length and distance code lengths */
+#endif
+  register ulg b;       /* bit buffer */
+  register unsigned k;  /* number of bits in bit buffer */
+
+DEBG("<dyn");
+
+  /* make local bit buffer */
+  b = bb;
+  k = bk;
+
+
+  /* read in table lengths */
+  NEEDBITS(5)
+  nl = 257 + ((unsigned)b & 0x1f);      /* number of literal/length codes */
+  DUMPBITS(5)
+  NEEDBITS(5)
+  nd = 1 + ((unsigned)b & 0x1f);        /* number of distance codes */
+  DUMPBITS(5)
+  NEEDBITS(4)
+  nb = 4 + ((unsigned)b & 0xf);         /* number of bit length codes */
+  DUMPBITS(4)
+#ifdef PKZIP_BUG_WORKAROUND
+  if (nl > 288 || nd > 32)
+#else
+  if (nl > 286 || nd > 30)
+#endif
+    return 1;                   /* bad lengths */
+
+DEBG("dyn1 ");
+
+  /* read in bit-length-code lengths */
+  for (j = 0; j < nb; j++)
+  {
+    NEEDBITS(3)
+    ll[border[j]] = (unsigned)b & 7;
+    DUMPBITS(3)
+  }
+  for (; j < 19; j++)
+    ll[border[j]] = 0;
+
+DEBG("dyn2 ");
+
+  /* build decoding table for trees--single level, 7 bit lookup */
+  bl = 7;
+  if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0)
+  {
+    if (i == 1)
+      huft_free(tl);
+    return i;                   /* incomplete code set */
+  }
+
+DEBG("dyn3 ");
+
+  /* read in literal and distance code lengths */
+  n = nl + nd;
+  m = mask_bits[bl];
+  i = l = 0;
+  while ((unsigned)i < n)
+  {
+    NEEDBITS((unsigned)bl)
+    j = (td = tl + ((unsigned)b & m))->b;
+    DUMPBITS(j)
+    j = td->v.n;
+    if (j < 16)                 /* length of code in bits (0..15) */
+      ll[i++] = l = j;          /* save last length in l */
+    else if (j == 16)           /* repeat last length 3 to 6 times */
+    {
+      NEEDBITS(2)
+      j = 3 + ((unsigned)b & 3);
+      DUMPBITS(2)
+      if ((unsigned)i + j > n)
+        return 1;
+      while (j--)
+        ll[i++] = l;
+    }
+    else if (j == 17)           /* 3 to 10 zero length codes */
+    {
+      NEEDBITS(3)
+      j = 3 + ((unsigned)b & 7);
+      DUMPBITS(3)
+      if ((unsigned)i + j > n)
+        return 1;
+      while (j--)
+        ll[i++] = 0;
+      l = 0;
+    }
+    else                        /* j == 18: 11 to 138 zero length codes */
+    {
+      NEEDBITS(7)
+      j = 11 + ((unsigned)b & 0x7f);
+      DUMPBITS(7)
+      if ((unsigned)i + j > n)
+        return 1;
+      while (j--)
+        ll[i++] = 0;
+      l = 0;
+    }
+  }
+
+DEBG("dyn4 ");
+
+  /* free decoding table for trees */
+  huft_free(tl);
+
+DEBG("dyn5 ");
+
+  /* restore the global bit buffer */
+  bb = b;
+  bk = k;
+
+DEBG("dyn5a ");
+
+  /* build the decoding tables for literal/length and distance codes */
+  bl = lbits;
+  if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0)
+  {
+DEBG("dyn5b ");
+    if (i == 1) {
+      error(" incomplete literal tree\n");
+      huft_free(tl);
+    }
+    return i;                   /* incomplete code set */
+  }
+DEBG("dyn5c ");
+  bd = dbits;
+  if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0)
+  {
+DEBG("dyn5d ");
+    if (i == 1) {
+      error(" incomplete distance tree\n");
+#ifdef PKZIP_BUG_WORKAROUND
+      i = 0;
+    }
+#else
+      huft_free(td);
+    }
+    huft_free(tl);
+    return i;                   /* incomplete code set */
+#endif
+  }
+
+DEBG("dyn6 ");
+
+  /* decompress until an end-of-block code */
+  if (inflate_codes(tl, td, bl, bd))
+    return 1;
+
+DEBG("dyn7 ");
+
+  /* free the decoding tables, return */
+  huft_free(tl);
+  huft_free(td);
+
+  DEBG(">");
+  return 0;
+}
+
+
+
+int inflate_block(e)
+int *e;                 /* last block flag */
+/* decompress an inflated block */
+{
+  unsigned t;           /* block type */
+  register ulg b;       /* bit buffer */
+  register unsigned k;  /* number of bits in bit buffer */
+
+  DEBG("<blk");
+
+  /* make local bit buffer */
+  b = bb;
+  k = bk;
+
+
+  /* read in last block bit */
+  NEEDBITS(1)
+  *e = (int)b & 1;
+  DUMPBITS(1)
+
+
+  /* read in block type */
+  NEEDBITS(2)
+  t = (unsigned)b & 3;
+  DUMPBITS(2)
+
+
+  /* restore the global bit buffer */
+  bb = b;
+  bk = k;
+
+  /* inflate that block type */
+  if (t == 2)
+    return inflate_dynamic();
+  if (t == 0)
+    return inflate_stored();
+  if (t == 1)
+    return inflate_fixed();
+
+  DEBG(">");
+
+  /* bad block type */
+  return 2;
+}
+
+
+
+int inflate()
+/* decompress an inflated entry */
+{
+  int e;                /* last block flag */
+  int r;                /* result code */
+  unsigned h;           /* maximum struct huft's malloc'ed */
+
+
+  /* initialize window, bit buffer */
+  wp = 0;
+  bk = 0;
+  bb = 0;
+
+
+  /* decompress until the last block */
+  h = 0;
+  do {
+    hufts = 0;
+    if ((r = inflate_block(&e)) != 0)
+      return r;
+    if (hufts > h)
+      h = hufts;
+  } while (!e);
+
+  /* Undo too much lookahead. The next read will be byte aligned so we
+   * can discard unused bits in the last meaningful byte.
+   */
+  while (bk >= 8) {
+    bk -= 8;
+    inptr--;
+  }
+
+  /* flush out slide */
+  flush_output(wp);
+
+
+  /* return success */
+#ifdef DEBUG
+  fprintf(stderr, "<%u> ", h);
+#endif /* DEBUG */
+  return 0;
+}
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/boot/compressed/lzw.h linux/arch/ppc/boot/compressed/lzw.h
--- pre2.0.7/linux/arch/ppc/boot/compressed/lzw.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/boot/compressed/lzw.h	Mon May 27 12:00:57 1996
@@ -0,0 +1,42 @@
+/* lzw.h -- define the lzw functions.
+ * Copyright (C) 1992-1993 Jean-loup Gailly.
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License, see the file COPYING.
+ */
+
+#if !defined(OF) && defined(lint)
+#  include "gzip.h"
+#endif
+
+#ifndef BITS
+#  define BITS 16
+#endif
+#define INIT_BITS 9              /* Initial number of bits per code */
+
+#define	LZW_MAGIC  "\037\235"   /* Magic header for lzw files, 1F 9D */
+
+#define BIT_MASK    0x1f /* Mask for 'number of compression bits' */
+/* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free.
+ * It's a pity that old uncompress does not check bit 0x20. That makes
+ * extension of the format actually undesirable because old compress
+ * would just crash on the new format instead of giving a meaningful
+ * error message. It does check the number of bits, but it's more
+ * helpful to say "unsupported format, get a new version" than
+ * "can only handle 16 bits".
+ */
+
+#define BLOCK_MODE  0x80
+/* Block compression: if table is full and compression rate is dropping,
+ * clear the dictionary.
+ */
+
+#define LZW_RESERVED 0x60 /* reserved bits */
+
+#define	CLEAR  256       /* flush the dictionary */
+#define FIRST  (CLEAR+1) /* first free entry */
+
+extern int maxbits;      /* max bits per code for LZW */
+extern int block_mode;   /* block compress mode -C compatible with 2.0 */
+
+extern void lzw    OF((int in, int out));
+extern void unlzw  OF((int in, int out));
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/boot/compressed/misc.c linux/arch/ppc/boot/compressed/misc.c
--- pre2.0.7/linux/arch/ppc/boot/compressed/misc.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/boot/compressed/misc.c	Mon May 27 12:00:57 1996
@@ -0,0 +1,430 @@
+/*
+ * misc.c
+ * 
+ * This is a collection of several routines from gzip-1.0.3 
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ * puts by Nick Holloway 1993
+ */
+
+#include "gzip.h"
+#include "lzw.h"
+
+
+#define EOF -1
+
+DECLARE(uch, inbuf, INBUFSIZ);
+DECLARE(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA);
+DECLARE(uch, window, WSIZE);
+
+unsigned outcnt;
+unsigned insize;
+unsigned inptr;
+
+extern char input_data[];
+extern int input_len;
+
+int input_ptr;
+
+int method, exit_code, part_nb, last_member;
+int test = 0;
+int force = 0;
+int verbose = 1;
+long bytes_in, bytes_out;
+
+char *output_data;
+unsigned long output_ptr;
+
+extern int end;
+long free_mem_ptr = (long)&end;
+
+int to_stdout = 0;
+int hard_math = 0;
+
+void (*work)(int inf, int outf);
+void makecrc(void);
+
+local int get_method(int);
+
+char *vidmem = (char *)0xC00B8000;
+int lines, cols;
+int orig_x, orig_y;
+
+void puts(const char *);
+
+void *malloc(int size)
+{
+	void *p;
+
+	if (size <0) error("Malloc error\n");
+	if (free_mem_ptr <= 0) error("Memory error\n");
+
+   while(1) {
+	free_mem_ptr = (free_mem_ptr + 3) & ~3;	/* Align */
+
+	p = (void *)free_mem_ptr;
+	free_mem_ptr += size;
+
+	/*
+  	 * The part of the compressed kernel which has already been expanded
+	 * is no longer needed. Therefore we can reuse it for malloc.
+	 * With bigger kernels, this is necessary.
+	 */
+          
+	if (free_mem_ptr < (long)&end) {
+		if (free_mem_ptr > (long)&input_data[input_ptr])
+			error("\nOut of memory\n");
+
+		return p;
+	}
+#if 0	
+	if (free_mem_ptr < 0x90000)
+#endif	
+	return p;
+	puts("large kernel, low 1M tight...");
+	free_mem_ptr = (long)input_data;
+	}
+}
+
+void free(void *where)
+{	/* Don't care */
+}
+
+static void scroll()
+{
+	int i;
+
+	memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
+	for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
+		vidmem[i] = ' ';
+}
+
+void puts(const char *s)
+{
+	int x,y;
+	char c;
+
+#if 0	
+	x = SCREEN_INFO.orig_x;
+	y = SCREEN_INFO.orig_y;
+#else
+	x = orig_x;
+	y = orig_y;
+#endif	
+
+	while ( ( c = *s++ ) != '\0' ) {
+		if ( c == '\n' ) {
+			x = 0;
+			if ( ++y >= lines ) {
+				scroll();
+				y--;
+			}
+		} else {
+			vidmem [ ( x + cols * y ) * 2 ] = c; 
+			if ( ++x >= cols ) {
+				x = 0;
+				if ( ++y >= lines ) {
+					scroll();
+					y--;
+				}
+			}
+		}
+	}
+
+#if 0	
+	SCREEN_INFO.orig_x = x;
+	SCREEN_INFO.orig_y = y;
+#else
+	orig_x = x;
+	orig_y = y;
+#endif	
+}
+
+__ptr_t memset(__ptr_t s, int c, size_t n)
+{
+	int i;
+	char *ss = (char*)s;
+
+	for (i=0;i<n;i++) ss[i] = c;
+}
+
+__ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
+			    size_t __n)
+{
+	int i;
+	char *d = (char *)__dest, *s = (char *)__src;
+
+	for (i=0;i<__n;i++) d[i] = s[i];
+}
+
+int memcmp(__ptr_t __dest, __const __ptr_t __src,
+			    size_t __n)
+{
+	int i;
+	char *d = (char *)__dest, *s = (char *)__src;
+
+	for (i=0;i<__n;i++, d++, s++)
+	{
+		if (*d != *s)
+		{
+			return (*s - *d);
+		}
+	}
+	return (0);
+}
+
+extern ulg crc_32_tab[];   /* crc table, defined below */
+
+/* ===========================================================================
+ * Run a set of bytes through the crc shift register.  If s is a NULL
+ * pointer, then initialize the crc shift register contents instead.
+ * Return the current crc in either case.
+ */
+ulg updcrc(s, n)
+    uch *s;                 /* pointer to bytes to pump through */
+    unsigned n;             /* number of bytes in s[] */
+{
+    register ulg c;         /* temporary variable */
+
+    static ulg crc = (ulg)0xffffffffL; /* shift register contents */
+
+    if (s == NULL) {
+	c = 0xffffffffL;
+    } else {
+	c = crc;
+	while (n--) {
+	    c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
+	}
+    }
+    crc = c;
+    return c ^ 0xffffffffL;       /* (instead of ~c for 64-bit machines) */
+}
+
+/* ===========================================================================
+ * Clear input and output buffers
+ */
+void clear_bufs()
+{
+    outcnt = 0;
+    insize = inptr = 0;
+    bytes_in = bytes_out = 0L;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+int fill_inbuf()
+{
+    int len, i;
+
+    /* Read as much as possible */
+puts("*");    
+    insize = 0;
+    do {
+	len = INBUFSIZ-insize;
+	if (len > (input_len-input_ptr+1)) len=input_len-input_ptr+1;
+        if (len == 0 || len == EOF) break;
+
+        for (i=0;i<len;i++) inbuf[insize+i] = input_data[input_ptr+i];
+	insize += len;
+	input_ptr += len;
+    } while (insize < INBUFSIZ);
+
+    if (insize == 0) {
+	error("unable to fill buffer\n");
+    }
+    bytes_in += (ulg)insize;
+    inptr = 1;
+    return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+void flush_window()
+{
+    if (outcnt == 0) return;
+    updcrc(window, outcnt);
+
+    memcpy(&output_data[output_ptr], (char *)window, outcnt);
+
+    bytes_out += (ulg)outcnt;
+    output_ptr += (ulg)outcnt;
+    outcnt = 0;
+}
+
+/*
+ * Code to compute the CRC-32 table. Borrowed from 
+ * gzip-1.0.3/makecrc.c.
+ */
+
+ulg crc_32_tab[256];
+
+void
+makecrc(void)
+{
+/* Not copyrighted 1990 Mark Adler	*/
+
+  unsigned long c;      /* crc shift register */
+  unsigned long e;      /* polynomial exclusive-or pattern */
+  int i;                /* counter for all possible eight bit values */
+  int k;                /* byte being shifted into crc apparatus */
+
+  /* terms of polynomial defining this crc (except x^32): */
+  static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+  /* Make exclusive-or pattern from polynomial */
+  e = 0;
+  for (i = 0; i < sizeof(p)/sizeof(int); i++)
+    e |= 1L << (31 - p[i]);
+
+  crc_32_tab[0] = 0;
+
+  for (i = 1; i < 256; i++)
+  {
+    c = 0;
+    for (k = i | 256; k != 1; k >>= 1)
+    {
+      c = c & 1 ? (c >> 1) ^ e : c >> 1;
+      if (k & 1)
+        c ^= e;
+    }
+    crc_32_tab[i] = c;
+  }
+}
+
+void error(char *x)
+{
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted");
+
+	while(1);	/* Halt */
+}
+
+#if 0
+#define STACK_SIZE (4096)
+
+long user_stack [STACK_SIZE];
+
+struct {
+	long * a;
+	short b;
+	} stack_start = { & user_stack [STACK_SIZE] , KERNEL_DS };
+#endif
+
+void decompress_kernel()
+{
+#if 0	
+	if (SCREEN_INFO.orig_video_mode == 7)
+		vidmem = (char *) 0xb0000;
+	else
+		vidmem = (char *) 0xb8000;
+
+	lines = SCREEN_INFO.orig_video_lines;
+	cols = SCREEN_INFO.orig_video_cols;
+
+	if (EXT_MEM_K < 1024) error("<2M of mem\n");
+	output_data = (char *)0x100000;	/* Points to 1M */
+#else
+	output_data = (char *)0x0;	/* Points to 0 */
+	lines = 25;
+	cols = 80;
+	orig_x = 0;
+	orig_y = 24;
+#endif	
+
+	output_ptr = 0;
+
+	exit_code = 0;
+	test = 0;
+	input_ptr = 0;
+	part_nb = 0;
+
+	clear_bufs();
+	makecrc();
+
+	puts("Uncompressing Linux...");
+
+	method = get_method(0);
+
+	work(0, 0);
+
+	puts("done.\n");
+
+	puts("Now booting the kernel\n");
+}
+
+/* ========================================================================
+ * Check the magic number of the input file and update ofname if an
+ * original name was given and to_stdout is not set.
+ * Return the compression method, -1 for error, -2 for warning.
+ * Set inptr to the offset of the next byte to be processed.
+ * This function may be called repeatedly for an input file consisting
+ * of several contiguous gzip'ed members.
+ * IN assertions: there is at least one remaining compressed member.
+ *   If the member is a zip file, it must be the only one.
+ */
+local int get_method(in)
+    int in;        /* input file descriptor */
+{
+    uch flags;
+    char magic[2]; /* magic header */
+
+    magic[0] = (char)get_byte();
+    magic[1] = (char)get_byte();
+
+    method = -1;                 /* unknown yet */
+    part_nb++;                   /* number of parts in gzip file */
+    last_member = 0;
+    /* assume multiple members in gzip file except for record oriented I/O */
+
+    if (memcmp(magic, GZIP_MAGIC, 2) == 0
+        || memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) {
+
+	work = unzip;
+	method = (int)get_byte();
+	flags  = (uch)get_byte();
+	if ((flags & ENCRYPTED) != 0)
+	    error("Input is encrypted\n");
+	if ((flags & CONTINUATION) != 0)
+	       error("Multi part input\n");
+	if ((flags & RESERVED) != 0) {
+	    error("Input has invalid flags\n");
+	    exit_code = ERROR;
+	    if (force <= 1) return -1;
+	}
+	(ulg)get_byte();	/* Get timestamp */
+	((ulg)get_byte()) << 8;
+	((ulg)get_byte()) << 16;
+	((ulg)get_byte()) << 24;
+
+	(void)get_byte();  /* Ignore extra flags for the moment */
+	(void)get_byte();  /* Ignore OS type for the moment */
+
+	if ((flags & EXTRA_FIELD) != 0) {
+	    unsigned len = (unsigned)get_byte();
+	    len |= ((unsigned)get_byte())<<8;
+	    while (len--) (void)get_byte();
+	}
+
+	/* Get original file name if it was truncated */
+	if ((flags & ORIG_NAME) != 0) {
+	    if (to_stdout || part_nb > 1) {
+		/* Discard the old name */
+		while (get_byte() != 0) /* null */ ;
+	    } else {
+	    } /* to_stdout */
+	} /* orig_name */
+
+	/* Discard file comment if any */
+	if ((flags & COMMENT) != 0) {
+	    while (get_byte() != 0) /* null */ ;
+	}
+    } else
+	error("unknown compression method");
+    return method;
+}
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/boot/compressed/piggyback.c linux/arch/ppc/boot/compressed/piggyback.c
--- pre2.0.7/linux/arch/ppc/boot/compressed/piggyback.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/boot/compressed/piggyback.c	Mon May 27 12:00:57 1996
@@ -0,0 +1,59 @@
+#include <stdio.h>
+
+extern long ce_exec_config[];
+
+main(int argc, char *argv[])
+{
+	int i, cnt, pos, len;
+	unsigned char *lp;
+	unsigned char buf[8192];
+	if (argc != 1)
+	{
+		fprintf(stderr, "usage: %s <in-file >out-file\n", argv[0]);
+		exit(1);
+	}
+	fprintf(stdout, "#\n");
+	fprintf(stdout, "# Miscellaneous data structures:\n");
+	fprintf(stdout, "# WARNING - this file is automatically generated!\n");
+	fprintf(stdout, "#\n");
+	fprintf(stdout, "\n");
+	fprintf(stdout, "\t.data\n");
+	fprintf(stdout, "\t.globl input_data\n");
+	fprintf(stdout, "input_data:\n");
+	pos = 0;
+	while ((len = read(0, buf, sizeof(buf))) > 0)
+	{
+		cnt = 0;
+		lp = (unsigned char *)buf;
+		len = (len + 3) & ~3;  /* Round up to longwords */
+		for (i = 0;  i < len;  i += 4)
+		{
+			if (cnt == 0)
+			{
+				fprintf(stdout, "\t.long\t");
+			}
+			fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
+			lp += 4;
+			if (++cnt == 4)
+			{
+				cnt = 0;
+				fprintf(stdout, " # %x \n", pos+i-12);
+				fflush(stdout);
+			} else
+			{
+				fprintf(stdout, ",");
+			}
+		}
+		if (cnt)
+		{
+			fprintf(stdout, "0\n");
+		}
+		pos += len;
+	}
+	fprintf(stdout, "\t.globl input_len\n");
+	fprintf(stdout, "input_len:\t.long\t0x%x\n", pos);
+	fflush(stdout);
+	fclose(stdout);
+	exit(0);
+}
+
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/boot/compressed/ppc_defs.h linux/arch/ppc/boot/compressed/ppc_defs.h
--- pre2.0.7/linux/arch/ppc/boot/compressed/ppc_defs.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/boot/compressed/ppc_defs.h	Mon May 27 12:00:57 1996
@@ -0,0 +1,6 @@
+#define r0 0
+#define r1 1
+#define r2 2
+#define r3 3
+#define r4 4
+#define r5 5
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/boot/compressed/unzip.c linux/arch/ppc/boot/compressed/unzip.c
--- pre2.0.7/linux/arch/ppc/boot/compressed/unzip.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/boot/compressed/unzip.c	Mon May 27 12:00:57 1996
@@ -0,0 +1,180 @@
+/* unzip.c -- decompress files in gzip or pkzip format.
+ * Copyright (C) 1992-1993 Jean-loup Gailly
+ *
+ * Adapted for Linux booting by Hannu Savolainen 1993
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License, see the file COPYING.
+ *
+ * The code in this file is derived from the file funzip.c written
+ * and put in the public domain by Mark Adler.
+ */
+
+/*
+   This version can extract files in gzip or pkzip format.
+   For the latter, only the first entry is extracted, and it has to be
+   either deflated or stored.
+ */
+
+#ifndef lint
+static char rcsid[] = "$Id: unzip.c,v 0.9 1993/02/10 16:07:22 jloup Exp $";
+#endif
+
+#include "gzip.h"
+#include "crypt.h"
+
+#include <stdio.h>
+
+/* PKZIP header definitions */
+#define LOCSIG 0x04034b50L      /* four-byte lead-in (lsb first) */
+#define LOCFLG 6                /* offset of bit flag */
+#define  CRPFLG 1               /*  bit for encrypted entry */
+#define  EXTFLG 8               /*  bit for extended local header */
+#define LOCHOW 8                /* offset of compression method */
+#define LOCTIM 10               /* file mod time (for decryption) */
+#define LOCCRC 14               /* offset of crc */
+#define LOCSIZ 18               /* offset of compressed size */
+#define LOCLEN 22               /* offset of uncompressed length */
+#define LOCFIL 26               /* offset of file name field length */
+#define LOCEXT 28               /* offset of extra field length */
+#define LOCHDR 30               /* size of local header, including sig */
+#define EXTHDR 16               /* size of extended local header, inc sig */
+
+
+/* Globals */
+
+int decrypt;      /* flag to turn on decryption */
+char *key;        /* not used--needed to link crypt.c */
+int pkzip = 0;    /* set for a pkzip file */
+int extended = 0; /* set if extended local header */
+
+/* ===========================================================================
+ * Check zip file and advance inptr to the start of the compressed data.
+ * Get ofname from the local header if necessary.
+ */
+int check_zipfile(in)
+    int in;   /* input file descriptors */
+{
+    uch *h = inbuf + inptr; /* first local header */
+
+    /* ifd = in; */
+
+    /* Check validity of local header, and skip name and extra fields */
+    inptr += LOCHDR + SH(h + LOCFIL) + SH(h + LOCEXT);
+
+    if (inptr > insize || LG(h) != LOCSIG) {
+	error("input not a zip");
+    }
+    method = h[LOCHOW];
+    if (method != STORED && method != DEFLATED) {
+	error("first entry not deflated or stored--can't extract");
+    }
+
+    /* If entry encrypted, decrypt and validate encryption header */
+    if ((decrypt = h[LOCFLG] & CRPFLG) != 0) {
+	error("encrypted file\n");
+	exit_code = ERROR;
+	return -1;
+    }
+
+    /* Save flags for unzip() */
+    extended = (h[LOCFLG] & EXTFLG) != 0;
+    pkzip = 1;
+
+    /* Get ofname and time stamp from local header (to be done) */
+    return 0;
+}
+
+/* ===========================================================================
+ * Unzip in to out.  This routine works on both gzip and pkzip files.
+ *
+ * IN assertions: the buffer inbuf contains already the beginning of
+ *   the compressed data, from offsets inptr to insize-1 included.
+ *   The magic header has already been checked. The output buffer is cleared.
+ */
+void unzip(in, out)
+    int in, out;   /* input and output file descriptors */
+{
+    ulg orig_crc = 0;       /* original crc */
+    ulg orig_len = 0;       /* original uncompressed length */
+    int n;
+    uch buf[EXTHDR];        /* extended local header */
+
+    /* ifd = in;
+    ofd = out; */
+
+    updcrc(NULL, 0);           /* initialize crc */
+
+    if (pkzip && !extended) {  /* crc and length at the end otherwise */
+	orig_crc = LG(inbuf + LOCCRC);
+	orig_len = LG(inbuf + LOCLEN);
+    }
+
+    /* Decompress */
+    if (method == DEFLATED)  {
+
+	int res = inflate();
+
+	if (res == 3) {
+	    error("out of memory");
+	} else if (res != 0) {
+	    error("invalid compressed format");
+	}
+
+    } else if (pkzip && method == STORED) {
+
+	register ulg n = LG(inbuf + LOCLEN);
+
+	if (n != LG(inbuf + LOCSIZ) - (decrypt ? RAND_HEAD_LEN : 0)) {
+
+	    error("length mismatch");
+	}
+	while (n--) {
+	    uch c = (uch)get_byte();
+#ifdef CRYPT
+	    if (decrypt) zdecode(c);
+#endif
+	    if (!test) put_char(c);
+	}
+    } else {
+	error("internal error, invalid method");
+    }
+
+    /* Get the crc and original length */
+    if (!pkzip) {
+        /* crc32  (see algorithm.doc)
+	 * uncompressed input size modulo 2^32
+         */
+	for (n = 0; n < 8; n++) {
+	    buf[n] = (uch)get_byte(); /* may cause an error if EOF */
+	}
+	orig_crc = LG(buf);
+	orig_len = LG(buf+4);
+
+    } else if (extended) {  /* If extended header, check it */
+	/* signature - 4bytes: 0x50 0x4b 0x07 0x08
+	 * CRC-32 value
+         * compressed size 4-bytes
+         * uncompressed size 4-bytes
+	 */
+	for (n = 0; n < EXTHDR; n++) {
+	    buf[n] = (uch)get_byte(); /* may cause an error if EOF */
+	}
+	orig_crc = LG(buf+4);
+	orig_len = LG(buf+12);
+    }
+
+    /* Validate decompression */
+    if (orig_crc != updcrc(outbuf, 0)) {
+	error("crc error");
+    }
+    if (orig_len != bytes_out) {
+	error("length error");
+    }
+
+    /* Check if there are more entries in a pkzip file */
+    if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) {
+	    error("zip file has more than one entry");
+    }
+    extended = pkzip = 0; /* for next file */
+}
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/boot/mk_type41.c linux/arch/ppc/boot/mk_type41.c
--- pre2.0.7/linux/arch/ppc/boot/mk_type41.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/boot/mk_type41.c	Mon May 27 12:00:57 1996
@@ -0,0 +1,204 @@
+/*
+ * This program will make a type 0x41 load image from an
+ * executable file.  Note:  assumes that the executable has
+ * already been "flattened" by 'mkboot'.
+ *
+ * usage: mk_type41 flat-file image
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+_LE(long val, unsigned char *le)
+{
+	le[0] = val;
+	le[1] = val >> 8;
+	le[2] = val >> 16;
+	le[3] = val >> 24;
+}
+
+main(int argc, char *argv[])
+{
+	int in_fd, out_fd, len, size;
+	struct stat info;
+	char buf[8192];
+	struct hdr
+	{
+		unsigned long entry_point;
+		unsigned long image_length;
+	} hdr;
+	if (argc != 3)
+	{
+		fprintf(stderr, "usage: mk_type41 <boot-file> <image>\n");
+		exit(1);
+	}
+	if ((in_fd = open(argv[1], 0)) < 0)
+	{
+		fprintf(stderr, "Can't open input file: '%s': %s\n", argv[1], strerror(errno));
+		exit(2);
+	}
+	if ((out_fd = creat(argv[2], 0666)) < 0)
+	{
+		fprintf(stderr, "Can't create outpue file: '%s': %s\n", argv[2], strerror(errno));
+		exit(2);
+	}
+	if (fstat(in_fd, &info) < 0)
+	{
+		fprintf(stderr, "Can't get info on input file: %s\n", strerror(errno));
+		exit(4);
+	}
+	write_prep_boot_partition(out_fd);
+	_LE(0x400, &hdr.entry_point);
+	_LE(info.st_size+0x400, &hdr.image_length);
+	lseek(out_fd, 0x200, 0);
+	if (write(out_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
+	{
+		fprintf(stderr, "Can't write output file: %s\n", strerror(errno));
+		exit(5);
+	}
+	lseek(out_fd, 0x400, 0);
+	while ((len = read(in_fd, buf, sizeof(buf))) > 0)
+	{
+		if (write(out_fd, buf, len) != len)
+		{
+			fprintf(stderr, "Can't write output file: %s\n", strerror(errno));
+			exit(5);
+		}
+	}
+	if (len < 0)
+	{
+		fprintf(stderr, "Can't read input file: %s\n", strerror(errno));
+		exit(6);
+	}
+	close(in_fd);
+	close(out_fd);
+}
+
+/* Adapted from IBM Naked Application Package (NAP) */
+
+#define Align(value,boundary)						\
+	(((value) + (boundary) - 1) & ~((boundary) - 1))
+
+#define HiByte(word)		((word_t)(word) >> 8)
+#define LoByte(word)		((word_t)(word) & 0xFF)
+
+#define HiWord(dword)		((dword_t)(dword) >> 16)
+#define LoWord(dword)		((dword_t)(dword) & 0xFFFF)
+
+/*
+ * Little-endian stuff
+ */
+#define LeWord(word)							\
+	(((word_t)(word) >> 8) | ((word_t)(word) << 8))
+
+#define LeDword(dword)							\
+	(LeWord(LoWord(dword)) << 16) | LeWord(HiWord(dword))
+
+#define PcDword(dword)							\
+	(LeWord(LoWord(dword)) << 16) | LeWord(HiWord(dword))
+
+
+typedef unsigned long dword_t;
+typedef unsigned short word_t;
+typedef unsigned char byte_t;
+typedef byte_t block_t[512];
+typedef byte_t page_t[4096];
+
+/*
+ * Partition table entry
+ *  - from the PReP spec
+ */
+typedef struct partition_entry {
+    byte_t	boot_indicator;
+    byte_t	starting_head;
+    byte_t	starting_sector;
+    byte_t	starting_cylinder;
+
+    byte_t	system_indicator;
+    byte_t	ending_head;
+    byte_t	ending_sector;
+    byte_t	ending_cylinder;
+
+    dword_t	beginning_sector;
+    dword_t	number_of_sectors;
+} partition_entry_t;
+
+#define BootActive	0x80
+#define SystemPrep	0x41
+
+
+/*
+ * Writes the "boot record", which contains the partition table, to the
+ * diskette, followed by the dummy PC boot block and load image descriptor
+ * block.  It returns the number of bytes it has written to the load
+ * image.
+ *
+ * The boot record is the first block of the diskette and identifies the
+ * "PReP" partition.  The "PReP" partition contains the "load image" starting
+ * at offset zero within the partition.  The first block of the load image is
+ * a dummy PC boot block.  The second block is the "load image descriptor"
+ * which contains the size of the load image and the entry point into the
+ * image.  The actual boot image starts at offset 1024 bytes (third sector)
+ * in the partition.
+ */
+void
+write_prep_boot_partition(int out_fd)
+{
+    block_t block;
+    partition_entry_t *pe = (partition_entry_t *)&block[0x1BE];
+    dword_t *entry  = (dword_t *)&block[0];
+    dword_t *length = (dword_t *)&block[4];
+
+    bzero( &block, sizeof block );
+
+    /*
+     * Magic marker
+     */
+    block[510] = 0x55;
+    block[511] = 0xAA;
+
+    /*
+     * Build a "PReP" partition table entry in the boot record
+     *  - "PReP" may only look at the system_indicator
+     */
+    pe->boot_indicator   = BootActive;
+    pe->system_indicator = SystemPrep;
+
+    /*
+     * The first block of the diskette is used by this "boot record" which
+     * actually contains the partition table. (The first block of the
+     * partition contains the boot image, but I digress...)  We'll set up
+     * one partition on the diskette and it shall contain the rest of the
+     * diskette.
+     */
+    pe->starting_head     = 0;		/* zero-based			     */
+    pe->starting_sector   = 2;		/* one-based			     */
+    pe->starting_cylinder = 0;		/* zero-based			     */
+
+    pe->ending_head       = 1;		/* assumes two heads		     */
+    pe->ending_sector     = 18;		/* assumes 18 sectors/track	     */
+    pe->ending_cylinder   = 79;		/* assumes 80 cylinders/diskette     */
+
+    /*
+     * The "PReP" software ignores the above fields and just looks at
+     * the next two.
+     *   - size of the diskette is (assumed to be)
+     *     (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
+     *   - unlike the above sector nunbers, the beginning sector is zero-based!
+     */
+#if 0     
+    pe->beginning_sector  = LeDword(1);
+#else
+    /* This has to be 0 on the PowerStack? */   
+    pe->beginning_sector  = LeDword(0);
+#endif    
+    pe->number_of_sectors = LeDword(2*18*80-1);
+
+    /*
+     * Write the partition table
+     */
+    lseek( out_fd, 0, 0 );
+    write( out_fd, block, sizeof block );
+}
+
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/config.in linux/arch/ppc/config.in
--- pre2.0.7/linux/arch/ppc/config.in	Tue May  7 16:22:21 1996
+++ linux/arch/ppc/config.in	Mon May 27 12:00:57 1996
@@ -2,323 +2,106 @@
 # For a description of the syntax of this configuration file,
 # see the Configure script.
 #
-# This is a stripped down version to just get us what we need to
-# get the kernel to its knees for now.
-#                   -- Cort
+mainmenu_name "Linux Kernel Configuration"
 
-comment 'General setup'
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
 
-#bool 'Kernel math emulation' CONFIG_MATH_EMULATION n
-tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD y
-#bool 'Normal (MFM/RLL) disk and IDE disk/cdrom support' CONFIG_ST506 
-if [ "$CONFIG_ST506" = "y" ]; then
-  comment 'Please see drivers/block/README.ide for help/info on IDE drives'
-  bool '   Use old disk-only driver for primary i/f' CONFIG_BLK_DEV_HD n
-  if [ "$CONFIG_BLK_DEV_HD" = "y" ]; then
-    bool '   Include new IDE driver for secondary i/f support' CONFIG_BLK_DEV_IDE n
-  else
-    bool '   Use new IDE driver for primary/secondary i/f' CONFIG_BLK_DEV_IDE y
-  fi
-  if [ "$CONFIG_BLK_DEV_IDE" = "y" ]; then
-    bool '   Include support for IDE/ATAPI CDROMs' CONFIG_BLK_DEV_IDECD n
-  fi
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+  bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
+  bool 'Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
 fi
+endmenu
 
-#bool 'XT harddisk support' CONFIG_BLK_DEV_XD n
-bool 'Networking support' CONFIG_NET y
-#bool 'Limit memory to low 16MB' CONFIG_MAX_16M n
-bool 'PCI bios support' CONFIG_PCI y
+mainmenu_option next_comment
+comment 'General setup'
+
+bool 'Kernel math emulation' CONFIG_MATH_EMULATION
+bool 'Networking support' CONFIG_NET
+bool 'Limit memory to low 16MB' CONFIG_MAX_16M
+bool 'PCI bios support' CONFIG_PCI
 if [ "$CONFIG_PCI" = "y" ]; then
   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-    bool '   PCI bridge optimization (experimental)' CONFIG_PCI_OPTIMIZE n
-  fi
-  if [ "$CONFIG_BLK_DEV_IDE" = "y" ]; then
-    bool '   PCI Triton IDE Bus Master DMA support' CONFIG_BLK_DEV_TRITON y
+    bool '   PCI bridge optimization (experimental)' CONFIG_PCI_OPTIMIZE
   fi
 fi
-bool 'System V IPC' CONFIG_SYSVIPC y
-tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y
+bool 'System V IPC' CONFIG_SYSVIPC
+tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
+tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 if [ "$CONFIG_BINFMT_ELF" = "y" ]; then
-bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF y
+  bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
 fi
-tristate 'Kernel support for A.OUT binaries' CONFIG_BINFMT_AOUT y
-#bool 'Use -mpentium flag for Pentium-specific optimizations' CONFIG_M586 n
-#if [ "$CONFIG_M586" = "n" ]; then
-#bool 'Use -m486 flag for 486-specific optimizations' CONFIG_M486 y
-#fi
 
-comment 'Loadable module support'
-bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS n
+source drivers/block/Config.in
 
 if [ "$CONFIG_NET" = "y" ]; then
-comment 'Networking options'
-bool 'TCP/IP networking' CONFIG_INET y
-if [ "$CONFIG_INET" = "y" ]; then
-bool 'IP: forwarding/gatewaying' CONFIG_IP_FORWARD n
-bool 'IP: multicasting' CONFIG_IP_MULTICAST n
-bool 'IP: firewalling' CONFIG_IP_FIREWALL n
-bool 'IP: accounting' CONFIG_IP_ACCT n
-tristate 'IP: tunneling' CONFIG_NET_IPIP n
-if [ "$CONFIG_IP_FORWARD" = "y" -a "$CONFIG_IP_FIREWALL" = "y" ]; then
-  bool 'IP: firewall packet logging' CONFIG_IP_FIREWALL_VERBOSE y
-  bool 'IP: masquerading (ALPHA)' CONFIG_IP_MASQUERADE n
-fi
-if [ "$CONFIG_IP_FORWARD" = "y" -a "$CONFIG_IP_MULTICAST" = "y" -a "$CONFIG_NET_IPIP" = "y" ]; then
-  bool 'IP: multicast routing(in progress)' CONFIG_IP_MROUTE n
-fi
-comment '(it is safe to leave these untouched)'
-bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP n
-tristate 'IP: Reverse ARP' CONFIG_INET_RARP n
-bool 'IP: Assume subnets are local' CONFIG_INET_SNARL y
-bool 'IP: Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n
-bool 'IP: Drop source routed frames' CONFIG_IP_NOSR y
-bool 'IP: Allow large windows (not recommended if <16Mb of memory)' CONFIG_SKB_LARGE y
-fi
-bool 'The IPX protocol' CONFIG_IPX n
-bool 'Appletalk DDP' CONFIG_ATALK n
-bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 n
-if [ "$CONFIG_AX25" = "y" ]; then
-  bool 'Amateur Radio NET/ROM' CONFIG_NETROM n
-fi
+  source net/Config.in
 fi
 
+mainmenu_option next_comment
 comment 'SCSI support'
 
-tristate 'SCSI support' CONFIG_SCSI y
-
-if [ "$CONFIG_SCSI" = "n" ]; then
-
-comment 'Skipping SCSI configuration options...'
+tristate 'SCSI support' CONFIG_SCSI
 
-else
-
-comment 'SCSI support type (disk, tape, CDrom)'
-
-dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD y $CONFIG_SCSI
-dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST n $CONFIG_SCSI
-dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR y $CONFIG_SCSI
-dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG n $CONFIG_SCSI
-
-comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
-
-bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN y
-
-comment 'SCSI low-level drivers'
-
-dep_tristate 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n $CONFIG_SCSI
-dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 n $CONFIG_SCSI
-dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 n $CONFIG_SCSI
-dep_tristate 'Adaptec AHA274X/284X/294X support' CONFIG_SCSI_AIC7XXX n $CONFIG_SCSI
-dep_tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n $CONFIG_SCSI
-dep_tristate 'EATA-DMA (DPT, NEC, ATT, Olivetti) support' CONFIG_SCSI_EATA_DMA n $CONFIG_SCSI
-dep_tristate 'EATA-PIO (old DPT PM2001, PM2012A) support' CONFIG_SCSI_EATA_PIO n $CONFIG_SCSI
-dep_tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F n $CONFIG_SCSI
-dep_tristate 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n $CONFIG_SCSI
-bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 y
-if [ "$CONFIG_PCI" = "y" ]; then
-  dep_tristate 'NCR53c7,8xx SCSI support'  CONFIG_SCSI_NCR53C7xx y $CONFIG_SCSI
+if [ "$CONFIG_SCSI" != "n" ]; then
+  source drivers/scsi/Config.in
 fi
-dep_tristate 'Always IN2000 SCSI support (test release)' CONFIG_SCSI_IN2000 n $CONFIG_SCSI
-bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 n
-dep_tristate 'QLOGIC SCSI support' CONFIG_SCSI_QLOGIC n $CONFIG_SCSI
-dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE n $CONFIG_SCSI
-bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 n
-dep_tristate 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR n $CONFIG_SCSI
-dep_tristate '7000FASST SCSI support' CONFIG_SCSI_7000FASST n $CONFIG_SCSI
-dep_tristate 'EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support' CONFIG_SCSI_EATA n $CONFIG_SCSI
-#dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG n $CONFIG_SCSI
-fi
-
+endmenu
 
 if [ "$CONFIG_NET" = "y" ]; then
+  mainmenu_option next_comment
+  comment 'Network device support'
 
-comment 'Network device support'
-
-bool 'Network device support' CONFIG_NETDEVICES y
-if [ "$CONFIG_NETDEVICES" = "n" ]; then
-
-comment 'Skipping network driver configuration options...'
-
-else
-tristate 'Dummy net driver support' CONFIG_DUMMY y
-tristate 'SLIP (serial line) support' CONFIG_SLIP n
-if [ "$CONFIG_SLIP" != "n" ]; then
-  bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED y
-fi
-tristate 'PPP (point-to-point) support' CONFIG_PPP n
-if [ "$CONFIG_PPP" != "n" ]; then
-  bool ' 16 channels instead of 4' CONFIG_PPP_LOTS n
-fi
-if [ "$CONFIG_AX25" = "y" ]; then
-	bool 'Z8530 SCC kiss emulation driver for AX.25' CONFIG_SCC y
-else
-	bool 'Z8530 SCC kiss emulation driver for AX.25' CONFIG_SCC n
-fi
-tristate 'PLIP (parallel port) support' CONFIG_PLIP n
-tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER n
-bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA n
-bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC n
-if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
-	tristate 'WD80*3 support' CONFIG_WD80x3 n
-	tristate 'SMC Ultra support' CONFIG_ULTRA n
-fi
-bool 'AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE n
-bool '3COM cards' CONFIG_NET_VENDOR_3COM n
-if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
-	tristate '3c501 support' CONFIG_EL1 n
-	tristate '3c503 support' CONFIG_EL2 n
-	if [ "$CONFIG_NET_ALPHA" = "y" ]; then
-		tristate '3c505 support' CONFIG_ELPLUS n
-		tristate '3c507 support' CONFIG_EL16 n
-	fi
-	tristate '3c509/3c579 support' CONFIG_EL3 y
-fi
-bool 'Other ISA cards' CONFIG_NET_ISA n
-if [ "$CONFIG_NET_ISA" = "y" ]; then
-	tristate 'Cabletron E21xx support' CONFIG_E2100 n
-	tristate 'DEPCA support' CONFIG_DEPCA n
-	tristate 'EtherWorks 3 support' CONFIG_EWRK3 n
-	if [ "$CONFIG_NET_ALPHA" = "y" ]; then
-		bool 'SEEQ8005 support' CONFIG_SEEQ8005 n
-		tristate 'AT1700 support' CONFIG_AT1700 n
-		tristate 'EtherExpressPro support' CONFIG_EEXPRESS_PRO n
-		tristate 'EtherExpress support' CONFIG_EEXPRESS n
-		bool 'NI5210 support' CONFIG_NI52 n
-		bool 'NI6510 support' CONFIG_NI65 n
-		if [ "$CONFIG_AX25" = "y" ]; then
-			bool 'Ottawa PI and PI/2 support' CONFIG_PI y
-		fi
-		tristate 'WaveLAN support' CONFIG_WAVELAN n
-	fi
-	tristate 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS n
-	tristate 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN n
-	tristate 'HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100 n
-	tristate 'NE2000/NE1000 support' CONFIG_NE2000 n
-	bool 'SK_G16 support' CONFIG_SK_G16 n
-fi
-bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA n
-if [ "$CONFIG_NET_EISA" = "y" ]; then
-	if [ "$CONFIG_NET_ALPHA" = "y" ]; then
-		tristate 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n
-	fi
-	tristate 'Apricot Xen-II on board ethernet' CONFIG_APRICOT n
-	tristate 'DE425, DE434, DE435, DE500 support' CONFIG_DE4X5 n
-	tristate 'DEC 21040 PCI support' CONFIG_DEC_ELCP y
-	bool 'LPL T100V 100Mbs support' CONFIG_LPL_T100 n
-	bool 'PCnet32 (32 bit VLB and PCI LANCE) support' CONFIG_PCNET32 n
-	bool 'Zenith Z-Note support' CONFIG_ZNET n
-fi
-bool 'Pocket and portable adaptors' CONFIG_NET_POCKET n
-if [ "$CONFIG_NET_POCKET" = "y" ]; then
-	bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP n
-	tristate 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n
-	tristate 'D-Link DE620 pocket adaptor support' CONFIG_DE620 n
-#	bool 'Silicom pocket adaptor support' CONFIG_SILICOM_PEA n
-#	bool 'WaveLAN PCMCIA support' CONFIG_WaveLAN n
-#	bool '3 Com 3c589 PCMCIA support' CONFIG_3C589 n
-fi
-bool 'Token Ring driver support' CONFIG_TR n
-if [ "$CONFIG_TR" = "y" ]; then
-	tristate 'IBM Tropic chipset based adaptor support' CONFIG_IBMTR y
-fi
-tristate 'Arcnet support' CONFIG_ARCNET n
-fi
-fi
-
-comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
-
-bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI n
-if [ "$CONFIG_CD_NO_IDESCSI" = "y" ]; then
-  tristate 'Sony CDU31A/CDU33A CDROM support' CONFIG_CDU31A n
-  tristate 'Standard Mitsumi [no XA/Multisession] CDROM support' CONFIG_MCD n
-  tristate 'Experimental Mitsumi [XA/MultiSession] support' CONFIG_MCDX n
-  tristate 'Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support' CONFIG_SBPCD n
-  if [ "$CONFIG_SBPCD" = "y" ]; then
-    bool 'Matsushita/Panasonic, ... second CDROM controller support' CONFIG_SBPCD2 n
-    if [ "$CONFIG_SBPCD2" = "y" ]; then
-      bool 'Matsushita/Panasonic, ... third CDROM controller support' CONFIG_SBPCD3 n
-      if [ "$CONFIG_SBPCD3" = "y" ]; then
-        bool 'Matsushita/Panasonic, ... fourth CDROM controller support' CONFIG_SBPCD4 n
-      fi
-    fi
+  bool 'Network device support' CONFIG_NETDEVICES
+  if [ "$CONFIG_NETDEVICES" = "y" ]; then
+    source drivers/net/Config.in
   fi
-  tristate 'Aztech/Orchid/Okano/Wearnes (non IDE) CDROM support' CONFIG_AZTCD n
-  tristate 'Sony CDU535 CDROM support' CONFIG_CDU535 n
-  tristate 'Goldstar R420 CDROM support' CONFIG_GSCD n
-  tristate 'Philips/LMS CM206 CDROM support' CONFIG_CM206 n
-  tristate 'Experimental Optics Storage DOLPHIN 8000AT CDROM support' CONFIG_OPTCD n
-  tristate 'Sanyo CDR-H94A CDROM support' CONFIG_SJCD n
-  bool 'ISP16/MAD16/Mozart soft configurable cdrom interface support' CONFIG_ISP16_CDI n
+  endmenu
 fi
 
-comment 'Filesystems'
+mainmenu_option next_comment
+comment 'ISDN subsystem'
 
-tristate 'Standard (minix) fs support' CONFIG_MINIX_FS y
-tristate 'Extended fs support' CONFIG_EXT_FS y
-tristate 'Second extended fs support' CONFIG_EXT2_FS y
-tristate 'xiafs filesystem support' CONFIG_XIA_FS n
-tristate 'msdos fs support' CONFIG_MSDOS_FS n
-if [ "$CONFIG_MSDOS_FS" != "n" ]; then
-  tristate 'umsdos: Unix like fs on top of std MSDOS FAT fs' CONFIG_UMSDOS_FS n
+tristate 'ISDN support' CONFIG_ISDN
+if [ "$CONFIG_ISDN" != "n" ]; then
+  source drivers/isdn/Config.in
 fi
-bool '/proc filesystem support' CONFIG_PROC_FS y
-if [ "$CONFIG_INET" = "y" ]; then
-  tristate 'NFS filesystem support' CONFIG_NFS_FS y
-fi
-tristate 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS y
-tristate 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS n
-tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS n
-tristate 'SMB filesystem (to mount WfW shares etc..) support' CONFIG_SMB_FS n
-
-comment 'character devices'
-
-bool 'Cyclades async mux support' CONFIG_CYCLADES n
-bool 'Stallion multiport serial support' CONFIG_STALDRV n
-if [ "$CONFIG_STALDRV" = "y" ]; then
-  tristate '  Stallion EasyIO or EC8/32 support' CONFIG_STALLION n
-  tristate '  Stallion EC8/64, ONboard, Brumby support' CONFIG_ISTALLION n
-fi
-tristate 'Parallel printer support' CONFIG_PRINTER n
-tristate 'Logitech busmouse support' CONFIG_BUSMOUSE n
-tristate 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE n
-if [ "$CONFIG_PSMOUSE" = "y" ]; then
-  bool 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE y
-fi
-tristate 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE n
-tristate 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE n
-
-
-bool 'QIC-02 tape support' CONFIG_QIC02_TAPE n
-if [ "$CONFIG_QIC02_TAPE" = "y" ]; then
-  bool 'Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF y
-if [ "$CONFIG_QIC02_DYNCONF" != "y" ]; then
-
-comment '>>> Edit configuration parameters in ./include/linux/tpqic02.h!'
-
-else
+endmenu
 
-comment '>>> Setting runtime QIC-02 configuration is done with qic02conf'
-comment '>>> Which is available from ftp://ftp.funet.fi/pub/OS/Linux/BETA/QIC-02/'
+mainmenu_option next_comment
+comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
 
+bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+  source drivers/cdrom/Config.in
 fi
-fi
+endmenu
 
-bool 'QIC-117 tape support' CONFIG_FTAPE n
-if [ "$CONFIG_FTAPE" = "y" ]; then
-  int ' number of ftape buffers' NR_FTAPE_BUFFERS 3
-fi
+source fs/Config.in
 
+source drivers/char/Config.in
+
+mainmenu_option next_comment
 comment 'Sound'
 
-tristate 'Sound card support' CONFIG_SOUND y
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+  source drivers/sound/Config.in
+fi
+endmenu
 
+mainmenu_option next_comment
 comment 'Kernel hacking'
 
-#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC n
-bool 'Kernel profiling support' CONFIG_PROFILE n
+#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
+bool 'Kernel profiling support' CONFIG_PROFILE
 if [ "$CONFIG_PROFILE" = "y" ]; then
   int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
-if [ "$CONFIG_SCSI" = "y" ]; then
-bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS y
-fi
+endmenu
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/Makefile linux/arch/ppc/kernel/Makefile
--- pre2.0.7/linux/arch/ppc/kernel/Makefile	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/kernel/Makefile	Mon May 27 12:00:57 1996
@@ -6,10 +6,6 @@
 # unless it's something special (ie not a .c file).
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
-#
-#
-# Modified by Cort Dougan
-#
 
 .c.s:
 	$(CC) $(CFLAGS) -S $<
@@ -24,54 +20,49 @@
 #	$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
 	$(CPP) $(CFLAGS) -D__ASSEMBLY__ $< -o $*.s
 	$(AS) $(ASFLAGS) -o $*.o $*.s
+	rm $*.s
 
 HOST_CC = gcc
 
 OBJS  = misc.o setup.o port_io.o irq.o pci.o traps.o stubs.o process.o \
-	signal.o raw_printf.o ramdisk.o 
+	signal.o raw_printf.o ksyms.o time.o ramdisk_drvr.o syscalls.o \
+	support.o ptrace.o
 
-all: head.o kernel.o
+all: head.o kernel.o no_ramdisk.o ramdisk.o
 
 head.o: head.s
 head.s: head.S $(TOPDIR)/include/linux/tasks.h ppc_defs.h
 
-ppc_defs.h: mk_defs $(TOPDIR)/include/asm/mmu.h $(TOPDIR)/include/asm/processor.h $(TOPDIR)/include/asm/pgtable.h $(TOPDIR)/include/asm/ptrace.h
+ppc_defs.h: mk_defs
 #	simppc mk_defs -- $@
-	mk_defs ppc_defs.h
+	mk_defs $@
 
-ramdisk.o: ramdisk.s
+no_ramdisk.o: no_ramdisk.S
 
-ramdisk.s: ramdisk.image mk_ramdisk
-	mk_ramdisk ramdisk.image ramdisk.s
+ramdisk.o: ramdisk.image mk_ramdisk
+	mk_ramdisk ramdisk.image $*.s
+	$(AS) -o $@ $*.s
+	rm $*.s
 
 mk_ramdisk: mk_ramdisk.c
-	$(HOST_CC) -o mk_ramdisk mk_ramdisk.c	
-
-
-
-cortstrip : cortstrip.c
-	${HOST_CC} -o cortstrip cortstrip.c
-
-mkboot : mkboot.c
-	${HOST_CC} -o mkboot mkboot.c
-
+	${HOST_CC} -o mk_ramdisk mk_ramdisk.c	
+	
 mk_defs: mk_defs.c $(TOPDIR)/include/asm/mmu.h $(TOPDIR)/include/asm/processor.h $(TOPDIR)/include/asm/pgtable.h $(TOPDIR)/include/asm/ptrace.h
-#	$(CC) ${CFLAGS} -c mk_defs -T ld.script-user -Ttext 0x1000 mk_defs.c
-#	$(LD) -T ld.script-user -Ttext 0x1000  -o mk_defs mk_defs.o
-	$(HOST_CC) -DMKDEFS ${CFLAGS} -o mk_defs mk_defs.c
+#	cc.ppc ${CFLAGS} -o mk_defs -T ld.script-user -Ttext 0x1000 mk_defs.c
+	cc.ppc ${CFLAGS} -o mk_defs mk_defs.c
 
 
 kernel.o: $(OBJS)
 	$(LD) -r -o kernel.o $(OBJS)
 	sync
 
+mkboot: mkboot.c
+	${HOST_CC} -o $@ -Iinclude mkboot.c
 
 dep:
 	$(CPP) -M *.c > .depend
-
+	
 fastdep:
-	$(CPP) -M *.c > .depend
-
 
 modules:
 
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S
--- pre2.0.7/linux/arch/ppc/kernel/head.S	Tue May  7 16:22:21 1996
+++ linux/arch/ppc/kernel/head.S	Mon May 27 12:00:57 1996
@@ -1,5 +1,6 @@
 #include "ppc_asm.tmpl"
 #include "ppc_defs.h"
+#include <linux/errno.h>
 
 #define SYNC() \
 	isync; \
@@ -14,7 +15,7 @@
  * Increment a [64 bit] statistic counter
  * Uses R2, R3
  */
-#define BUMP(ctr) /*\
+#define BUMP(ctr) \
 	lis	r2,ctr@h; \
 	ori	r2,r2,ctr@l; \
 	lwz	r3,4(r2); \
@@ -22,10 +23,10 @@
 	stw	r3,4(r2); \
 	lwz	r3,0(r2); \
 	addze	r3,r3; \
-	stw	r3,0(r2)*/
+	stw	r3,0(r2)
 
 /* The same as 'BUMP' but running unmapped (TLB code) */	
-#define BUMP_UNMAPPED(ctr) /*\
+#define BUMP_UNMAPPED(ctr) \
 	mfspr	r0,XER; \
 	lis	r2,ctr@h; \
 	ori	r2,r2,ctr@l; \
@@ -37,7 +38,7 @@
 	lwz	r3,0(r2); \
 	addze	r3,r3; \
 	mtspr	XER,r0; \
-	stw	r3,0(r2)*/
+	stw	r3,0(r2)
 
 /* These macros can be used to generate very raw traces of low-level */
 /* operations (where printf, etc. can't help).  All they provide is */
@@ -49,9 +50,9 @@
 /* gather some data without disturbing anything - Heisenberg are you watching? */
 
 /* CAUTION! Don't turn on more than one of these at once! */	
-/* #define DO_TRAP_TRACE   */
-/* #define DO_TLB_TRACE    */
-/* #define DO_RFI_TRACE   */
+/* #define DO_TRAP_TRACE  /* */
+/* #define DO_TLB_TRACE   /* */
+/* #define DO_RFI_TRACE   /* */
 
 #ifdef DO_RFI_TRACE
 #define DO_RFI_TRACE_UNMAPPED(mark) \
@@ -237,7 +238,7 @@
 
 /* This instruction is not implemented on the PPC 603 */
 #define tlbia \
-	li	r4,32; \
+	li	r4,64; \
 	mtspr	CTR,r4; \
 	lis	r4,0x9000; \
 0:	tlbie	r4; \
@@ -246,10 +247,10 @@
 
 /* Validate kernel stack - check for overflow */
 #define CHECK_STACK()
-#define _CHECK_STACK()\
+#define _CHECK_STACK() \
 	mtspr	SPR0,r3; \
-	lis	r2,current@ha; \
-	lwz	r2,current@l(r2); \
+	lis	r2,current_set@ha; \
+	lwz	r2,current_set@l(r2); \
 	lwz	r2,KERNEL_STACK_PAGE(r2); \
 	lis	r3,sys_stack@h; \
 	ori	r3,r3,sys_stack@l; \
@@ -308,7 +309,13 @@
 	stw	r2,_DAR(r1); \
 	mfspr	r2,DSISR; \
 	stw	r2,_DSISR(r1); \
-	mfspr	r2,HASH1; \
+	mfspr	r2,PVR;			/* Check for 603/603e */ \
+	srwi	r2,r2,16; \
+	cmpi	0,r2,3;			/* 603 */ \
+	beq	22f; \
+	cmpi	0,r2,6;			/* 603e */ \
+	bne	24f; \
+22:	mfspr	r2,HASH1; 		/* Note: these registers exist only on 603 */ \
 	stw	r2,_HASH1(r1); \
 	mfspr	r2,HASH2; \
 	stw	r2,_HASH2(r1); \
@@ -319,7 +326,8 @@
 	mfspr	r2,ICMP; \
 	stw	r2,_ICMP(r1); \
 	mfspr	r2,DCMP; \
-	stw	r2,_DCMP(r1)
+	stw	r2,_DCMP(r1); \
+24:	
 	
 #define SAVE_INT_REGS(mark) \
 	mtspr	SPR0,r1;	/* Save current stack pointer */ \
@@ -342,10 +350,15 @@
 	ori	r2,r2,MSR_|MSR_DR|MSR_IR; \
 	mtspr	SRR1,r2; \
 	rfi; \
-05:	lis	r2,current@ha; \
-	lwz	r2,current@l(r2); \
+05:	lis	r2,current_set@ha; \
+	lwz	r2,current_set@l(r2); \
 	mfspr	r1,SPR2; \
 	stw	r1,TSS+LAST_PC(r2); \
+	mfspr	r1,SPR0; \
+	stw	r1,TSS+USER_STACK(r2); \
+	lwz	r1,TSS+KSP(r2); \
+	subi	r1,r1,INT_FRAME_SIZE;	/* Make room for frame */ \
+	stw	r1,TSS+PT_REGS(r2); 	/* Save regs pointer for 'ptrace' */ \
 	lwz	r1,TSS+KSP(r2); \
 	b	20f; \
 10:	mfspr	r2,SPR2;	/* Restore CCR */ \
@@ -362,7 +375,7 @@
 	mtspr	SRR1,r2; \
 	SYNC(); \
 	rfi; \
-20:   SAVE_REGS(mark); \
+20:	SAVE_REGS(mark); \
 	CHECK_STACK()
 
 #define RETURN_FROM_INT(mark) \
@@ -370,8 +383,8 @@
 	li	r4,0; \
 	ori	r4,r4,MSR_EE; \
 	andc	r0,r0,r4; \
+	sync; 			/* Some chip revs need this... */ \
 	mtmsr	r0; \
-	SYNC(); \
 	lis	r2,intr_count@ha; /* Need to run 'bottom half' */ \
 	lwz	r3,intr_count@l(r2); \
 	cmpi	0,r3,0; \
@@ -392,13 +405,13 @@
 00:	lwz	r2,_MSR(r1); /* Returning to user mode? */ \
 	andi.	r2,r2,MSR_PR; \
 	beq+	10f;		/* no - no need to mess with stack */ \
-	lis	r2,kernel_pages_are_copyback@ha; \
+/*	lis	r2,kernel_pages_are_copyback@ha; \
 	lwz	r2,kernel_pages_are_copyback@l(r2); \
 	cmpi	0,r2,0; \
 	beq	05f; \
-	bl	_EXTERN(flush_instruction_cache); \
-05:	lis	r3,current@ha;	/* need to save kernel stack pointer */ \
-	lwz	r3,current@l(r3); \
+	bl	_EXTERN(flush_instruction_cache); */ \
+05:	lis	r3,current_set@ha;	/* need to save kernel stack pointer */ \
+	lwz	r3,current_set@l(r3); \
 	addi	r4,r1,INT_FRAME_SIZE;	/* size of frame */ \
 	stw	r4,TSS+KSP(r3); \
 	lwz	r4,STATE(r3);	/* If state != 0, can't run */ \
@@ -444,14 +457,59 @@
 	rfi
 
 _TEXT()
+/*
+ * This code may be executed by a bootstrap process.  If so, the
+ * purpose is to relocate the loaded image to it's final location
+ * in memory.
+ *    R3: End of image
+ *    R4: Start of image - 0x400
+ *   R11: Start of command line string
+ *   R12: End of command line string
+ *   R30: 'BeBx' if this is a BeBox
+ *
+ */
 	.globl	_start
-_start:
-	.globl  _stext
+	.globl	_stext
 _stext:
+_start:
+	addi	r4,r4,0x400	/* Point at start of image */
+	li	r5,0		/* Load address */
+	subi	r4,r4,4		/* Adjust for auto-increment */
+	subi	r5,r5,4
+	subi	r3,r3,4
+00:	lwzu	r0,4(r4)	/* Fast move */
+	stwu	r0,4(r5)
+	cmp	0,r3,r4
+	bne	00b
+	li	r5,0x100	/* Actual code starts here */
+	mtlr	r5
+	blr
 
 hang:
 	ori	r0,r0,0
 	b	hang
+
+/*
+ * BeBox CPU #1 vector & code
+ */	
+_ORG(0x0080)
+	.globl	BeBox_CPU1_vector
+BeBox_CPU1_vector:
+	.long	0
+BeBox_CPU1_reset:
+	li	r1,BeBox_CPU1_vector@l
+	li	r2,0
+	stw	r2,0(r1)
+00:	lwz	r2,0(r1)
+	cmpi	0,r2,0
+	bne	10f
+	li	r2,10000
+	mtctr	r2
+02:	nop
+	bdnz	02b
+	b	00b
+10:	mtlr	r1
+	blr	
 	
 _ORG(0x0100)
 
@@ -506,7 +564,8 @@
 	b	SystemCall
 
 _ORG(0x0D00)
-DEFAULT_TRAP(0x0D00)	
+	b	SingleStep
+
 _ORG(0x0E00)
 DEFAULT_TRAP(0x0E00)	
 _ORG(0x0F00)
@@ -649,7 +708,7 @@
  * the only juncture [as far as the OS goes] where the data cache may
  * contain instructions, e.g. after a disk read.
  */
-#define NUM_CACHE_LINES 128*2
+#define NUM_CACHE_LINES 128*4
 #define CACHE_LINE_SIZE 32 
 cache_flush_buffer:
 	.space	NUM_CACHE_LINES*CACHE_LINE_SIZE	/* CAUTION! these need to match hardware */
@@ -658,12 +717,40 @@
 _ORG(0x4000)
 #endif
 
+
 /*
  * Hardware reset [actually from bootstrap]
  * Initialize memory management & call secondary init
+ * Registers initialized by bootstrap:
+ *   R11: Start of command line string
+ *   R12: End of command line string
+ *   R30: 'BeBx' if this is a BeBox
  */	
 Reset:
 	lis	r7,0xF000		/* To mask upper 4 bits */
+#define IS_BE_BOX	0x42654278	/* 'BeBx' */
+	lis	r1,isBeBox@h
+	ori	r1,r1,isBeBox@l
+	andc	r1,r1,r7
+/* See if this is a CPU other than CPU#1 */
+/* This [currently] happens on the BeBox */
+	lwz	r2,0(r1)
+	cmpi	0,r2,0
+	bne	Reset_BeBox_CPU1
+/* Save machine type indicator */
+	li	r2,0
+	lis	r3,IS_BE_BOX>>16
+	ori	r3,r3,IS_BE_BOX&0xFFFF
+	cmp	0,r30,r3
+	bne	00f
+	li	r2,1
+	mr	r11,r28
+	mr	r12,r29
+	lis	r5,BeBox_CPU1_vector@h
+	ori	r5,r5,BeBox_CPU1_vector@l
+	andc	r5,r5,r7		/* Tell CPU #1 where to go */
+00:	stw	r2,0(r1)
+	stw	r30,4(r1)
 /* Copy argument string */
 	li	r0,0		/* Null terminate string */
 	stb	r0,0(r12)
@@ -723,6 +810,17 @@
 	lwz	r0,4(r3)
 	mtspr	IBAT2L,r0
 	mtspr	DBAT2L,r0
+#if 0	
+	lis	r3,BAT3@h
+	ori	r3,r3,BAT3@l
+	andc	r3,r3,r7	/* make unmapped address */
+	lwz	r0,0(r3)
+	mtspr	IBAT3U,r0
+	mtspr	DBAT3U,r0
+	lwz	r0,4(r3)
+	mtspr	IBAT3L,r0
+	mtspr	DBAT3L,r0
+#endif	
 /* Now we can turn on the MMU */
 	mfmsr	r3
 	ori	r3,r3,MSR_DR|MSR_IR
@@ -736,7 +834,6 @@
 10:	bl	_EXTERN(MMU_init)	/* initialize MMU environment */
 DO_RFI_TRACE_MAPPED(0xDEAD0100)	
 /* Withdraw BAT2->RAM mapping */
-#if 1
 	lis	r7,0xF000		/* To mask upper 4 bits */
 	lis	r3,20f@h
 	ori	r3,r3,20f@l
@@ -750,7 +847,7 @@
 DO_RFI_TRACE_MAPPED(0xDEAD0200)	
 	SYNC
 	rfi
-20:
+20:	
 DO_RFI_TRACE_UNMAPPED(0xDEAD0400)	
 20:	lis	r3,BAT2@h
 	ori	r3,r3,BAT2@l
@@ -761,8 +858,6 @@
 	lwz	r0,4(r3)
 	mtspr	IBAT2L,r0
 	mtspr	DBAT2L,r0
-#endif
-
 /* Load up the kernel context */
 	lis	r2,init_task@h
 	ori	r2,r2,init_task@l
@@ -818,7 +913,6 @@
 	SYNC
 	rfi				/* enables MMU */
 30:
-DO_RFI_TRACE_MAPPED(0xDEAD0600)
 /* Turn on L1 Data Cache */
 	mfspr	r3,HID0		/* Caches are controlled by this register */
 	ori	r4,r3,(HID0_ICE|HID0_ICFI)
@@ -828,11 +922,81 @@
 	sync
 	mtspr	HID0,r4
 	mtspr	HID0,r3
-/* L1 cache enable */	
-	b	_EXTERN(start_kernel)		/* call main code */
+/* L1 cache enable */
+	mfspr	r2,PVR			/* Check for 603/603e */
+	srwi	r2,r2,16
+	cmpi	0,r2,4			/* 604 */
+	bne	40f
+	mfspr	r3,HID0			/* Turn on 604 specific features */
+	ori	r3,r3,(HID0_SIED|HID0_BHTE)
+	mtspr	HID0,r3
+40:	b	_EXTERN(start_kernel)		/* call main code */
 	.long	0		# Illegal!
 
 /*
+ * BeBox CPU #2 runs here
+ */
+Reset_BeBox_CPU1:	
+	lis	r1,CPU1_stack@h
+	ori	r1,r1,CPU1_stack@l
+	li	r2,0x0FFF	/* Mask stack address down to page boundary */
+	andc	r1,r1,r2
+	subi	r1,r1,INT_FRAME_SIZE	/* Padding for first frame */
+	lis	r30,CPU1_trace@h
+	ori	r30,r30,CPU1_trace@l
+	andc	r30,r30,r7
+	li	r5,1
+	stw	r5,0(r30)
+	li	r2,0		/* TOC pointer for nanokernel */
+	li	r0,MSR_		/* Make sure FPU enabled */
+	mtmsr	r0
+/* Initialize BAT registers */
+	lis	r3,BAT0@h
+	ori	r3,r3,BAT0@l
+	andc	r3,r3,r7	/* make unmapped address */
+	lwz	r0,0(r3)
+	mtspr	IBAT0U,r0
+	mtspr	DBAT0U,r0
+	lwz	r0,4(r3)
+	mtspr	IBAT0L,r0
+	mtspr	DBAT0L,r0
+	lis	r3,BAT1@h
+	ori	r3,r3,BAT1@l
+	andc	r3,r3,r7	/* make unmapped address */
+	lwz	r0,0(r3)
+	mtspr	IBAT1U,r0
+	mtspr	DBAT1U,r0
+	lwz	r0,4(r3)
+	mtspr	IBAT1L,r0
+	mtspr	DBAT1L,r0
+	lis	r3,TMP_BAT2@h
+	ori	r3,r3,TMP_BAT2@l
+	andc	r3,r3,r7	/* make unmapped address */
+	lwz	r0,0(r3)
+	mtspr	IBAT2U,r0
+	mtspr	DBAT2U,r0
+	lwz	r0,4(r3)
+	mtspr	IBAT2L,r0
+	mtspr	DBAT2L,r0
+/* Now we can turn on the MMU */
+	mfmsr	r3
+	ori	r3,r3,MSR_DR|MSR_IR
+	mtspr	SRR1,r3
+	lis	r3,10f@h
+	ori	r3,r3,10f@l
+	mtspr	SRR0,r3
+	li	r5,2
+	stw	r5,0(r30)
+	SYNC
+	rfi				/* enables MMU */
+10:
+	lis	r30,CPU1_trace@h
+	ori	r30,r30,CPU1_trace@l
+	li	r5,3
+	stw	r5,0(r30)
+	bl	_EXTERN(BeBox_CPU1)
+
+/*
  * Machine Check (Bus Errors, etc)
  */
 MachineCheck:	
@@ -846,25 +1010,30 @@
  * Data Access exception
  */
 DataAccess:
-	TRACE_TRAP(0x0300)
+/*	TRACE_TRAP(0x0300) */
 	SAVE_INT_REGS(0x0300)
 	SAVE_PAGE_FAULT_REGS(0x0300)
 	BUMP(__Data_Page_Faults)
 	mr	r3,r1		/* Set pointer to saved regs */
 	bl	_EXTERN(DataAccessException)
+#if 0
+	bl	_EXTERN(flush_instruction_cache)
+#endif	
 	RETURN_FROM_INT(0x0300)
 
 /*
  * Instruction Access Exception
  */
 InstructionAccess:
-	TRACE_TRAP(0x0400)
+/*	TRACE_TRAP(0x0400) */
 	SAVE_INT_REGS(0x0400)
 	SAVE_PAGE_FAULT_REGS(0x0400)
 	BUMP(__Instruction_Page_Faults)
 	mr	r3,r1		/* Set pointer to saved regs */
 	bl	_EXTERN(InstructionAccessException)
+#if 0
 	bl	_EXTERN(flush_instruction_cache)
+#endif	
 	RETURN_FROM_INT(0x0400)
 
 /*
@@ -898,6 +1067,19 @@
 	RETURN_FROM_INT(0x0700)
 
 /*
+ * Single Step Exception
+ */
+SingleStep:
+	SAVE_INT_REGS(0x0D00)
+	SAVE_PAGE_FAULT_REGS(0x0D00)
+	mr	r3,r1		/* Set pointer to saved regs */
+	bl	_EXTERN(SingleStepException)
+#if 0
+	bl	_EXTERN(flush_instruction_cache)
+#endif	
+	RETURN_FROM_INT(0x0D00)
+
+/*
  * Floating point [not available, etc]
  */
 FloatingPointCheck:	
@@ -909,8 +1091,9 @@
 
 /*
  * System Call exception
- */	
+ */
 SystemCall:
+/*	TRACE_TRAP(0x0C00) */
 	SAVE_INT_REGS(0x0C00)
 	lwz	r2,_CCR(r1)	/* Clear SO bit in CR */
 	lis	r9,0x1000
@@ -923,11 +1106,15 @@
 	cmpi	0,r3,0		/* Check for restarted system call */
 	bge	99f
 	b	20f
-10:	lis	r2,sys_call_table@h
+10:	lis	r2,current_set@ha
+	lwz	r2,current_set@l(r2)
+	lwz	r2,TASK_FLAGS(r2)
+	andi.	r2,r2,PF_TRACESYS
+	bne	50f
+	lis	r2,sys_call_table@h
 	ori	r2,r2,sys_call_table@l
 	slwi	r0,r0,2
 	lwzx	r2,r2,r0	/* Fetch system call handler [ptr] */
- 
 	mtlr	r2
 	mr	r9,r1
 	blrl			/* Call handler */
@@ -935,11 +1122,56 @@
 	cmpi	0,r3,0
 	bge	30f
 	neg	r3,r3
-	lwz	r2,_CCR(r1)	/* Set SO bit in CR */
+	cmpi	0,r3,ERESTARTNOHAND
+	bne	22f
+	li	r3,EINTR
+22:	lwz	r2,_CCR(r1)	/* Set SO bit in CR */
 	oris	r2,r2,0x1000
 	stw	r2,_CCR(r1)
 30:	stw	r3,GPR3(r1)	/* Update return value */
+#if 0
+	mr	r3,r1
+	bl	_EXTERN(trace_syscall)
+#endif
+	b	99f
+/* Traced system call support */
+50:	bl	_EXTERN(syscall_trace)
+	lwz	r0,GPR0(r1)	/* Restore original registers */
+	lwz	r3,GPR3(r1)
+	lwz	r4,GPR4(r1)
+	lwz	r5,GPR5(r1)
+	lwz	r6,GPR6(r1)
+	lwz	r7,GPR7(r1)
+	lwz	r8,GPR8(r1)
+	lwz	r9,GPR9(r1)
+	lis	r2,sys_call_table@h
+	ori	r2,r2,sys_call_table@l
+	slwi	r0,r0,2
+	lwzx	r2,r2,r0	/* Fetch system call handler [ptr] */
+	mtlr	r2
+	mr	r9,r1
+	blrl			/* Call handler */
+	stw	r3,RESULT(r1)	/* Save result */	
+	cmpi	0,r3,0
+	bge	60f
+	neg	r3,r3
+	cmpi	0,r3,ERESTARTNOHAND
+	bne	52f
+	li	r3,EINTR
+52:	lwz	r2,_CCR(r1)	/* Set SO bit in CR */
+	oris	r2,r2,0x1000
+	stw	r2,_CCR(r1)
+60:	stw	r3,GPR3(r1)	/* Update return value */
+	bl	_EXTERN(syscall_trace)
 99:
+#if 0 /* This isn't needed here - already in RETURN_FROM_INT */
+	lis	r2,kernel_pages_are_copyback@ha
+	lwz	r2,kernel_pages_are_copyback@l(r2)
+	cmpi	0,r2,0
+	beq	00f
+	bl	_EXTERN(flush_instruction_cache)	/* Ensure cache coherency */
+00:
+#endif
 	RETURN_FROM_INT(0x0C00)
 
 /*
@@ -1205,6 +1437,7 @@
 	xoris	r0,r0,MSR_TGPR>>16
 	mtcrf	0x80,r3		/* Restore CR0 */
 	ori	r0,r0,MSR_FP	/* Need to keep FP enabled */
+	sync			/* Some chip revs have problems here... */
 	mtmsr	r0
 	b	InstructionAccess
 
@@ -1233,6 +1466,7 @@
 	xoris	r0,r0,MSR_TGPR>>16
 	mtcrf	0x80,r3		/* Restore CR0 */
 	ori	r0,r0,MSR_FP	/* Need to keep FP enabled */
+	sync			/* Some chip revs have problems here... */
 	mtmsr	r0
 	b	DataAccess
 
@@ -1246,22 +1480,11 @@
 	mfspr	r3,HID0	/* Caches are controlled by this register */
 	li	r4,0
 	ori	r4,r4,(HID0_ICE|HID0_ICFI)
+	or	r3,r3,r4	/* Need to enable+invalidate to clear */
+	mtspr	HID0,r3
 	andc	r3,r3,r4
-	isync
-	mtspr	HID0,r3		/* Disable cache */
-	isync
-	ori	r3,r3,HID0_ICFI
-	isync
-	mtspr	HID0,r3		/* Invalidate cache */
-	isync
-	andc	r3,r3,r4
-	isync
-	mtspr	HID0,r3		/* Invalidate (step 2) */
-	isync
-	ori	r3,r3,HID0_ICE
-	isync
-	mtspr	HID0,r3		/* Enable cache */
-	isync
+	ori	r3,r3,HID0_ICE	/* Enable cache */
+	mtspr	HID0,r3
 	mtlr	r5
 	blr
 
@@ -1284,6 +1507,23 @@
 	addi	r3,r3,CACHE_LINE_SIZE	/* Next line, please */
 	bdnz	00b	
 10:	blr
+
+/*
+ * Flush a particular page from the DATA cache
+ * Note: this is necessary because the instruction cache does *not*
+ * snoop from the data cache.
+ *	void flush_page(void *page)
+ */
+_GLOBAL(flush_page)
+	li	r4,0x0FFF
+	andc	r3,r3,r4		/* Get page base address */
+	li	r4,4096/CACHE_LINE_SIZE	/* Number of lines in a page */
+	mtctr	r4
+00:	dcbf	0,r3			/* Clear line */
+	icbi	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	00b
+	blr
 	
 /*
  * This routine switches between two different tasks.  The process
@@ -1348,6 +1588,7 @@
 	mtsr	SR15,r0
 	tlbia				/* Invalidate entire TLB */
 	BUMP(__TLBIAs)
+	bl	_EXTERN(flush_instruction_cache)
 #ifdef TLB_STATS
 /* TEMP */
 	lis	r2,DataLoadTLB_trace_ptr@h
@@ -1368,8 +1609,10 @@
 00:	stw	r4,0(r2)
 /* TEMP */	
 #endif
+#if 0
 	lwz	r2,_NIP(r1)	/* Force TLB/MMU hit */
 	lwz	r2,0(r2)
+#endif	
 	RETURN_FROM_INT(0xF000)
 	
 
@@ -1422,11 +1665,17 @@
 sdata:
 	.space	2*4096
 sys_stack:
+	.space	2*4096
+CPU1_stack:	
 
 	.globl	empty_zero_page
 empty_zero_page:
 	.space	4096
 
+	.globl	swapper_pg_dir
+swapper_pg_dir:
+	.space	4096	
+
 /*
  * This space gets a copy of optional info passed to us by the bootstrap
  * Used to pass parameters into the kernel like root=/dev/sda1, etc.
@@ -1495,3 +1744,4 @@
 _RFI_ptr:  .long	_RFI_DATA
 	.text	
 #endif
+
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/include/elf/ChangeLog linux/arch/ppc/kernel/include/elf/ChangeLog
--- pre2.0.7/linux/arch/ppc/kernel/include/elf/ChangeLog	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/include/elf/ChangeLog	Mon May 27 12:00:57 1996
@@ -0,0 +1,155 @@
+Tue Jun 20 10:18:28 1995  Jeff Law  (law@snake.cs.utah.edu)
+
+	* hppa.h (CPU_PA_RISC1_0): Protect from redefinitions.
+	(CPU_PA_RISC1_1): Likewise.
+
+Wed Mar  8 18:14:37 1995  Michael Meissner  <meissner@tiktok.cygnus.com>
+
+	* ppc.h: New file for PowerPC support.
+
+Tue Feb 14 13:59:13 1995  Michael Meissner  <meissner@tiktok.cygnus.com>
+
+	* common.h (EM_PPC): Use offical value of 20, not 17.
+	(EM_PPC_OLD): Define this to be the old value of EM_PPC.
+
+
+Tue Jan 24 09:40:59 1995  Michael Meissner  <meissner@tiktok.cygnus.com>
+
+	* common.h (EM_PPC): New macro, PowerPC machine id.
+
+Tue Jan 17 10:51:38 1995  Ian Lance Taylor  <ian@sanguine.cygnus.com>
+
+	* mips.h (SHT_MIPS_MSYM, SHT_MIPS_DWARF, SHT_MIPS_EVENTS): Define.
+
+
+Mon Oct 17 13:43:59 1994  Ian Lance Taylor  <ian@sanguine.cygnus.com>
+
+	* internal.h (Elf_Internal_Shdr): Remove rawdata and size fields.
+	Add bfd_section field.
+
+Tue May 24 16:11:50 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+	* mips.h (Elf32_External_gptab): Define.
+
+Mon May 16 13:22:04 1994  Jeff Law  (law@snake.cs.utah.edu)
+
+	* common.h (EM_HPPA): Delete.
+	(EM_PARISC): Add.
+	* hppa.h: New file.
+
+Mon May  9 13:27:03 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+	* common.h (SHN_LORESERVE): Rename from SHN_LORESERV.
+	(ELF32_R_TYPE, ELF32_R_INFO): Don't rely on size of unsigned char.
+	(ELF64_R_TYPE): Don't rely on size of unsigned long.
+
+Mon Apr 25 15:53:09 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+	* internal.h (Elf_Internal_Shdr): Use PTR, not void *.
+
+Fri Mar 11 00:34:59 1994  Peter Schauer  (pes@regent.e-technik.tu-muenchen.de)
+
+	* mips.h (SHN_MIPS_TEXT, SHN_MIPS_DATA):  Define.
+
+Sat Mar  5 14:08:54 1994  Peter Schauer  (pes@regent.e-technik.tu-muenchen.de)
+
+	* internal.h:  Remove Elf32_*, Elf64_* typedefs.  These names
+	cause conflicts with system headers, e.g. link.h in gdb/solib.c.
+	Combine 32- and 64-bit versions of *_Internal_Dyn.
+	* common.h:  Replace uses of Elf64_Word, Elf64_Xword typedefs
+	by their expansion.
+	* mips.h:  Replace uses of Elf32_Word, Elf32_Sword, Elf32_Addr
+	typedefs by their expansion. Add DT_MIPS_RLD_MAP definition.
+
+Fri Feb 18 10:39:54 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+	* common.h (EM_CYGNUS_POWERPC): Define.  This may be temporary,
+	depending upon how quickly I can find a real PowerPC ABI.
+
+Mon Feb  7 08:27:13 1994  Jim Kingdon  (kingdon@lioth.cygnus.com)
+
+	* internal.h: Change HOST_64_BIT to BFD_HOST_64_BIT.
+
+Wed Feb  2 14:12:18 1994  Jim Kingdon  (kingdon@lioth.cygnus.com)
+
+	* common.h: Add comments regarding value of EM_HPPA and how to
+	pick an unofficial value.
+
+Wed Nov 17 17:14:26 1993  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+	* mips.h (SHT_MIPS_OPTIONS): Define.
+
+Mon Nov  8 17:57:00 1993  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+	* mips.h: Added some more MIPS ABI macro definitions.
+
+Wed Nov  3 22:07:17 1993  Ken Raeburn  (raeburn@rtl.cygnus.com)
+
+	* common.h (EM_MIPS_RS4_BE): New macro.
+
+Tue Oct 12 07:28:18 1993  Ian Lance Taylor  (ian@cygnus.com)
+
+	* mips.h: New file.  MIPS ABI specific information.
+
+Mon Jun 21 13:13:43 1993  Ken Raeburn  (raeburn@poseidon.cygnus.com)
+
+	* internal.h: Combined 32- and 64-bit versions of all structures
+	except *_Internal_Dyn.  This will simply the assembler interface,
+	and some bfd code.
+
+Tue May 25 02:00:16 1993  Ken Raeburn  (raeburn@cambridge.cygnus.com)
+
+	* external.h, internal.h, common.h: Added 64-bit versions of some
+	structures and macros.  Renamed old versions to put "32" in the
+	name.  Some are unchanged.
+
+Thu Apr 29 12:12:20 1993  Ken Raeburn  (raeburn@deneb.cygnus.com)
+
+	* common.h (EM_HPPA, NT_VERSION, STN_UNDEF, DT_*): New macros.
+	* external.h (Elf_External_Dyn): New type.
+
+	* internal.h (Elf_Intenral_Shdr): New field `size'.
+	(Elf_Internal_Dyn): New type.
+
+Tue Apr 20 16:03:45 1993  Fred Fish  (fnf@cygnus.com)
+
+	* dwarf.h (LANG_CHILL):  Change value to one randomly picked in
+	the user defined range, to reduce probability of collisions.
+
+Sun Nov 15 09:34:02 1992  Fred Fish  (fnf@cygnus.com)
+
+	* dwarf.h (AT_src_coords):  Whitespace change only.
+	* dwarf.h (AT_body_begin, AT_body_end, LANG_MODULA2):
+	Add from latest gcc.
+	* dwarf.h (LANG_CHILL):  Add as GNU extension.
+
+Sat Aug  1 13:46:53 1992  Fred Fish  (fnf@cygnus.com)
+
+	* dwarf.h:  Replace with current version from gcc distribution.
+
+Fri Jun 19 19:05:09 1992  John Gilmore  (gnu at cygnus.com)
+
+	* internal.h:  Add real struct tags to all the Type_Defs, so they
+	can be used in prototypes where the Type_Defs are not known.
+
+Fri Apr  3 20:58:58 1992  Mark Eichin  (eichin at cygnus.com)
+
+	* common.h: added ELF_R_{SYM,TYPE,INFO} for handling relocation
+	info
+	added EM_MIPS, and corrected value of EM_860 based on System V ABI
+	manual. 
+
+	* external.h: added Elf_External_{Rel,Rela}.
+
+	* internal.h: added Elf_Internal_{Rel,Rela}.
+	added rawdata to Elf_Internal_Shdr.
+
+Sat Nov 30 20:43:59 1991  Steve Chamberlain  (sac at rtl.cygnus.com)
+
+	* common.h, dwarf.h, external.h, internal.h, ChangeLog; moved from
+	../elf-<foo>
+
+
+Local Variables:
+version-control: never
+End:
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/include/elf/common.h linux/arch/ppc/kernel/include/elf/common.h
--- pre2.0.7/linux/arch/ppc/kernel/include/elf/common.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/include/elf/common.h	Mon May 27 12:00:57 1996
@@ -0,0 +1,232 @@
+/* ELF support for BFD.
+   Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+
+   Written by Fred Fish @ Cygnus Support, from information published
+   in "UNIX System V Release 4, Programmers Guide: ANSI C and
+   Programming Support Tools".
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+/* This file is part of ELF support for BFD, and contains the portions
+   that are common to both the internal and external representations.
+   For example, ELFMAG0 is the byte 0x7F in both the internal (in-memory)
+   and external (in-file) representations. */
+   
+
+/* Fields in e_ident[] */
+
+#define EI_MAG0		0		/* File identification byte 0 index */
+#define ELFMAG0		0x7F		/* Magic number byte 0 */
+
+#define EI_MAG1		1		/* File identification byte 1 index */
+#define ELFMAG1		'E'		/* Magic number byte 1 */
+
+#define EI_MAG2		2		/* File identification byte 2 index */
+#define ELFMAG2		'L'		/* Magic number byte 2 */
+
+#define EI_MAG3		3		/* File identification byte 3 index */
+#define ELFMAG3		'F'		/* Magic number byte 3 */
+
+#define EI_CLASS	4		/* File class */
+#define ELFCLASSNONE	0		/* Invalid class */
+#define ELFCLASS32	1		/* 32-bit objects */
+#define ELFCLASS64	2		/* 64-bit objects */
+
+#define EI_DATA		5		/* Data encoding */
+#define ELFDATANONE	0		/* Invalid data encoding */
+#define ELFDATA2LSB	1		/* 2's complement, little endian */
+#define ELFDATA2MSB	2		/* 2's complement, big endian */
+
+#define EI_VERSION	6		/* File version */
+
+#define EI_PAD		7		/* Start of padding bytes */
+
+
+/* Values for e_type, which identifies the object file type */
+
+#define ET_NONE		0		/* No file type */
+#define ET_REL		1		/* Relocatable file */
+#define ET_EXEC		2		/* Executable file */
+#define ET_DYN		3		/* Shared object file */
+#define ET_CORE		4		/* Core file */
+#define ET_LOPROC	0xFF00		/* Processor-specific */
+#define ET_HIPROC	0xFFFF		/* Processor-specific */
+
+/* Values for e_machine, which identifies the architecture */
+
+#define EM_NONE		0	/* No machine */
+#define EM_M32		1	/* AT&T WE 32100 */
+#define EM_SPARC	2	/* SUN SPARC */
+#define EM_386		3	/* Intel 80386 */
+#define EM_68K		4	/* Motorola m68k family */
+#define EM_88K		5	/* Motorola m88k family */
+#define EM_860		7	/* Intel 80860 */
+#define EM_MIPS		8	/* MIPS R3000 (officially, big-endian only) */
+
+#define EM_MIPS_RS4_BE 10	/* MIPS R4000 big-endian */
+
+#define EM_SPARC64     11	/* SPARC v9 (not official) 64-bit */
+
+#define EM_PARISC      15	/* HPPA */
+#define EM_PPC	       20	/* PowerPC */
+
+/* If it is necessary to assign new unofficial EM_* values, please pick large
+   random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
+   with official or non-GNU unofficial values.  */
+
+/* Cygnus PowerPC ELF backend.  Written in the absence of an ABI.  */
+#define EM_CYGNUS_POWERPC 0x9025
+
+/* Old version of PowerPC, this should be removed shortly. */
+#define EM_PPC_OLD	17
+
+
+/* Values for e_version */
+
+#define EV_NONE		0		/* Invalid ELF version */
+#define EV_CURRENT	1		/* Current version */
+
+/* Values for program header, p_type field */
+
+#define	PT_NULL		0		/* Program header table entry unused */
+#define PT_LOAD		1		/* Loadable program segment */
+#define PT_DYNAMIC	2		/* Dynamic linking information */
+#define PT_INTERP	3		/* Program interpreter */
+#define PT_NOTE		4		/* Auxiliary information */
+#define PT_SHLIB	5		/* Reserved, unspecified semantics */
+#define PT_PHDR		6		/* Entry for header table itself */
+#define PT_LOPROC	0x70000000	/* Processor-specific */
+#define PT_HIPROC	0x7FFFFFFF	/* Processor-specific */
+
+/* Program segment permissions, in program header p_flags field */
+
+#define PF_X		(1 << 0)	/* Segment is executable */
+#define PF_W		(1 << 1)	/* Segment is writable */
+#define PF_R		(1 << 2)	/* Segment is readable */
+#define PF_MASKPROC	0xF0000000	/* Processor-specific reserved bits */
+
+/* Values for section header, sh_type field */
+
+#define SHT_NULL	0		/* Section header table entry unused */
+#define SHT_PROGBITS	1		/* Program specific (private) data */
+#define SHT_SYMTAB	2		/* Link editing symbol table */
+#define SHT_STRTAB	3		/* A string table */
+#define SHT_RELA	4		/* Relocation entries with addends */
+#define SHT_HASH	5		/* A symbol hash table */
+#define SHT_DYNAMIC	6		/* Information for dynamic linking */
+#define SHT_NOTE	7		/* Information that marks file */
+#define SHT_NOBITS	8		/* Section occupies no space in file */
+#define SHT_REL		9		/* Relocation entries, no addends */
+#define SHT_SHLIB	10		/* Reserved, unspecified semantics */
+#define SHT_DYNSYM	11		/* Dynamic linking symbol table */
+#define SHT_LOPROC	0x70000000	/* Processor-specific semantics, lo */
+#define SHT_HIPROC	0x7FFFFFFF	/* Processor-specific semantics, hi */
+#define SHT_LOUSER	0x80000000	/* Application-specific semantics */
+#define SHT_HIUSER	0x8FFFFFFF	/* Application-specific semantics */
+
+/* Values for section header, sh_flags field */
+
+#define SHF_WRITE	(1 << 0)	/* Writable data during execution */
+#define SHF_ALLOC	(1 << 1)	/* Occupies memory during execution */
+#define SHF_EXECINSTR	(1 << 2)	/* Executable machine instructions */
+#define SHF_MASKPROC	0xF0000000	/* Processor-specific semantics */
+
+/* Values of note segment descriptor types for core files. */
+
+#define NT_PRSTATUS	1		/* Contains copy of prstatus struct */
+#define NT_FPREGSET	2		/* Contains copy of fpregset struct */
+#define NT_PRPSINFO	3		/* Contains copy of prpsinfo struct */
+
+/* Values of note segment descriptor types for object files.  */
+/* (Only for hppa right now.  Should this be moved elsewhere?)  */
+
+#define NT_VERSION	1		/* Contains a version string.  */
+
+/* These three macros disassemble and assemble a symbol table st_info field,
+   which contains the symbol binding and symbol type.  The STB_ and STT_
+   defines identify the binding and type. */
+
+#define ELF_ST_BIND(val)		(((unsigned int)(val)) >> 4)
+#define ELF_ST_TYPE(val)		((val) & 0xF)
+#define ELF_ST_INFO(bind,type)		(((bind) << 4) + ((type) & 0xF))
+
+#define STN_UNDEF	0		/* undefined symbol index */
+
+#define STB_LOCAL	0		/* Symbol not visible outside obj */
+#define STB_GLOBAL	1		/* Symbol visible outside obj */
+#define STB_WEAK	2		/* Like globals, lower precedence */
+#define STB_LOPROC	13		/* Application-specific semantics */
+#define STB_HIPROC	15		/* Application-specific semantics */
+
+#define STT_NOTYPE	0		/* Symbol type is unspecified */
+#define STT_OBJECT	1		/* Symbol is a data object */
+#define STT_FUNC	2		/* Symbol is a code object */
+#define STT_SECTION	3		/* Symbol associated with a section */
+#define STT_FILE	4		/* Symbol gives a file name */
+#define STT_LOPROC	13		/* Application-specific semantics */
+#define STT_HIPROC	15		/* Application-specific semantics */
+
+/* Special section indices, which may show up in st_shndx fields, among
+   other places. */
+
+#define SHN_UNDEF	0		/* Undefined section reference */
+#define SHN_LORESERVE	0xFF00		/* Begin range of reserved indices */
+#define SHN_LOPROC	0xFF00		/* Begin range of appl-specific */
+#define SHN_HIPROC	0xFF1F		/* End range of appl-specific */
+#define SHN_ABS		0xFFF1		/* Associated symbol is absolute */
+#define SHN_COMMON	0xFFF2		/* Associated symbol is in common */
+#define SHN_HIRESERVE	0xFFFF		/* End range of reserved indices */
+
+/* relocation info handling macros */
+
+#define ELF32_R_SYM(i)		((i) >> 8)
+#define ELF32_R_TYPE(i)		((i) & 0xff)
+#define ELF32_R_INFO(s,t)	(((s) << 8) + ((t) & 0xff))
+
+#define ELF64_R_SYM(i)		((i) >> 32)
+#define ELF64_R_TYPE(i)		((i) & 0xffffffff)
+#define ELF64_R_INFO(s,t)	(((bfd_vma) (s) << 32) + (bfd_vma) (t))
+
+/* Dynamic section tags */
+
+#define DT_NULL		0
+#define DT_NEEDED	1
+#define DT_PLTRELSZ	2
+#define DT_PLTGOT	3
+#define DT_HASH		4
+#define DT_STRTAB	5
+#define DT_SYMTAB	6
+#define DT_RELA		7
+#define DT_RELASZ	8
+#define DT_RELAENT	9
+#define DT_STRSZ	10
+#define DT_SYMENT	11
+#define DT_INIT		12
+#define DT_FINI		13
+#define DT_SONAME	14
+#define DT_RPATH	15
+#define DT_SYMBOLIC	16
+#define DT_REL		17
+#define DT_RELSZ	18
+#define DT_RELENT	19
+#define DT_PLTREL	20
+#define DT_DEBUG	21
+#define DT_TEXTREL	22
+#define DT_JMPREL	23
+#define DT_LOPROC	0x70000000
+#define DT_HIPROC	0x7fffffff
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/include/elf/dwarf.h linux/arch/ppc/kernel/include/elf/dwarf.h
--- pre2.0.7/linux/arch/ppc/kernel/include/elf/dwarf.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/include/elf/dwarf.h	Mon May 27 12:00:57 1996
@@ -0,0 +1,314 @@
+/* Declarations and definitions of codes relating to the DWARF symbolic
+   debugging information format.
+
+   Written by Ron Guilmette (rfg@ncd.com)
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* This file is derived from the DWARF specification (a public document)
+   Revision 1.0.1 (April 8, 1992) developed by the UNIX International
+   Programming Languages Special Interest Group (UI/PLSIG) and distributed
+   by UNIX International.  Copies of this specification are available from
+   UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054.
+*/
+
+/* Tag names and codes.  */
+
+enum dwarf_tag {
+    TAG_padding			= 0x0000,
+    TAG_array_type		= 0x0001,
+    TAG_class_type		= 0x0002,
+    TAG_entry_point		= 0x0003,
+    TAG_enumeration_type	= 0x0004,
+    TAG_formal_parameter	= 0x0005,
+    TAG_global_subroutine	= 0x0006,
+    TAG_global_variable		= 0x0007,
+    				/* 0x0008 -- reserved */
+				/* 0x0009 -- reserved */
+    TAG_label			= 0x000a,
+    TAG_lexical_block		= 0x000b,
+    TAG_local_variable		= 0x000c,
+    TAG_member			= 0x000d,
+				/* 0x000e -- reserved */
+    TAG_pointer_type		= 0x000f,
+    TAG_reference_type		= 0x0010,
+    TAG_compile_unit		= 0x0011,
+    TAG_string_type		= 0x0012,
+    TAG_structure_type		= 0x0013,
+    TAG_subroutine		= 0x0014,
+    TAG_subroutine_type		= 0x0015,
+    TAG_typedef			= 0x0016,
+    TAG_union_type		= 0x0017,
+    TAG_unspecified_parameters	= 0x0018,
+    TAG_variant			= 0x0019,
+    TAG_common_block		= 0x001a,
+    TAG_common_inclusion	= 0x001b,
+    TAG_inheritance		= 0x001c,
+    TAG_inlined_subroutine	= 0x001d,
+    TAG_module			= 0x001e,
+    TAG_ptr_to_member_type	= 0x001f,
+    TAG_set_type		= 0x0020,
+    TAG_subrange_type		= 0x0021,
+    TAG_with_stmt		= 0x0022,
+
+    /* GNU extensions */
+
+    TAG_format_label		= 0x8000,  /* for FORTRAN 77 and Fortran 90 */
+    TAG_namelist		= 0x8001,  /* For Fortran 90 */
+    TAG_function_template	= 0x8002,  /* for C++ */
+    TAG_class_template		= 0x8003   /* for C++ */
+};
+
+#define TAG_lo_user	0x8000  /* implementation-defined range start */
+#define TAG_hi_user	0xffff  /* implementation-defined range end */
+#define TAG_source_file TAG_compile_unit  /* for backward compatibility */
+
+/* Form names and codes.  */
+
+enum dwarf_form {
+    FORM_ADDR	= 0x1,
+    FORM_REF	= 0x2,
+    FORM_BLOCK2	= 0x3,
+    FORM_BLOCK4	= 0x4,
+    FORM_DATA2	= 0x5,
+    FORM_DATA4	= 0x6,
+    FORM_DATA8	= 0x7,
+    FORM_STRING	= 0x8
+};
+
+/* Attribute names and codes.  */
+
+enum dwarf_attribute {
+    AT_sibling			= (0x0010|FORM_REF),
+    AT_location			= (0x0020|FORM_BLOCK2),
+    AT_name			= (0x0030|FORM_STRING),
+    AT_fund_type		= (0x0050|FORM_DATA2),
+    AT_mod_fund_type		= (0x0060|FORM_BLOCK2),
+    AT_user_def_type		= (0x0070|FORM_REF),
+    AT_mod_u_d_type		= (0x0080|FORM_BLOCK2),
+    AT_ordering			= (0x0090|FORM_DATA2),
+    AT_subscr_data		= (0x00a0|FORM_BLOCK2),
+    AT_byte_size		= (0x00b0|FORM_DATA4),
+    AT_bit_offset		= (0x00c0|FORM_DATA2),
+    AT_bit_size			= (0x00d0|FORM_DATA4),
+				/* (0x00e0|FORM_xxxx) -- reserved */
+    AT_element_list		= (0x00f0|FORM_BLOCK4),
+    AT_stmt_list		= (0x0100|FORM_DATA4),
+    AT_low_pc			= (0x0110|FORM_ADDR),
+    AT_high_pc			= (0x0120|FORM_ADDR),
+    AT_language			= (0x0130|FORM_DATA4),
+    AT_member			= (0x0140|FORM_REF),
+    AT_discr			= (0x0150|FORM_REF),
+    AT_discr_value		= (0x0160|FORM_BLOCK2),
+				/* (0x0170|FORM_xxxx) -- reserved */
+				/* (0x0180|FORM_xxxx) -- reserved */
+    AT_string_length		= (0x0190|FORM_BLOCK2),
+    AT_common_reference		= (0x01a0|FORM_REF),
+    AT_comp_dir			= (0x01b0|FORM_STRING),
+        AT_const_value_string	= (0x01c0|FORM_STRING),
+        AT_const_value_data2	= (0x01c0|FORM_DATA2),
+        AT_const_value_data4	= (0x01c0|FORM_DATA4),
+        AT_const_value_data8	= (0x01c0|FORM_DATA8),
+        AT_const_value_block2	= (0x01c0|FORM_BLOCK2),
+        AT_const_value_block4	= (0x01c0|FORM_BLOCK4),
+    AT_containing_type		= (0x01d0|FORM_REF),
+        AT_default_value_addr	= (0x01e0|FORM_ADDR),
+        AT_default_value_data2	= (0x01e0|FORM_DATA2),
+        AT_default_value_data4	= (0x01e0|FORM_DATA4),
+        AT_default_value_data8	= (0x01e0|FORM_DATA8),
+        AT_default_value_string	= (0x01e0|FORM_STRING),
+    AT_friends			= (0x01f0|FORM_BLOCK2),
+    AT_inline			= (0x0200|FORM_STRING),
+    AT_is_optional		= (0x0210|FORM_STRING),
+        AT_lower_bound_ref	= (0x0220|FORM_REF),
+        AT_lower_bound_data2	= (0x0220|FORM_DATA2),
+        AT_lower_bound_data4	= (0x0220|FORM_DATA4),
+        AT_lower_bound_data8	= (0x0220|FORM_DATA8),
+    AT_private			= (0x0240|FORM_STRING),
+    AT_producer			= (0x0250|FORM_STRING),
+    AT_program			= (0x0230|FORM_STRING),
+    AT_protected		= (0x0260|FORM_STRING),
+    AT_prototyped		= (0x0270|FORM_STRING),
+    AT_public			= (0x0280|FORM_STRING),
+    AT_pure_virtual		= (0x0290|FORM_STRING),
+    AT_return_addr		= (0x02a0|FORM_BLOCK2),
+    AT_abstract_origin		= (0x02b0|FORM_REF),
+    AT_start_scope		= (0x02c0|FORM_DATA4),
+    AT_stride_size		= (0x02e0|FORM_DATA4),
+        AT_upper_bound_ref	= (0x02f0|FORM_REF),
+        AT_upper_bound_data2	= (0x02f0|FORM_DATA2),
+        AT_upper_bound_data4	= (0x02f0|FORM_DATA4),
+        AT_upper_bound_data8	= (0x02f0|FORM_DATA8),
+    AT_virtual			= (0x0300|FORM_STRING),
+
+    /* GNU extensions.  */
+
+    AT_sf_names			= (0x8000|FORM_DATA4),
+    AT_src_info			= (0x8010|FORM_DATA4),
+    AT_mac_info			= (0x8020|FORM_DATA4),
+    AT_src_coords		= (0x8030|FORM_DATA4),
+    AT_body_begin		= (0x8040|FORM_ADDR),
+    AT_body_end			= (0x8050|FORM_ADDR)
+};
+
+#define AT_lo_user	0x8000  /* implementation-defined range start */
+#define AT_hi_user	0xffff  /* implementation-defined range end */
+
+/* Location atom names and codes.  */
+
+enum dwarf_location_atom {
+    OP_REG	= 0x01,
+    OP_BASEREG	= 0x02,
+    OP_ADDR	= 0x03,
+    OP_CONST	= 0x04,
+    OP_DEREF2	= 0x05,
+    OP_DEREF4	= 0x06,
+    OP_ADD	= 0x07
+};
+
+#define OP_LO_USER	0x80  /* implementation-defined range start */
+#define OP_HI_USER	0xff  /* implementation-defined range end */
+
+/* Fundamental type names and codes.  */
+
+enum dwarf_fundamental_type {
+    FT_char		= 0x0001,
+    FT_signed_char	= 0x0002,
+    FT_unsigned_char	= 0x0003,
+    FT_short		= 0x0004,
+    FT_signed_short	= 0x0005,
+    FT_unsigned_short	= 0x0006,
+    FT_integer		= 0x0007,
+    FT_signed_integer	= 0x0008,
+    FT_unsigned_integer	= 0x0009,
+    FT_long		= 0x000a,
+    FT_signed_long	= 0x000b,
+    FT_unsigned_long	= 0x000c,
+    FT_pointer		= 0x000d,  /* an alias for (void *) */
+    FT_float		= 0x000e,
+    FT_dbl_prec_float	= 0x000f,
+    FT_ext_prec_float	= 0x0010,  /* breaks "classic" svr4 SDB */
+    FT_complex		= 0x0011,  /* breaks "classic" svr4 SDB */
+    FT_dbl_prec_complex	= 0x0012,  /* breaks "classic" svr4 SDB */
+			/* 0x0013 -- reserved */
+    FT_void		= 0x0014,
+    FT_boolean		= 0x0015,  /* breaks "classic" svr4 SDB */
+    FT_ext_prec_complex	= 0x0016,  /* breaks "classic" svr4 SDB */
+    FT_label		= 0x0017,
+  
+    /* GNU extensions
+       The low order byte must indicate the size (in bytes) for the type.
+       All of these types will probably break "classic" svr4 SDB */
+
+    FT_long_long	= 0x8008,
+    FT_signed_long_long	= 0x8108,
+    FT_unsigned_long_long = 0x8208,
+
+    FT_int8		= 0x9001,
+    FT_signed_int8	= 0x9101,
+    FT_unsigned_int8	= 0x9201,
+    FT_int16		= 0x9302,
+    FT_signed_int16	= 0x9402,
+    FT_unsigned_int16	= 0x9502,
+    FT_int32		= 0x9604,
+    FT_signed_int32	= 0x9704,
+    FT_unsigned_int32	= 0x9804,
+    FT_int64		= 0x9908,
+    FT_signed_int64	= 0x9a08,
+    FT_unsigned_int64	= 0x9b08,
+
+    FT_real32		= 0xa004,
+    FT_real64		= 0xa108,
+    FT_real96		= 0xa20c,
+    FT_real128		= 0xa310
+};
+
+#define FT_lo_user	0x8000  /* implementation-defined range start */
+#define FT_hi_user	0xffff  /* implementation defined range end */
+
+/* Type modifier names and codes.  */
+
+enum dwarf_type_modifier {
+    MOD_pointer_to	= 0x01,
+    MOD_reference_to	= 0x02,
+    MOD_const		= 0x03,
+    MOD_volatile	= 0x04
+};
+
+#define MOD_lo_user	0x80  /* implementation-defined range start */
+#define MOD_hi_user	0xff  /* implementation-defined range end */
+
+/* Array ordering names and codes.  */
+
+enum dwarf_array_dim_ordering {
+    ORD_row_major	= 0,
+    ORD_col_major	= 1
+};
+
+/* Array subscript format names and codes.  */
+
+enum dwarf_subscr_data_formats {
+    FMT_FT_C_C	= 0x0,
+    FMT_FT_C_X	= 0x1,
+    FMT_FT_X_C	= 0x2,
+    FMT_FT_X_X	= 0x3,
+    FMT_UT_C_C	= 0x4,
+    FMT_UT_C_X	= 0x5,
+    FMT_UT_X_C	= 0x6,
+    FMT_UT_X_X	= 0x7,
+    FMT_ET	= 0x8
+};
+
+/* Derived from above for ease of use.  */
+
+#define FMT_CODE(_FUNDAMENTAL_TYPE_P, _UB_CONST_P, _LB_CONST_P) \
+ (((_FUNDAMENTAL_TYPE_P) ? 0 : 4)	\
+  | ((_UB_CONST_P) ? 0 : 2)		\
+  | ((_LB_CONST_P) ? 0 : 1))
+
+/* Source language names and codes.  */
+
+enum dwarf_source_language {
+    LANG_C89		= 0x00000001,
+    LANG_C		= 0x00000002,
+    LANG_ADA83		= 0x00000003,
+    LANG_C_PLUS_PLUS	= 0x00000004,
+    LANG_COBOL74	= 0x00000005,
+    LANG_COBOL85	= 0x00000006,
+    LANG_FORTRAN77	= 0x00000007,
+    LANG_FORTRAN90	= 0x00000008,
+    LANG_PASCAL83	= 0x00000009,
+    LANG_MODULA2	= 0x0000000a,
+
+    /* GNU extensions */
+
+    LANG_CHILL		= 0x00009af3	/* random value for GNU Chill */
+};
+
+#define LANG_lo_user	0x00008000  /* implementation-defined range start */
+#define LANG_hi_user	0x0000ffff  /* implementation-defined range end */
+
+/* Names and codes for GNU "macinfo" extension.  */
+
+enum dwarf_macinfo_record_type {
+    MACINFO_start	= 's',
+    MACINFO_resume	= 'r',
+    MACINFO_define	= 'd',
+    MACINFO_undef	= 'u'
+};
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/include/elf/external.h linux/arch/ppc/kernel/include/elf/external.h
--- pre2.0.7/linux/arch/ppc/kernel/include/elf/external.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/include/elf/external.h	Mon May 27 12:00:57 1996
@@ -0,0 +1,190 @@
+/* ELF support for BFD.
+   Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+   Written by Fred Fish @ Cygnus Support, from information published
+   in "UNIX System V Release 4, Programmers Guide: ANSI C and
+   Programming Support Tools".
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+/* This file is part of ELF support for BFD, and contains the portions
+   that describe how ELF is represented externally by the BFD library.
+   I.E. it describes the in-file representation of ELF.  It requires
+   the elf-common.h file which contains the portions that are common to
+   both the internal and external representations. */
+   
+/* The 64-bit stuff is kind of random.  Perhaps someone will publish a
+   spec someday.  */
+
+/* ELF Header (32-bit implementations) */
+
+typedef struct {
+  unsigned char	e_ident[16];		/* ELF "magic number" */
+  unsigned char	e_type[2];		/* Identifies object file type */
+  unsigned char	e_machine[2];		/* Specifies required architecture */
+  unsigned char	e_version[4];		/* Identifies object file version */
+  unsigned char	e_entry[4];		/* Entry point virtual address */
+  unsigned char	e_phoff[4];		/* Program header table file offset */
+  unsigned char	e_shoff[4];		/* Section header table file offset */
+  unsigned char	e_flags[4];		/* Processor-specific flags */
+  unsigned char	e_ehsize[2];		/* ELF header size in bytes */
+  unsigned char	e_phentsize[2];		/* Program header table entry size */
+  unsigned char	e_phnum[2];		/* Program header table entry count */
+  unsigned char	e_shentsize[2];		/* Section header table entry size */
+  unsigned char	e_shnum[2];		/* Section header table entry count */
+  unsigned char	e_shstrndx[2];		/* Section header string table index */
+} Elf32_External_Ehdr;
+
+typedef struct {
+  unsigned char	e_ident[16];		/* ELF "magic number" */
+  unsigned char	e_type[2];		/* Identifies object file type */
+  unsigned char	e_machine[2];		/* Specifies required architecture */
+  unsigned char	e_version[4];		/* Identifies object file version */
+  unsigned char	e_entry[8];		/* Entry point virtual address */
+  unsigned char	e_phoff[8];		/* Program header table file offset */
+  unsigned char	e_shoff[8];		/* Section header table file offset */
+  unsigned char	e_flags[4];		/* Processor-specific flags */
+  unsigned char	e_ehsize[2];		/* ELF header size in bytes */
+  unsigned char	e_phentsize[2];		/* Program header table entry size */
+  unsigned char	e_phnum[2];		/* Program header table entry count */
+  unsigned char	e_shentsize[2];		/* Section header table entry size */
+  unsigned char	e_shnum[2];		/* Section header table entry count */
+  unsigned char	e_shstrndx[2];		/* Section header string table index */
+} Elf64_External_Ehdr;
+
+/* Program header */
+
+typedef struct {
+  unsigned char	p_type[4];		/* Identifies program segment type */
+  unsigned char	p_offset[4];		/* Segment file offset */
+  unsigned char	p_vaddr[4];		/* Segment virtual address */
+  unsigned char	p_paddr[4];		/* Segment physical address */
+  unsigned char	p_filesz[4];		/* Segment size in file */
+  unsigned char	p_memsz[4];		/* Segment size in memory */
+  unsigned char	p_flags[4];		/* Segment flags */
+  unsigned char	p_align[4];		/* Segment alignment, file & memory */
+} Elf32_External_Phdr;
+
+typedef struct {
+  unsigned char	p_type[4];		/* Identifies program segment type */
+  unsigned char	p_flags[4];		/* Segment flags */
+  unsigned char	p_offset[8];		/* Segment file offset */
+  unsigned char	p_vaddr[8];		/* Segment virtual address */
+  unsigned char	p_paddr[8];		/* Segment physical address */
+  unsigned char	p_filesz[8];		/* Segment size in file */
+  unsigned char	p_memsz[8];		/* Segment size in memory */
+  unsigned char	p_align[8];		/* Segment alignment, file & memory */
+} Elf64_External_Phdr;
+
+/* Section header */
+
+typedef struct {
+  unsigned char	sh_name[4];		/* Section name, index in string tbl */
+  unsigned char	sh_type[4];		/* Type of section */
+  unsigned char	sh_flags[4];		/* Miscellaneous section attributes */
+  unsigned char	sh_addr[4];		/* Section virtual addr at execution */
+  unsigned char	sh_offset[4];		/* Section file offset */
+  unsigned char	sh_size[4];		/* Size of section in bytes */
+  unsigned char	sh_link[4];		/* Index of another section */
+  unsigned char	sh_info[4];		/* Additional section information */
+  unsigned char	sh_addralign[4];	/* Section alignment */
+  unsigned char	sh_entsize[4];		/* Entry size if section holds table */
+} Elf32_External_Shdr;
+
+typedef struct {
+  unsigned char	sh_name[4];		/* Section name, index in string tbl */
+  unsigned char	sh_type[4];		/* Type of section */
+  unsigned char	sh_flags[8];		/* Miscellaneous section attributes */
+  unsigned char	sh_addr[8];		/* Section virtual addr at execution */
+  unsigned char	sh_offset[8];		/* Section file offset */
+  unsigned char	sh_size[8];		/* Size of section in bytes */
+  unsigned char	sh_link[4];		/* Index of another section */
+  unsigned char	sh_info[4];		/* Additional section information */
+  unsigned char	sh_addralign[8];	/* Section alignment */
+  unsigned char	sh_entsize[8];		/* Entry size if section holds table */
+} Elf64_External_Shdr;
+
+/* Symbol table entry */
+
+typedef struct {
+  unsigned char	st_name[4];		/* Symbol name, index in string tbl */
+  unsigned char	st_value[4];		/* Value of the symbol */
+  unsigned char	st_size[4];		/* Associated symbol size */
+  unsigned char	st_info[1];		/* Type and binding attributes */
+  unsigned char	st_other[1];		/* No defined meaning, 0 */
+  unsigned char	st_shndx[2];		/* Associated section index */
+} Elf32_External_Sym;
+
+typedef struct {
+  unsigned char	st_name[4];		/* Symbol name, index in string tbl */
+  unsigned char	st_info[1];		/* Type and binding attributes */
+  unsigned char	st_other[1];		/* No defined meaning, 0 */
+  unsigned char	st_shndx[2];		/* Associated section index */
+  unsigned char	st_value[8];		/* Value of the symbol */
+  unsigned char	st_size[8];		/* Associated symbol size */
+} Elf64_External_Sym;
+
+/* Note segments */
+
+typedef struct {
+  unsigned char	namesz[4];		/* Size of entry's owner string */
+  unsigned char	descsz[4];		/* Size of the note descriptor */
+  unsigned char	type[4];		/* Interpretation of the descriptor */
+  char		name[1];		/* Start of the name+desc data */
+} Elf_External_Note;
+
+/* Relocation Entries */
+typedef struct {
+  unsigned char r_offset[4];	/* Location at which to apply the action */
+  unsigned char	r_info[4];	/* index and type of relocation */
+} Elf32_External_Rel;
+
+typedef struct {
+  unsigned char r_offset[4];	/* Location at which to apply the action */
+  unsigned char	r_info[4];	/* index and type of relocation */
+  unsigned char	r_addend[4];	/* Constant addend used to compute value */
+} Elf32_External_Rela;
+
+typedef struct {
+  unsigned char r_offset[8];	/* Location at which to apply the action */
+  unsigned char	r_info[8];	/* index and type of relocation */
+} Elf64_External_Rel;
+
+typedef struct {
+  unsigned char r_offset[8];	/* Location at which to apply the action */
+  unsigned char	r_info[8];	/* index and type of relocation */
+  unsigned char	r_addend[8];	/* Constant addend used to compute value */
+} Elf64_External_Rela;
+
+/* dynamic section structure */
+
+typedef struct {
+  unsigned char	d_tag[4];		/* entry tag value */
+  union {
+    unsigned char	d_val[4];
+    unsigned char	d_ptr[4];
+  } d_un;
+} Elf32_External_Dyn;
+
+typedef struct {
+  unsigned char	d_tag[8];		/* entry tag value */
+  union {
+    unsigned char	d_val[8];
+    unsigned char	d_ptr[8];
+  } d_un;
+} Elf64_External_Dyn;
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/include/elf/hppa.h linux/arch/ppc/kernel/include/elf/hppa.h
--- pre2.0.7/linux/arch/ppc/kernel/include/elf/hppa.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/include/elf/hppa.h	Mon May 27 12:00:57 1996
@@ -0,0 +1,90 @@
+/* HPPA ELF support for BFD.
+   Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* This file holds definitions specific to the HPPA ELF ABI.  Note
+   that most of this is not actually implemented by BFD.  */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+
+/* Target processor IDs to be placed in the low 16 bits of the flags
+   field.  Note these names are shared with SOM, and therefore do not
+   follow ELF naming conventions.  */
+
+/* PA 1.0 big endian.  */
+#ifndef CPU_PA_RISC1_0
+#define CPU_PA_RISC1_0		0x0000020b
+#endif
+
+/* PA 1.1 big endian.  */
+#ifndef CPU_PA_RISC1_1
+#define CPU_PA_RISC1_1		0x00000210
+#endif
+
+/* PA 1.0 little endian (unsupported) is 0x0000028b.  */
+/* PA 1.1 little endian (unsupported) is 0x00000290.  */
+
+/* Trap null address dereferences.  */
+#define ELF_PARISC_TRAPNIL	0x00010000
+
+/* .PARISC.archext section is present.  */
+#define EF_PARISC_EXT		0x00020000
+
+/* Processor specific section types.  */
+
+/* Holds the global offset table, a table of pointers to external
+   data.  */
+#define SHT_PARISC_GOT		SHT_LOPROC+0
+
+/* Nonloadable section containing information in architecture
+   extensions used by the code.  */
+#define SHT_PARISC_ARCH		SHT_LOPROC+1
+
+/* Section in which $global$ is defined.  */
+#define SHT_PARISC_GLOBAL	SHT_LOPROC+2
+
+/* Section holding millicode routines (mul, div, rem, dyncall, etc.  */
+#define SHT_PARISC_MILLI	SHT_LOPROC+3
+
+/* Section holding unwind information for use by debuggers.  */
+#define SHT_PARISC_UNWIND	SHT_LOPROC+4
+
+/* Section holding the procedure linkage table.  */
+#define SHT_PARISC_PLT		SHT_LOPROC+5
+
+/* Short initialized and uninitialized data.  */
+#define SHT_PARISC_SDATA	SHT_LOPROC+6
+#define SHT_PARISC_SBSS		SHT_LOPROC+7
+
+/* Optional section holding argument location/relocation info.  */
+#define SHT_PARISC_SYMEXTN	SHT_LOPROC+8
+
+/* Option section for linker stubs.  */
+#define SHT_PARISC_STUBS	SHT_LOPROC+9
+
+/* Processor specific section flags.  */
+
+/* This section is near the global data pointer and thus allows short
+   addressing modes to be used.  */
+#define SHF_PARISC_SHORT        0x20000000
+
+/* Processor specific symbol types.  */
+
+/* Millicode function entry point.  */
+#define STT_PARISC_MILLICODE	STT_LOPROC+0
+
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/include/elf/internal.h linux/arch/ppc/kernel/include/elf/internal.h
--- pre2.0.7/linux/arch/ppc/kernel/include/elf/internal.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/include/elf/internal.h	Mon May 27 12:00:57 1996
@@ -0,0 +1,173 @@
+/* ELF support for BFD.
+   Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+
+   Written by Fred Fish @ Cygnus Support, from information published
+   in "UNIX System V Release 4, Programmers Guide: ANSI C and
+   Programming Support Tools".
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+/* This file is part of ELF support for BFD, and contains the portions
+   that describe how ELF is represented internally in the BFD library.
+   I.E. it describes the in-memory representation of ELF.  It requires
+   the elf-common.h file which contains the portions that are common to
+   both the internal and external representations. */
+   
+
+/* NOTE that these structures are not kept in the same order as they appear
+   in the object file.  In some cases they've been reordered for more optimal
+   packing under various circumstances.  */
+
+/* ELF Header */
+
+#define EI_NIDENT	16		/* Size of e_ident[] */
+
+typedef struct elf_internal_ehdr {
+  unsigned char		e_ident[EI_NIDENT];	/* ELF "magic number" */
+  bfd_vma		e_entry;		/* Entry point virtual address */
+  bfd_signed_vma	e_phoff;		/* Program header table file offset */
+  bfd_signed_vma	e_shoff;		/* Section header table file offset */
+  unsigned long		e_version;		/* Identifies object file version */
+  unsigned long		e_flags;		/* Processor-specific flags */
+  unsigned short	e_type;			/* Identifies object file type */
+  unsigned short	e_machine;		/* Specifies required architecture */
+  unsigned short	e_ehsize;		/* ELF header size in bytes */
+  unsigned short	e_phentsize;		/* Program header table entry size */
+  unsigned short	e_phnum;		/* Program header table entry count */
+  unsigned short	e_shentsize;		/* Section header table entry size */
+  unsigned short	e_shnum;		/* Section header table entry count */
+  unsigned short	e_shstrndx;		/* Section header string table index */
+} Elf_Internal_Ehdr;
+
+#define elf32_internal_ehdr elf_internal_ehdr
+#define Elf32_Internal_Ehdr Elf_Internal_Ehdr
+#define elf64_internal_ehdr elf_internal_ehdr
+#define Elf64_Internal_Ehdr Elf_Internal_Ehdr
+
+/* Program header */
+
+struct elf_internal_phdr {
+  unsigned long	p_type;			/* Identifies program segment type */
+  unsigned long	p_flags;		/* Segment flags */
+  bfd_vma	p_offset;		/* Segment file offset */
+  bfd_vma	p_vaddr;		/* Segment virtual address */
+  bfd_vma	p_paddr;		/* Segment physical address */
+  bfd_vma	p_filesz;		/* Segment size in file */
+  bfd_vma	p_memsz;		/* Segment size in memory */
+  bfd_vma	p_align;		/* Segment alignment, file & memory */
+};
+
+typedef struct elf_internal_phdr Elf_Internal_Phdr;
+#define elf32_internal_phdr elf_internal_phdr
+#define Elf32_Internal_Phdr Elf_Internal_Phdr
+#define elf64_internal_phdr elf_internal_phdr
+#define Elf64_Internal_Phdr Elf_Internal_Phdr
+
+/* Section header */
+
+typedef struct elf_internal_shdr {
+  unsigned int	sh_name;		/* Section name, index in string tbl */
+  unsigned int	sh_type;		/* Type of section */
+  bfd_vma	sh_flags;		/* Miscellaneous section attributes */
+  bfd_vma	sh_addr;		/* Section virtual addr at execution */
+  bfd_size_type	sh_size;		/* Size of section in bytes */
+  bfd_size_type	sh_entsize;		/* Entry size if section holds table */
+  unsigned long	sh_link;		/* Index of another section */
+  unsigned long	sh_info;		/* Additional section information */
+  file_ptr	sh_offset;		/* Section file offset */
+  unsigned int	sh_addralign;		/* Section alignment */
+
+  /* The internal rep also has some cached info associated with it. */
+  asection *	bfd_section;		/* Associated BFD section.  */
+  PTR		contents;		/* Section contents.  */
+} Elf_Internal_Shdr;
+
+#define elf32_internal_shdr elf_internal_shdr
+#define Elf32_Internal_Shdr Elf_Internal_Shdr
+#define elf64_internal_shdr elf_internal_shdr
+#define Elf64_Internal_Shdr Elf_Internal_Shdr
+
+/* Symbol table entry */
+
+struct elf_internal_sym {
+  bfd_vma	st_value;		/* Value of the symbol */
+  bfd_vma	st_size;		/* Associated symbol size */
+  unsigned long	st_name;		/* Symbol name, index in string tbl */
+  unsigned char	st_info;		/* Type and binding attributes */
+  unsigned char	st_other;		/* No defined meaning, 0 */
+  unsigned short st_shndx;		/* Associated section index */
+};
+
+typedef struct elf_internal_sym Elf_Internal_Sym;
+
+#define elf32_internal_sym elf_internal_sym
+#define elf64_internal_sym elf_internal_sym
+#define Elf32_Internal_Sym Elf_Internal_Sym
+#define Elf64_Internal_Sym Elf_Internal_Sym
+
+/* Note segments */
+
+typedef struct elf_internal_note {
+  unsigned long	namesz;			/* Size of entry's owner string */
+  unsigned long	descsz;			/* Size of the note descriptor */
+  unsigned long	type;			/* Interpretation of the descriptor */
+  char		name[1];		/* Start of the name+desc data */
+} Elf_Internal_Note;
+#define Elf32_Internal_Note	Elf_Internal_Note
+#define elf32_internal_note	elf_internal_note
+
+/* Relocation Entries */
+
+typedef struct elf_internal_rel {
+  bfd_vma	r_offset;	/* Location at which to apply the action */
+  /* This needs to support 64-bit values in elf64.  */
+  bfd_vma	r_info;		/* index and type of relocation */
+} Elf_Internal_Rel;
+
+#define elf32_internal_rel elf_internal_rel
+#define Elf32_Internal_Rel Elf_Internal_Rel
+#define elf64_internal_rel elf_internal_rel
+#define Elf64_Internal_Rel Elf_Internal_Rel
+
+typedef struct elf_internal_rela {
+  bfd_vma	r_offset;	/* Location at which to apply the action */
+  bfd_vma	r_info;		/* Index and Type of relocation */
+  bfd_signed_vma r_addend;	/* Constant addend used to compute value */
+} Elf_Internal_Rela;
+
+#define elf32_internal_rela elf_internal_rela
+#define elf64_internal_rela elf_internal_rela
+#define Elf32_Internal_Rela Elf_Internal_Rela
+#define Elf64_Internal_Rela Elf_Internal_Rela
+
+/* dynamic section structure */
+
+typedef struct elf_internal_dyn {
+  /* This needs to support 64-bit values in elf64.  */
+  bfd_vma d_tag;		/* entry tag value */
+  union {
+    /* This needs to support 64-bit values in elf64.  */
+    bfd_vma	d_val;
+    bfd_vma	d_ptr;
+  } d_un;
+} Elf_Internal_Dyn;
+
+#define elf32_internal_dyn elf_internal_dyn
+#define elf64_internal_dyn elf_internal_dyn
+#define Elf32_Internal_Dyn Elf_Internal_Dyn
+#define Elf64_Internal_Dyn Elf_Internal_Dyn
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/include/elf/mips.h linux/arch/ppc/kernel/include/elf/mips.h
--- pre2.0.7/linux/arch/ppc/kernel/include/elf/mips.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/include/elf/mips.h	Mon May 27 12:00:57 1996
@@ -0,0 +1,267 @@
+/* MIPS ELF support for BFD.
+   Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+
+   By Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>, from
+   information in the System V Application Binary Interface, MIPS
+   Processor Supplement.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* This file holds definitions specific to the MIPS ELF ABI.  Note
+   that most of this is not actually implemented by BFD.  */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+
+/* At least one .noreorder directive appears in the source.  */
+#define EF_MIPS_NOREORDER	0x00000001
+
+/* File contains position independent code.  */
+#define EF_MIPS_PIC		0x00000002
+
+/* Code in file uses the standard calling sequence for calling
+   position independent code.  */
+#define EF_MIPS_CPIC		0x00000004
+
+/* Four bit MIPS architecture field.  */
+#define EF_MIPS_ARCH		0xf0000000
+
+/* -mips1 code.  */
+#define E_MIPS_ARCH_1		0x00000000
+
+/* -mips2 code.  */
+#define E_MIPS_ARCH_2		0x10000000
+
+/* -mips3 code.  */
+#define E_MIPS_ARCH_3		0x20000000
+
+/* Processor specific section indices.  These sections do not actually
+   exist.  Symbols with a st_shndx field corresponding to one of these
+   values have a special meaning.  */
+
+/* Defined and allocated common symbol.  Value is virtual address.  If
+   relocated, alignment must be preserved.  */
+#define SHN_MIPS_ACOMMON	0xff00
+
+/* Defined and allocated text symbol.  Value is virtual address.
+   Occur in the dynamic symbol table of Alpha OSF/1 and Irix 5 executables.  */
+#define SHN_MIPS_TEXT		0xff01
+
+/* Defined and allocated data symbol.  Value is virtual address.
+   Occur in the dynamic symbol table of Alpha OSF/1 and Irix 5 executables.  */
+#define SHN_MIPS_DATA		0xff02
+
+/* Small common symbol.  */
+#define SHN_MIPS_SCOMMON	0xff03
+
+/* Small undefined symbol.  */
+#define SHN_MIPS_SUNDEFINED	0xff04
+
+/* Processor specific section types.  */
+
+/* Section contains the set of dynamic shared objects used when
+   statically linking.  */
+#define SHT_MIPS_LIBLIST	0x70000000
+
+/* I'm not sure what this is, but it's used on Irix 5.  */
+#define SHT_MIPS_MSYM		0x70000001
+
+/* Section contains list of symbols whose definitions conflict with
+   symbols defined in shared objects.  */
+#define SHT_MIPS_CONFLICT	0x70000002
+
+/* Section contains the global pointer table.  */
+#define SHT_MIPS_GPTAB		0x70000003
+
+/* Section contains microcode information.  The exact format is
+   unspecified.  */
+#define SHT_MIPS_UCODE		0x70000004
+
+/* Section contains some sort of debugging information.  The exact
+   format is unspecified.  It's probably ECOFF symbols.  */
+#define SHT_MIPS_DEBUG		0x70000005
+
+/* Section contains register usage information.  */
+#define SHT_MIPS_REGINFO	0x70000006
+
+/* Section contains miscellaneous options (used on Irix).  */
+#define SHT_MIPS_OPTIONS	0x7000000d
+
+/* DWARF debugging section (used on Irix 6).  */
+#define SHT_MIPS_DWARF		0x7000001e
+
+/* Events section.  This appears on Irix 6.  I don't know what it
+   means.  */
+#define SHT_MIPS_EVENTS		0x70000021
+
+/* A section of type SHT_MIPS_LIBLIST contains an array of the
+   following structure.  The sh_link field is the section index of the
+   string table.  The sh_info field is the number of entries in the
+   section.  */
+typedef struct
+{
+  /* String table index for name of shared object.  */
+  unsigned long l_name;
+  /* Time stamp.  */
+  unsigned long l_time_stamp;
+  /* Checksum of symbol names and common sizes.  */
+  unsigned long l_checksum;
+  /* String table index for version.  */
+  unsigned long l_version;
+  /* Flags.  */
+  unsigned long l_flags;
+} Elf32_Lib;
+
+/* The l_flags field of an Elf32_Lib structure may contain the
+   following flags.  */
+
+/* Require an exact match at runtime.  */
+#define LL_EXACT_MATCH		0x00000001
+
+/* Ignore version incompatibilities at runtime.  */
+#define LL_IGNORE_INT_VER	0x00000002
+
+/* A section of type SHT_MIPS_CONFLICT is an array of indices into the
+   .dynsym section.  Each element has the following type.  */
+typedef unsigned long Elf32_Conflict;
+
+/* A section of type SHT_MIPS_GPTAB contains information about how
+   much GP space would be required for different -G arguments.  This
+   information is only used so that the linker can provide informative
+   suggestions as to the best -G value to use.  The sh_info field is
+   the index of the section for which this information applies.  The
+   contents of the section are an array of the following union.  The
+   first element uses the gt_header field.  The remaining elements use
+   the gt_entry field.  */
+typedef union
+{
+  struct
+    {
+      /* -G value actually used for this object file.  */
+      unsigned long gt_current_g_value;
+      /* Unused.  */
+      unsigned long gt_unused;
+    } gt_header;
+  struct
+    {
+      /* If this -G argument has been used...  */
+      unsigned long gt_g_value;
+      /* ...this many GP section bytes would be required.  */
+      unsigned long gt_bytes;
+    } gt_entry;
+} Elf32_gptab;
+
+/* The external version of Elf32_gptab.  */
+
+typedef union
+{
+  struct
+    {
+      unsigned char gt_current_g_value[4];
+      unsigned char gt_unused[4];
+    } gt_header;
+  struct
+    {
+      unsigned char gt_g_value[4];
+      unsigned char gt_bytes[4];
+    } gt_entry;
+} Elf32_External_gptab;
+
+/* A section of type SHT_MIPS_REGINFO contains the following
+   structure.  */
+typedef struct
+{
+  /* Mask of general purpose registers used.  */
+  unsigned long ri_gprmask;
+  /* Mask of co-processor registers used.  */
+  unsigned long ri_cprmask[4];
+  /* GP register value for this object file.  */
+  long ri_gp_value;
+} Elf32_RegInfo;
+
+/* The external version of the Elf_RegInfo structure.  */
+typedef struct
+{
+  unsigned char ri_gprmask[4];
+  unsigned char ri_cprmask[4][4];
+  unsigned char ri_gp_value[4];
+} Elf32_External_RegInfo;
+
+/* MIPS ELF .reginfo swapping routines.  */
+extern void bfd_mips_elf32_swap_reginfo_in
+  PARAMS ((bfd *, const Elf32_External_RegInfo *, Elf32_RegInfo *));
+extern void bfd_mips_elf32_swap_reginfo_out
+  PARAMS ((bfd *, const Elf32_RegInfo *, Elf32_External_RegInfo *));
+
+/* Processor specific section flags.  */
+
+/* This section must be in the global data area.  */
+#define SHF_MIPS_GPREL		0x10000000
+
+/* Processor specific program header types.  */
+
+/* Register usage information.  Identifies one .reginfo section.  */
+#define PT_MIPS_REGINFO		0x70000000
+
+/* Processor specific dynamic array tags.  */
+
+/* 32 bit version number for runtime linker interface.  */
+#define DT_MIPS_RLD_VERSION	0x70000001
+
+/* Time stamp.  */
+#define DT_MIPS_TIME_STAMP	0x70000002
+
+/* Checksum of external strings and common sizes.  */
+#define DT_MIPS_ICHECKSUM	0x70000003
+
+/* Index of version string in string table.  */
+#define DT_MIPS_IVERSION	0x70000004
+
+/* 32 bits of flags.  */
+#define DT_MIPS_FLAGS		0x70000005
+
+/* Base address of the segment.  */
+#define DT_MIPS_BASE_ADDRESS	0x70000006
+
+/* Address of .conflict section.  */
+#define DT_MIPS_CONFLICT	0x70000008
+
+/* Address of .liblist section.  */
+#define DT_MIPS_LIBLIST		0x70000009
+
+/* Number of local global offset table entries.  */
+#define DT_MIPS_LOCAL_GOTNO	0x7000000a
+
+/* Number of entries in the .conflict section.  */
+#define DT_MIPS_CONFLICTNO	0x7000000b
+
+/* Number of entries in the .liblist section.  */
+#define DT_MIPS_LIBLISTNO	0x70000010
+
+/* Number of entries in the .dynsym section.  */
+#define DT_MIPS_SYMTABNO	0x70000011
+
+/* Index of first external dynamic symbol not referenced locally.  */
+#define DT_MIPS_UNREFEXTNO	0x70000012
+
+/* Index of first dynamic symbol in global offset table.  */
+#define DT_MIPS_GOTSYM		0x70000013
+
+/* Number of page table entries in global offset table.  */
+#define DT_MIPS_HIPAGENO	0x70000014
+
+/* Address of run time loader map, used for debugging.  */
+#define DT_MIPS_RLD_MAP		0x70000016
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/include/elf/ppc.h linux/arch/ppc/kernel/include/elf/ppc.h
--- pre2.0.7/linux/arch/ppc/kernel/include/elf/ppc.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/include/elf/ppc.h	Mon May 27 12:00:57 1996
@@ -0,0 +1,32 @@
+/* MIPS PPC support for BFD.
+   Copyright (C) 1995 Free Software Foundation, Inc.
+
+   By Michael Meissner, Cygnus Support, <meissner@cygnus.com>, from information
+   in the System V Application Binary Interface, PowerPC Processor Supplement
+   and the PowerPC Embedded Application Binary Interface (eabi).
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* This file holds definitions specific to the PPC ELF ABI.  Note
+   that most of this is not actually implemented by BFD.  */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+
+#define	EF_PPC_EMB		0x80000000	/* PowerPC embedded flag  */
+
+						/* CYGNUS local bits below */
+#define	EF_PPC_RELOCATABLE	0x00010000	/* PowerPC -mrelocatable flag */
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c
--- pre2.0.7/linux/arch/ppc/kernel/irq.c	Fri Mar  1 07:50:38 1996
+++ linux/arch/ppc/kernel/irq.c	Mon May 27 12:00:58 1996
@@ -24,14 +24,19 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
-#include <linux/malloc.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/bitops.h>
 
-#define CR0_NE 32
+/*
+ * For the BeBox, interrupt numbers are 0..15 for 8259 PIC interrupts
+ * and 16..31 for other BeBox motherboard type interrupts.
+ */
+ 
+unsigned long isBeBox[];
+unsigned char *BeBox_IO_page;
 
 static unsigned char cache_21 = 0xff;
 static unsigned char cache_A1 = 0xff;
@@ -41,15 +46,21 @@
 	unsigned char mask;
 	int s = _disable_interrupts();
 
-	mask = 1 << (irq_nr & 7);
-	if (irq_nr < 8) {
-		cache_21 |= mask;
-		outb(cache_21,0x21);
-		_enable_interrupts(s);
-		return;
+	if (isBeBox[0] && (irq_nr >= 16))
+	{
+		BeBox_disable_irq(irq_nr);
+	} else
+	{
+		mask = 1 << (irq_nr & 7);
+		if (irq_nr < 8) {
+			cache_21 |= mask;
+			outb(cache_21,0x21);
+		} else
+		{
+			cache_A1 |= mask;
+			outb(cache_A1,0xA1);
+		}
 	}
-	cache_A1 |= mask;
-	outb(cache_A1,0xA1);
 	_enable_interrupts(s);
 }
 
@@ -58,104 +69,143 @@
 	unsigned char mask;
 	int s = _disable_interrupts();
 
-	mask = ~(1 << (irq_nr & 7));
-	if (irq_nr < 8) {
-		cache_21 &= mask;
-		outb(cache_21,0x21);
+	if (isBeBox[0] && (irq_nr >= 16))
+	{
+		BeBox_enable_irq(irq_nr);
 		_enable_interrupts(s);
 		return;
+	} else
+	{
+		mask = ~(1 << (irq_nr & 7));
+		if (irq_nr < 8) {
+			cache_21 &= mask;
+			outb(cache_21,0x21);
+		} else
+		{
+			cache_A1 &= mask;
+			outb(cache_A1,0xA1);
+		}
 	}
-	cache_A1 &= mask;
-	outb(cache_A1,0xA1);
 	_enable_interrupts(s);
 }
 
 /*
  * Irq handlers.
  */
-static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL};
-static struct irqaction cascade_irq = { NULL, 0, 0, NULL, NULL, NULL};
-static struct irqaction math_irq = { NULL, 0, 0, NULL, NULL, NULL};
-
-static struct irqaction *irq_action[16] = {
-	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL,
-	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL
+struct irq_action {
+	void (*handler)(int, void *dev, struct pt_regs *);
+	unsigned long flags;
+	unsigned long mask;
+	const char *name;
+	int notified;
+	void *dev_id;
+};
+
+static struct irq_action irq_action[32] = {
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
 };
 
 int get_irq_list(char *buf)
 {
 	int i, len = 0;
-	struct irqaction * action;
+	struct irq_action * action = irq_action;
 
-	for (i = 0 ; i < 16 ; i++) {
-	        action = *(i + irq_action);
-		if (!action) 
-		        continue;
-		len += sprintf(buf+len, "%2d: %8d %c %s",
+	for (i = 0;  i < 132;  i++, action++) {
+		if (!action->handler)
+			continue;
+		len += sprintf(buf+len, "%2d: %8d %c %s\n",
 			i, kstat.interrupts[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
-		for (action=action->next; action; action = action->next) {
-			len += sprintf(buf+len, ",%s %s",
-				(action->flags & SA_INTERRUPT) ? " +" : "",
-				action->name);
-		}
-		len += sprintf(buf+len, "\n");
 	}
 	return len;
 }
 
 asmlinkage void handle_IRQ(struct pt_regs *regs)
 {
-	int irq, s;
-	struct irqaction * action;
+	int irq, _irq, s;
+	struct irq_action *action;
 	intr_count++;
-	/* Figure out IRQ#, etc. */
-	outb(0x0C, 0x20);  /* Poll interrupt controller */
-	irq = inb(0x20);
-	irq &= 0x07;  /* Caution! */
-	if (irq == 2)
-	{ /* Cascaded interrupt -> IRQ8..IRQ15 */
-		outb(0x0C, 0xA0);
-		irq = inb(0xA0) & 0x07;
-		irq += 8;
-	}
-	/* Mask interrupt & Issue EOI to interrupt controller */
-	if (irq > 7)
-	{
-		outb(cache_A1 | (1<<(irq-7)), 0xA1);
-		outb(0x20, 0xA0);
-		/* Need to ack cascade controller as well */
-		outb(0x20, 0x20);
-	} else
+	if (!isBeBox[0] || ((irq = BeBox_irq()) < 16))
 	{
-		outb(cache_21 | (1<<irq), 0x21);
-		outb(0x20, 0x20);
+		/* Figure out IRQ#, etc. */
+		outb(0x0C, 0x20);  /* Poll interrupt controller */
+		irq = _irq = inb(0x20);
+		irq &= 0x07;  /* Caution! */
+		if (irq == 2)
+		{ /* Cascaded interrupt -> IRQ8..IRQ15 */
+			outb(0x0C, 0xA0);
+			irq = (_irq = inb(0xA0)) & 0x07;
+			irq += 8;
+		}
+		/* Mask interrupt & Issue EOI to interrupt controller */
+		if (irq > 7)
+		{
+			cache_A1 |= (1<<(irq-8));
+			outb(cache_A1, 0xA1);
+#if 0			
+			outb(0x20, 0xA0);
+			/* Need to ack cascade controller as well */
+			outb(0x20, 0x20);
+#else			
+			outb(0x60|(irq-8), 0xA0);	/* Specific EOI */
+			/* Need to ack cascade controller as well */
+			outb(0x62, 0x20);
+#endif			
+		} else
+		{
+			cache_21 |= (1<<irq);
+			outb(cache_21, 0x21);
+			outb(0x20, 0x20);
+		}
 	}
-	action = *(irq + irq_action);
+	action = irq + irq_action;
 	kstat.interrupts[irq]++;
-	while (action) {
-	    if (action->handler)
-	    {
+	if (action->handler)
+	{
 		action->handler(irq, action->dev_id, regs);
-	    } else
-	    {
-		_printk("Bogus interrupt #%d\n", irq);
-	    }
-	    action = action->next;
+	} else
+	{
+		printk("Bogus interrupt #%d/%x, PC: %x\n", irq, _irq, regs->nip);
 	}
 	if (_disable_interrupts() && !action->notified)
 	{
 		action->notified = 1;
 		printk("*** WARNING! %s handler [IRQ %d] turned interrupts on!\n", action->name, irq);
 	}
-	/* Re-enable interrupt */
-	if (irq > 7)
+	if (irq < 16)
 	{
-		outb(cache_A1, 0xA1);
+		if (!(action->flags & SA_ONESHOT))
+		{
+			/* Re-enable interrupt */
+			if (irq > 7)
+			{
+				cache_A1 &= ~(1<<(irq-8));
+				outb(cache_A1, 0xA1);
+			} else
+			{
+				cache_21 &= ~(1<<irq);
+				outb(cache_21, 0x21);
+			}
+		}
 	} else
 	{
-		outb(cache_21, 0x21);
+		BeBox_enable_irq(irq);
 	}
 	intr_count--;
 }
@@ -169,10 +219,15 @@
  * Re-initializing the interrupt controller [which might lose some
  * pending edge detected interrupts] seems to fix it.
  */
-void check_irq(void )
+check_irq()
 {
-	int s = _disable_interrupts();
+	int s;
 	unsigned char _a0, _a1, _20, _21;
+	if (isBeBox[0])
+	{
+		return;
+	}
+	s = _disable_interrupts();
 	_a1 = inb(0xA1);
 	_21 = inb(0x21);
 	outb(0x0C, 0x20);  _20 = inb(0x20);	
@@ -201,15 +256,10 @@
 	_enable_interrupts(s);
 }
 
-#define SA_PROBE SA_ONESHOT
-
-int request_irq(unsigned int irq, 
-		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
-		const char * devname,
-		void *dev_id)
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+	unsigned long irqflags, const char * devname, void *dev_id)
 {
-	struct irqaction * action, *tmp = NULL;
+	struct irq_action * action;
 	unsigned long flags;
 
 #if 0
@@ -217,77 +267,33 @@
 cnpause();
 #endif
 	if (irq > 15)
-		return -EINVAL;
-	if (!handler)
-	    return -EINVAL;
-	action = *(irq + irq_action);
-	if (action) {
-	    if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
-		for (tmp = action; tmp->next; tmp = tmp->next);
-	    } else {
-		return -EBUSY;
-	    }
-	    if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) {
-	      printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq);
-	      return -EBUSY;
-	    }   
+	{
+		if (!isBeBox[0] || (irq > 31))
+			return -EINVAL;
 	}
+	action = irq + irq_action;
+	if (action->handler)
+		return -EBUSY;
+	if (!handler)
+		return -EINVAL;
 	save_flags(flags);
 	cli();
-	if (irq == 2)
-	    action = &cascade_irq;
-	else if (irq == 13)
-	  action = &math_irq;
-	else if (irq == TIMER_IRQ)
-	  action = &timer_irq;
-	else
-	  action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-
-	if (!action) { 
-	    restore_flags(flags);
-	    return -ENOMEM;
-	}
-
 	action->handler = handler;
 	action->flags = irqflags;
 	action->mask = 0;
 	action->name = devname;
-	action->next = NULL;
 	action->dev_id = dev_id;
-
-	if (tmp) {
-	    tmp->next = action;
-	} else {
-	    *(irq + irq_action) = action;
-#if 0	
-	    if (!(action->flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */
-		if (action->flags & SA_INTERRUPT)
-		  set_intr_gate(0x20+irq,fast_interrupt[irq]);
-		else
-		  set_intr_gate(0x20+irq,interrupt[irq]);
-	    }
-#endif	
-	    if (irq < 8) {
-		cache_21 &= ~(1<<irq);
-		outb(cache_21,0x21);
-	    } else {
-		cache_21 &= ~(1<<2);
-		cache_A1 &= ~(1<<(irq-8));
-		outb(cache_21,0x21);
-		outb(cache_A1,0xA1);
-	    }
-	}
+	enable_irq(irq);
 	restore_flags(flags);
 	return 0;
 }
 		
 void free_irq(unsigned int irq, void *dev_id)
 {
-	struct irqaction * action = *(irq + irq_action);
-	struct irqaction * tmp = NULL;
+	struct irq_action * action = irq + irq_action;
 	unsigned long flags;
 
-	if (irq > 15) {
+	if (irq > 31) {
 		printk("Trying to free IRQ%d\n",irq);
 		return;
 	}
@@ -295,51 +301,27 @@
 		printk("Trying to free free IRQ%d\n",irq);
 		return;
 	}
-	if (dev_id) {
-	    for (; action; action = action->next) {
-	        if (action->dev_id == dev_id) break;
-		tmp = action;
-	    }
-	    if (!action) {
-		printk("Trying to free free shared IRQ%d\n",irq);
-		return;
-	    }
-	} else if (action->flags & SA_SHIRQ) {
-	    printk("Trying to free shared IRQ%d with NULL device ID\n", irq);
-	    return;
-	}
+	disable_irq(irq);
 	save_flags(flags);
 	cli();
-	if (action && tmp) {
-	    tmp->next = action->next;
-	} else {
-	    *(irq + irq_action) = action->next;
-	}
-
-	if ((irq == 2) || (irq == 13) | (irq == TIMER_IRQ))
-	  memset(action, 0, sizeof(struct irqaction));
-	else 
-	  kfree_s(action, sizeof(struct irqaction));
-	
-	if (!(*(irq + irq_action))) {
-	    if (irq < 8) {
-		cache_21 |= 1 << irq;
-		outb(cache_21,0x21);
-	    } else {
-		cache_A1 |= 1 << (irq-8);
-		outb(cache_A1,0xA1);
-	    }
-#if 0	
-	    set_intr_gate(0x20+irq,bad_interrupt[irq]);
-#endif	
-	}
-
+	action->handler = NULL;
+	action->flags = 0;
+	action->mask = 0;
+	action->name = NULL;
+	action->dev_id = NULL;
 	restore_flags(flags);
 }
 
-static void no_action(int cpl, void *dev_id, struct pt_regs * regs) { }
+#define SA_PROBE SA_ONESHOT
+
+static void no_action(int irq, void *dev, struct pt_regs * regs)
+{
+#ifdef DEBUG
+	printk("Probe got IRQ: %d\n", irq);
+#endif
+}
 
-unsigned /*int*/ long probe_irq_on (void)
+unsigned long probe_irq_on (void)
 {
 	unsigned int i, irqs = 0, irqmask;
 	unsigned long delay;
@@ -369,7 +351,7 @@
 	return irqs;
 }
 
-int probe_irq_off (unsigned /*int*/ long irqs)
+int probe_irq_off (unsigned long irqs)
 {
 	unsigned int i, irqmask;
 
@@ -390,16 +372,9 @@
 		i = -i;
 	return i;
 }
-
+ 
 void init_IRQ(void)
 {
-	unsigned long *vme2_ie  = (unsigned long *)0xFEFF006C;
-	unsigned long *vme2_ic  = (unsigned long *)0xFEFF0074;
-	unsigned long *vme2_il2 = (unsigned long *)0xFEFF007C;
-	unsigned long *vme2_ioc = (unsigned long *)0xFEFF0088;
-	unsigned char *vme2pci_ic = (unsigned char *)0x80802050;
-	unsigned char *ibc_pirq = (unsigned char *)0x80800860;
-	unsigned char *ibc_pcicon = (unsigned char *)0x80800840;
 	int i;
 
 	/* set the clock to 100 Hz */
@@ -410,33 +385,171 @@
 		printk("Unable to get IRQ2 for cascade\n");
 	request_region(0x20,0x20,"pic1");
 	request_region(0xa0,0x20,"pic2");
-#if 0	
-	/* Enable SIG0 */
-	*vme2_ie = (*vme2_ie & 0xFFFBFFFF) | 0x00040000;
-	/* Clear any pending interrupts */
-	*vme2_ic = 0xFFFFFFFF;
-	/* SIG0 -> Level 5 */
-	*vme2_il2 = (*vme2_il2 & 0xFFFFF0FF) | 0x00000500;
-	/* Master interrupt enable */
-	*vme2_ioc |= 0x00800000;
+
+	/* Set up PCI interrupts */
+	route_PCI_interrupts();
+
+	if (isBeBox[0])
+	{
+		BeBox_init_IRQ();
+	}
+}
+
+/*
+ * Wrapper for "bottom 1/2" of interrupt processing.  This routine
+ * is called whenever an interrupt needs non-interrupt-time service.
+ */
+
+_do_bottom_half()
+{
+	_enable_interrupts(1);
+	do_bottom_half();
+	_disable_interrupts();
+}
+ 
+
+/*
+ * Support for interrupts on the BeBox
+ */
+
+#define CPU0_INT_MASK	(volatile unsigned long *)(BeBox_IO_page+0x0F0)
+#define CPU1_INT_MASK	(volatile unsigned long *)(BeBox_IO_page+0x1F0)
+#define INT_SOURCE	(volatile unsigned long *)(BeBox_IO_page+0x2F0)
+#define CPU_RESET	(volatile unsigned long *)(BeBox_IO_page+0x4F0)
+
+#define CPU_HRESET	0x20000000
+#define CPU_SRESET	0x40000000
+
+#define SCSI_IRQ	16
+
+#define INT_SCSI	(1<<21)
+#define INT_8259	(1<<5)
+
+/*
+ * Map of pseudo IRQs to actual bits
+ * Note: We give out IRQ #16..31 for all interrupt sources which are
+ * not found in the 8259 PIC.
+ */
+ 
+unsigned long BeBox_IRQ_map[] =
+   {
+   	INT_SCSI,	/* 16 - SCSI */
+   	0x00000000,	/* 17 - Unused */
+   	0x00000000,	/* 18 - Unused */
+   	0x00000000,	/* 19 - Unused */
+   	0x00000000,	/* 20 - Unused */
+   	0x00000000,	/* 21 - Unused */
+   	0x00000000,	/* 22 - Unused */
+   	0x00000000,	/* 23 - Unused */
+   	0x00000000,	/* 24 - Unused */
+   	0x00000000,	/* 25 - Unused */
+   	0x00000000,	/* 26 - Unused */
+   	0x00000000,	/* 27 - Unused */
+   	0x00000000,	/* 28 - Unused */
+   	0x00000000,	/* 29 - Unused */
+   	0x00000000,	/* 30 - Unused */
+   	0x00000000,	/* 31 - Unused */
+   };
+
+volatile int CPU1_alive;
+volatile int CPU1_trace;
+
+static
+_NOP()
+{
+}
+
+static
+_delay()
+{
+	int i;
+	for (i = 0;  i < 100;  i++) _NOP();
+}
+
+void
+BeBox_init_IRQ(void)
+{
+	int tmr;
+	volatile extern long BeBox_CPU1_vector;
+	*CPU0_INT_MASK = 0x0FFFFFFC;  /* Clear all bits? */	
+	*CPU0_INT_MASK = 0x80000003 | INT_8259;
+	*CPU1_INT_MASK = 0x0FFFFFFC;  
+printk("Start CPU #1 - CPU Status: %x\n", *CPU_RESET);
+	BeBox_CPU1_vector = 0x0100;  /* Reset */
+	tmr = 0;
+	while (CPU1_alive == 0)
+	{
+		if (++tmr == 1000)
+		{
+printk("CPU #1 not there? - CPU Status: %x, Trace: %x\n", *CPU_RESET, CPU1_trace);
+			break;
+		}
+		_delay();
+	}
+printk("CPU #1 running!\n");
+#if 0
+/* Temp - for SCSI */
+	*(unsigned char *)0x81000038 = 0x00;
+	*(unsigned char *)0x8080103C = 0xFF;
+	*(unsigned char *)0x8080100D = 0x32;
 #endif	
-	/* Enable interrupts from VMECHIP */
-	*vme2pci_ic |= 0x08;
-	/* Route PCI interrupts */
-	ibc_pirq[0] = 0x0A;  /* PIRQ0 -> ISA10 */
-	ibc_pirq[1] = 0x0B;  /* PIRQ1 -> ISA11 */
-	ibc_pirq[2] = 0x0E;  /* PIRQ2 -> ISA14 */
-	ibc_pirq[3] = 0x0F;  /* PIRQ3 -> ISA15 */
-	/* Enable PCI interrupts */
-	*ibc_pcicon |= 0x20;
-} 
+}
+
+void
+BeBox_disable_irq(int irq)
+{
+	/* Note: this clears the particular bit */
+	*CPU0_INT_MASK = BeBox_IRQ_map[irq-16];
+}
 
-PCI_irq(int irq)
+void
+BeBox_enable_irq(int irq)
 {
-	static short _irq[] = {10, 11, 14, 15};
-	int res = _irq[(irq-1)&0x03];
+	int s = _disable_interrupts();
+	/* Sets a single bit */
 #if 0	
-	_printk("PCI IRQ #%d = %d\n", irq, res);
+printk("BeBox IRQ Mask = %x", *CPU0_INT_MASK);
+#endif
+	*CPU0_INT_MASK = 0x80000000 | BeBox_IRQ_map[irq-16];
+#if 0
+printk("/%x\n", *CPU0_INT_MASK);
 #endif	
-	return (res);
+	_enable_interrupts(s);	
+}
+
+int
+BeBox_irq(void)
+{
+	int i;
+	unsigned long cpu0_int_mask;
+	unsigned long int_state;
+	cpu0_int_mask = (*CPU0_INT_MASK & 0x0FFFFFFC) & ~INT_8259;
+	int_state = cpu0_int_mask & *INT_SOURCE;
+	if (int_state)
+	{ /* Determine the pseudo-interrupt # */
+#if 0	
+		printk("Ints[%x] = %x, Mask[%x] = %x/%x, State = %x\n", INT_SOURCE, *INT_SOURCE, CPU0_INT_MASK, *CPU0_INT_MASK, cpu0_int_mask, int_state);
+#endif		
+		for (i = 0;  i < 16;  i++)
+		{
+			if (BeBox_IRQ_map[i] & int_state)
+			{
+				return (i+16);
+			}
+		}
+printk("Ints[%x] = %x, Mask[%x] = %x/%x, State = %x\n", INT_SOURCE, *INT_SOURCE, CPU0_INT_MASK, *CPU0_INT_MASK, cpu0_int_mask, int_state);
+printk("Can't find BeBox IRQ!\n");
+	}
+	return (0);
+}
+
+BeBox_state()
+{
+	printk("Int state = %x, CPU0 mask = %x, CPU1 mask = %x\n", *INT_SOURCE, *CPU0_INT_MASK, *CPU1_INT_MASK);
+}
+
+BeBox_CPU1()
+{
+	CPU1_alive++;
+	while (1) ;
 }
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/ksyms.c linux/arch/ppc/kernel/ksyms.c
--- pre2.0.7/linux/arch/ppc/kernel/ksyms.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/ksyms.c	Mon May 27 12:00:58 1996
@@ -0,0 +1,14 @@
+#include <linux/module.h>
+#include <linux/smp.h>
+
+static struct symbol_table arch_symbol_table = {
+#include <linux/symtab_begin.h>
+	/* platform dependent support */
+#include <linux/symtab_end.h>
+};
+
+void arch_syms_export(void)
+{
+	register_symtab(&arch_symbol_table);
+}
+
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/ld.script-user linux/arch/ppc/kernel/ld.script-user
--- pre2.0.7/linux/arch/ppc/kernel/ld.script-user	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/kernel/ld.script-user	Mon May 27 12:00:58 1996
@@ -1,5 +1,6 @@
 OUTPUT_ARCH(powerpc)
-SEARCH_DIR(/usr/local/lib/gcc-lib/powerpc-linux-elf/2.7.0/);
+SEARCH_DIR(libc); SEARCH_DIR(../sa_test/libc); 
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
 /* Do we need any of these for elf?
    __DYNAMIC = 0;    */
 SECTIONS
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S
--- pre2.0.7/linux/arch/ppc/kernel/misc.S	Sat Jan  6 15:19:14 1996
+++ linux/arch/ppc/kernel/misc.S	Mon May 27 12:00:58 1996
@@ -25,7 +25,7 @@
 
 /* This instruction is not implemented on the PPC 603 */
 #define tlbia \
-	li	r4,32; \
+	li	r4,64; \
 	mtspr	CTR,r4; \
 	li	r4,0; \
 0:	tlbie	r4; \
@@ -44,6 +44,7 @@
 	li	r4,0		/* Need [unsigned] value of MSR_EE */
 	ori	r4,r4,MSR_EE	/* Set to turn off bit */
 	andc	r0,r0,r4	/* Clears bit in (r4) */
+	sync			/* Some chip revs have problems here... */
 	mtmsr	r0		/* Update machine state */
 	blr			/* Done */
 
@@ -55,6 +56,7 @@
 _GLOBAL(_enable_interrupts)
 	mfmsr	r0		/* Get current state */
 	rlwimi	r0,r3,16-1,32-16,32-16	/* Insert bit */
+	sync			/* Some chip revs have problems here... */
 	mtmsr	r0		/* Update machine state */
 	blr
 
@@ -73,6 +75,7 @@
  *	__restore_flags(long val)
  */
 _GLOBAL(__restore_flags)
+	sync			/* Some chip revs have problems here... */
 	mtmsr	r3
 	isync
 	blr
@@ -87,6 +90,7 @@
 	li	r4,0		/* Need [unsigned] value of MSR_EE */
 	ori	r4,r4,MSR_EE	/* Set to turn off bit */
 	andc	r0,r0,r4	/* Clears bit in (r4) */
+	sync			/* Some chip revs have problems here... */
 	mtmsr	r0		/* Update machine state */
 	blr			/* Done */
 
@@ -97,6 +101,7 @@
 _GLOBAL(sti)
 	mfmsr	r0		/* Get current state */
 	ori	r0,r0,MSR_EE	/* Turn on 'EE' bit */
+	sync			/* Some chip revs have problems here... */
 	mtmsr	r0		/* Update machine state */
 	blr
 
@@ -114,6 +119,14 @@
 _GLOBAL(_tlbie)
 	tlbie	r3
 	BUMP(__TLBIEs)
+	blr
+
+/*
+ * Fetch the current SR register
+ *   get_SR(int index)
+ */
+_GLOBAL(get_SR)
+	mfsrin	r3,r3
 	blr	
 
 /*
@@ -131,6 +144,52 @@
 	blr
 
 /*
+ * Atomic add/sub/inc/dec operations
+ *
+ * void atomic_add(int c, int *v)
+ * void atomic_sub(int c, int *v)
+ * void atomic_inc(int *v)
+ * void atomic_dec(int *v)
+ * void atomic_dec_and_test(int *v)
+ */
+_GLOBAL(atomic_add)
+10:	lwarx	r5,0,r4		/* Fetch old value & reserve */
+	add	r5,r5,r3	/* Perform 'add' operation */
+	stwcx.	r5,0,r4		/* Update with new value */
+	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
+	blr
+_GLOBAL(atomic_sub)
+10:	lwarx	r5,0,r4		/* Fetch old value & reserve */
+	sub	r5,r5,r3	/* Perform 'add' operation */
+	stwcx.	r5,0,r4		/* Update with new value */
+	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
+	blr
+_GLOBAL(atomic_inc)
+10:	lwarx	r5,0,r3		/* Fetch old value & reserve */
+	addi	r5,r5,1		/* Perform 'add' operation */
+	stwcx.	r5,0,r3		/* Update with new value */
+	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
+	blr
+_GLOBAL(atomic_dec)
+10:	lwarx	r5,0,r3		/* Fetch old value & reserve */
+	subi	r5,r5,1		/* Perform 'add' operation */
+	stwcx.	r5,0,r3		/* Update with new value */
+	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
+	blr
+_GLOBAL(atomic_dec_and_test)
+10:	lwarx	r5,0,r3		/* Fetch old value & reserve */
+	subi	r5,r5,1		/* Perform 'add' operation */
+	stwcx.	r5,0,r3		/* Update with new value */
+	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
+	cmpi	0,r5,0		/* Return 'true' IFF 0 */
+	bne	15f
+	li	r3,1
+	blr
+15:	li	r3,0
+	blr	
+	
+
+/*
  * Delay for a specific # of "loops"
  *	__delay(int loops)
  */
@@ -178,6 +237,29 @@
 	blr
 
 /*
+ * I/O string operations
+ *
+ * insw(port, buf, len)
+ * outsw(port, buf, len)
+ */
+_GLOBAL(_insw)
+	mtctr	r5
+	subi	r4,r4,2
+00:	lhbrx	r5,0,r3
+	sthu	r5,2(r4)
+	bdnz	00b
+	blr
+
+_GLOBAL(_outsw)
+	mtctr	r5
+	subi	r4,r4,2
+00:	lhzu	r5,2(r4)
+	sthbrx	r5,0,r3	
+	bdnz	00b
+	blr	
+
+#if 0	
+/*
  *extern inline int find_first_zero_bit(void * vaddr, unsigned size)
  *{
  *	unsigned long res;
@@ -281,6 +363,7 @@
 	bgt	20b
 90:	mr	r3,r5		/* Compute result */	
 	blr
+#endif
  
 /*
  *
@@ -371,100 +454,36 @@
 	neg	r3,r3
 10:	blr
 
-/*
- * Compute IP checksums
- *   _ip_fast_csum(buf, len) -- Optimized for IP header
- *   _ip_compute_csum(buf, len)
- */
-
-_GLOBAL(_ip_fast_csum)
-	li	r0,0
-	addic	r0,r0,0		/* Clear initial carry */
-	lwz	r4,0(r3)
-	lwz	r5,4(r3)
-	adde	r0,r0,r4
-	lwz	r4,8(r3)
-	adde	r0,r0,r5
-	lwz	r5,12(r3)
-	adde	r0,r0,r4
-	lwz	r4,16(r3)
-	adde	r0,r0,r5
-	adde	r0,r0,r4
-	mr	r3,r0
-	andi.	r3,r3,0xFFFF
-	srwi	r0,r0,16
-	adde	r3,r3,r0
-	andis.	r0,r3,1
-	beq	10f
-	addi	r3,r3,1
-10:	not	r3,r3
-	andi.	r3,r3,0xFFFF
+_GLOBAL(_get_SP)
+	mr	r3,r1		/* Close enough */
 	blr
 
-_GLOBAL(_ip_compute_csum)
-	li	r0,0
-	addic	r0,r0,0
-finish_ip_csum:	
-	subi	r3,r3,4
-	andi.	r5,r3,2		/* Align buffer to longword boundary */
-	beq	10f
-	lhz	r5,4(r3)
-	adde	r0,r0,r5
-	addi	r3,r3,2
-	subi	r4,r4,2
-10:	cmpi	0,r4,16		/* unrolled loop - 16 bytes at a time */
-	blt	20f
-	lwz	r5,4(r3)
-	lwz	r6,8(r3)
-	adde	r0,r0,r5
-	lwz	r5,12(r3)
-	adde	r0,r0,r6
-	lwzu	r6,16(r3)
-	adde	r0,r0,r5
-	adde	r0,r0,r6
-	subi	r4,r4,16
-	b	10b
-20:	cmpi	0,r4,4
-	blt	30f
-	lwzu	r5,4(r3)
-	adde	r0,r0,r5
-	subi	r4,r4,4
-	b	20b
-30:	cmpi	0,r4,2
-	blt	40f
-	lhz	r5,4(r3)
-	addi	r3,r3,2
-	adde	r0,r0,r5
-	subi	r4,r4,2
-40:	cmpi	0,r4,1
-	bne	50f
-	lbz	r5,4(r3)
-	slwi	r5,r5,8		/* Upper byte of word */
-	adde	r0,r0,r5
-50:	mr	r3,r0
-	andi.	r3,r3,0xFFFF
-	srwi	r0,r0,16
-	adde	r3,r3,r0
-	andis.	r0,r3,1
-	beq	60f
-	addi	r3,r3,1
-60:	not	r3,r3
-	andi.	r3,r3,0xFFFF
+_GLOBAL(_get_SDR1)
+	mfspr	r3,SDR1
 	blr
 
-_GLOBAL(_udp_check)
-	addc	r0,r5,r6	/* Add in header fields */
-	adde	r0,r0,r7
-	b	finish_ip_csum	
-#if 0
-_GLOBAL(_tcp_check)
-	addc	r0,r5,r6	/* Add in header fields */
-	adde	r0,r0,r7
-	b	finish_ip_csum	
-#endif
-_GLOBAL(_get_SP)
-	mr	r3,r1		/* Close enough */
-	blr	
+_GLOBAL(_get_SRx)
+	mfsrin	r3,r3
+	blr
+
+_GLOBAL(_get_PVR)
+	mfspr	r3,PVR
+	blr
+
+/*
+ * Create a kernel thread
+ *   __kernel_thread(flags, fn, arg)
+ */
+#define SYS_CLONE 	120
+_GLOBAL(__kernel_thread)
+__kernel_thread:
+	li	r0,SYS_CLONE
+	sc
+	cmpi	0,r3,0
+	bnelr
+	mtlr	r4
+	mr	r3,r5
+	blr
 
 /* Why isn't this a) automatic, b) written in 'C'? */	
 	.data
@@ -560,8 +579,7 @@
 	.long sys_uselib
 	.long sys_swapon
 	.long sys_reboot
-/*	.long sys_readdir*/
-	.long old_readdir
+	.long old_readdir		/* was sys_readdir */
 	.long sys_mmap			/* 90 */
 	.long sys_munmap
 	.long sys_truncate
@@ -617,11 +635,22 @@
 	.long sys_newselect
 	.long sys_flock
 	.long sys_msync
-        .space (NR_syscalls-144)*4
+	.long sys_readv		/* 145 */
+	.long sys_writev
+	.long sys_getsid
+	.long sys_fdatasync
+	.long sys_sysctl
+	.long sys_mlock		/* 150 */
+	.long sys_munlock
+	.long sys_mlockall
+	.long sys_munlockall
+	.long sys_sched_setparam
+	.long sys_sched_getparam   /* 155 */
+	.long sys_sched_setscheduler
+	.long sys_sched_getscheduler
+	.long sys_sched_yield
+	.long sys_sched_get_priority_max
+	.long sys_sched_get_priority_min  /* 160 */
+	.long sys_sched_rr_get_interval
+	.space (NR_syscalls-162)*4
 
-	.data
-#if 0
-	.globl	floppy_track_buffer
-floppy_track_buffer:
-	.space	512*2*38		/* Space for one entire cylinder! */	
-#endif
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/mk_defs.c linux/arch/ppc/kernel/mk_defs.c
--- pre2.0.7/linux/arch/ppc/kernel/mk_defs.c	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/kernel/mk_defs.c	Mon May 27 12:00:58 1996
@@ -28,7 +28,7 @@
 	struct pt_regs regs;
 	if (!(out = fopen(argv[1], "w")))
 	{
-		fprintf(stderr, "Can't create output file: %d\n", errno);
+		fprintf(stderr, "Can't create output file: %s\n", strerror(errno));
 		exit(1);
 	}
 	fprintf(out, "/*\n");
@@ -42,6 +42,10 @@
 	put_line(out, "TSS", (int)&task.tss-(int)&task);
 	put_line(out, "KSP", (int)&tss.ksp-(int)&tss);
 	put_line(out, "LAST_PC", (int)&tss.last_pc-(int)&tss);
+	put_line(out, "USER_STACK", (int)&tss.user_stack-(int)&tss);
+	put_line(out, "PT_REGS", (int)&tss.regs-(int)&tss);
+	put_line(out, "PF_TRACESYS", PF_TRACESYS);
+	put_line(out, "TASK_FLAGS", (int)&task.flags-(int)&task);
 	put_line(out, "MMU_SEG0", (int)&tss.segs[0]-(int)&tss);
 	put_line(out, "MMU_SEG1", (int)&tss.segs[1]-(int)&tss);
 	put_line(out, "MMU_SEG2", (int)&tss.segs[2]-(int)&tss);
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/mkboot.c linux/arch/ppc/kernel/mkboot.c
--- pre2.0.7/linux/arch/ppc/kernel/mkboot.c	Mon Oct 30 05:26:02 1995
+++ linux/arch/ppc/kernel/mkboot.c	Mon May 27 12:00:58 1996
@@ -1,67 +1,269 @@
+/*
+ * mkboot - Make a 'boot' image from a PowerPC (ELF) binary
+ *
+ * usage: mkboot <ELF-file> <Boot-file>
+ *
+ */
+
+#include <stdlib.h>
 #include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
+#include <errno.h>
+#include <elf/common.h>
+#include <elf/external.h>
+
+#define MAX_SECTIONS 64
+int fd;
+Elf32_External_Ehdr hdr;
+Elf32_External_Shdr sections[MAX_SECTIONS];
+char *symtab;
+
+/* Boolean type definitions */
+
+#define FALSE     0
+#define TRUE      1
+#define bool  short
 
-/* amount to skip */
-#define PLACE 65536
+extern char *strerror();
+extern int errno;
 
-/* size of read buffer */
-#define SIZE 0x200000
+#define ADDR unsigned long
 
+/* Definitions that control the shape of the output */
+#define MAX_ITEMS  32  /* Max # bytes per line */
 
-void main(int argc, char **argv )
+FILE *in_file;  /* Input (binary image) file */
+FILE *out_file; /* Output (boot image) file */
+
+int org = -1;
+
+#ifdef linux
+long
+_LONG(unsigned long *p)
 {
-  int fd, fdo;
-  unsigned char data[SIZE];
-  int i, n, skip;
+  unsigned char *xp = (unsigned char *)p;
+  return ((xp[0]<<24) | (xp[1]<<16) | (xp[2]<<8) | xp[3]);
+}
 
-  if ( argc != 3 )
+unsigned short
+_USHORT(unsigned short *p)
+{
+  unsigned char *xp = (unsigned char *)p;
+  return ((xp[0]<<8) | xp[1]);
+}
+#else
+#define _LONG *
+#define _USHORT *
+#endif
+
+Elf32_External_Shdr *
+find_section(char *section_name)
+{
+  Elf32_External_Shdr *shdr = sections;
+  int i;
+  for (i = 0;  i < MAX_SECTIONS;  i++, shdr++)
   {
-    fprintf(stderr,"%s infile outfile\n", argv[0]);
-    exit(-1);
+    if (strcmp(section_name, &symtab[_LONG((int *)shdr->sh_name)]) == 0)
+    {
+      return (shdr);
+    }
   }
+  return ((Elf32_External_Shdr *)0);
+}
 
+main (argc, argv)
+  int argc;
+  char *argv[];
+{
+  if ((argc == 3) || (argc == 4))
+  {
+    if (argc == 4)
+    {
+      org = strtol(argv[3], NULL, 0);
+    }
+    if (init(argc, argv))
+    {
+      process(argv[2]);
+    }
+    else exit(255);
+  } else
+  { /* Illegal command line */
+    fprintf(stderr, "Syntax: mkboot <bin_file> <out_file>\n");
+    exit(255);
+  }
+  exit(0);
+}
 
-  fd = open(argv[1], O_RDONLY);
-  if ( fd == -1 )
+init(argc, argv)
+  int argc;
+  char *argv[];
+{
+  int sizeof_sections, size;
+  char *fn = argv[1];
+  Elf32_External_Shdr *shdr;
+  if ((out_file = fopen(argv[2], "w")) == (FILE *)NULL)
+  {
+    io_err("creating output file");
+    return (FALSE);
+  }
+  if ((in_file = fopen(fn, "r")) == (FILE *)NULL)
+  {
+    fprintf(stderr, "Can't open '%s': %s\n", fn, strerror(errno));
+    return (FALSE);
+  }
+  if (fread(&hdr, sizeof(hdr), 1, in_file) != 1)
   {
-    fprintf(stderr,"Couldn't open %s\n", argv[1]);
-    perror("open()");
-    exit(-1);
+    fprintf(stderr, "Can't read ELF header: %s\n", strerror(errno));
+    return (FALSE);
   }
-  
-  fdo = open(argv[2], O_WRONLY|O_CREAT);
-  if ( fdo == -1 )
+  /* Make sure this is a file we like */
+  if ((hdr.e_ident[EI_MAG0] != ELFMAG0) || (hdr.e_ident[EI_MAG1] != ELFMAG1) ||
+      (hdr.e_ident[EI_MAG2] != ELFMAG2) || (hdr.e_ident[EI_MAG3] != ELFMAG3))
   {
-    fprintf(stderr,"Couldn't open %s\n", argv[2]);
-    perror("open()");
-    exit(-1);
+    fprintf(stderr, "Invalid binary file (not ELF)\n");
+    return (FALSE);
   }
+  if (hdr.e_ident[EI_CLASS] != ELFCLASS32)
+  {
+    fprintf(stderr, "Invalid binary file (not ELF32)\n");
+    return (FALSE);
+  }
+  if ((_USHORT((unsigned short *)hdr.e_machine) != EM_CYGNUS_POWERPC) &&
+      (_USHORT((unsigned short *)hdr.e_machine) != EM_PPC))
+  {
+    fprintf(stderr, "Invalid binary file (not PowerPC)\n");
+    return (FALSE);
+  }
+  if (_USHORT((unsigned short *)hdr.e_shnum) > MAX_SECTIONS)
+  {
+    fprintf(stderr, "Invalid binary file (too many sections)\n");
+    return (FALSE);
+  }
+  fseek(in_file, _LONG((int *)hdr.e_shoff), 0);
+  sizeof_sections = _USHORT((unsigned short *)hdr.e_shnum) * sizeof(sections[0]);
+  if (fread(sections, sizeof_sections, 1, in_file) != 1)
+  {
+    fprintf(stderr, "Can't read sections: %s\n", strerror(errno));
+    return (FALSE);
+  }
+  /* Read in symbol table */
+  shdr = &sections[_USHORT((unsigned short *)hdr.e_shstrndx)];
+  size = _LONG((int *)shdr->sh_size);
+  if (!(symtab = malloc(256)))
+  {
+    fprintf(stderr, "Can't allocate memory for symbol table.\n");
+    return (FALSE);
+  }
+  fseek(in_file, _LONG((int *)shdr->sh_offset), 0);
+  if (fread(symtab, size, 1, in_file) != 1)
+  {
+    fprintf(stderr, "Can't read symbol table: %s\n", strerror(errno));
+    return (FALSE);
+  }
+  return (TRUE);
+}
 
-#if 0
-  skip = atoi(argv[3]);
-#else
-  skip = PLACE;
-#endif
-  i = lseek(fd, skip, SEEK_SET);
-  printf("lseek'd %d bytes\n", i);
-  if ( i == -1 )
+process(out_name)
+  char *out_name;
+{
+  Elf32_External_Shdr *shdr_text, *shdr_data;
+  long relocated_text_base, text_base, text_offset, text_size;
+  long relocated_data_base, data_base, data_offset, data_size;
+  shdr_text = find_section(".text");
+  shdr_data = find_section(".data");
+  text_base = relocated_text_base = _LONG((int *)shdr_text->sh_addr);
+  text_size = _LONG((int *)shdr_text->sh_size);
+  text_offset = _LONG((int *)shdr_text->sh_offset);
+  data_base = relocated_data_base = _LONG((int *)shdr_data->sh_addr);
+  data_size = _LONG((int *)shdr_data->sh_size);
+  data_offset = _LONG((int *)shdr_data->sh_offset);
+  if (org >= 0)
+  {
+  	relocated_text_base = org;
+  	relocated_data_base = data_base - text_base + org;
+  }
+fprintf(stderr, "TEXT %x bytes at %x[%x]\n", text_size, text_base, relocated_text_base);
+fprintf(stderr, "DATA %x bytes at %x[%x]\n", data_size, data_base, relocated_data_base);
+  if (dump_segment(text_offset, relocated_text_base, text_size) &&
+      dump_segment(data_offset, relocated_data_base, data_size))
+  {
+  } else
   {
-      perror("lseek()");
+    unlink(out_name);
   }
+}
 
-  while ( (n = read(fd, data, SIZE)) > 0 )
+dump_segment(off, base, size)
+  long off;
+  ADDR base;
+  long size;
+{
+  char buf[4096];
+  int len;
+  bool ok = TRUE;
+fprintf(stderr, "Reading %x bytes at %x.%x\n", size, off, base);
+  fseek(in_file, 0, 0);
+  fseek(in_file, off, 0);
+#if 0  
+  if (org >= 0)
+  {
+     fseek(out_file, base+org, 0);
+  } else
   {
-    printf("Read %d bytes\n", n);
-    i = write(fdo, data, n);
-    printf("Wrote %d bytes\n", i);    
+     fseek(out_file, base, 0);
   }
+#else
+  fseek(out_file, base, 0);
+#endif  
+  while (size && ok)
+  {
+    len = size;
+    if (len > sizeof(buf))
+    {
+      len = sizeof(buf);
+    }
+    if (fread(buf, sizeof(char), len, in_file) == len)
+    {
+      fwrite(buf, sizeof(char), len, out_file);
+    } else
+    {
+      fprintf(stderr,"Premature EOF encountered.\n");
+      ok = FALSE;
+    }
+    size -= len;
+  }
+  return (ok);
+}
+
+io_err(what)
+  char *what;
+{
+  fprintf(stderr, "Error %s: %s\n", what, strerror(errno));
+}
 
 
-  close(fdo);
-  close(fd);
-  return(0);
+
+#ifdef sun
+extern int sys_nerr;
+extern char *sys_errlist[];
+
+char *
+strerror(int errno)
+{
+	static char msg[32];
+	if (errno <= sys_nerr)
+	{
+		return (sys_errlist[errno]);
+	} else
+	{
+		sprintf(msg, "<<Unknown error: %d>>", errno);
+		return (msg);
+	}
 }
+
+strtoul(char *str, char **radix, int base)
+{
+	return(strtol(str, radix, base));
+}
+#endif
 
 
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/mmu.h linux/arch/ppc/kernel/mmu.h
--- pre2.0.7/linux/arch/ppc/kernel/mmu.h	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/kernel/mmu.h	Mon May 27 12:00:58 1996
@@ -29,6 +29,7 @@
 #define PP_RWXX	0	/* Supervisor read/write, User none */
 #define PP_RWRX 1	/* Supervisor read/write, User read */
 #define PP_RWRW 2	/* Supervisor read/write, User read/write */
+#define PP_RXRX 3	/* Supervisor read,       User read */
 
 /* Segment Register */
 
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/no_ramdisk.S linux/arch/ppc/kernel/no_ramdisk.S
--- pre2.0.7/linux/arch/ppc/kernel/no_ramdisk.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/no_ramdisk.S	Mon May 27 12:00:58 1996
@@ -0,0 +1,6 @@
+	.data
+	.globl builtin_ramdisk_image
+builtin_ramdisk_image:
+	.globl builtin_ramdisk_size
+builtin_ramdisk_size:	.long	0
+
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/pci.c linux/arch/ppc/kernel/pci.c
--- pre2.0.7/linux/arch/ppc/kernel/pci.c	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/kernel/pci.c	Mon May 27 12:00:58 1996
@@ -1,5 +1,9 @@
 /*
  * PCI support
+ * -- rough emulation of "PCI BIOS" functions
+ *
+ * Note: these are very motherboard specific!  Some way needs to
+ * be worked out to handle the differences.
  */
 
 #include <linux/config.h>
@@ -7,15 +11,149 @@
 #include <linux/bios32.h>
 #include <linux/pci.h>
 
+/*
+ * PCI interrupt configuration.  This is motherboard specific.
+ */
+ 
+ 
+/* Which PCI interrupt line does a given device [slot] use? */
+/* Note: This really should be two dimensional based in slot/pin used */
+unsigned char *Motherboard_map;
+
+/* How is the 82378 PIRQ mapping setup? */
+unsigned char *Motherboard_routes;
+
+/* Tables for known hardware */   
+
+/* Motorola PowerStack */
+static char Blackhawk_pci_IRQ_map[16] =
+  {
+  	0,	/* Slot 0  - unused */
+  	0,	/* Slot 1  - unused */
+  	0,	/* Slot 2  - unused */
+  	0,	/* Slot 3  - unused */
+  	0,	/* Slot 4  - unused */
+  	0,	/* Slot 5  - unused */
+  	0,	/* Slot 6  - unused */
+  	0,	/* Slot 7  - unused */
+  	0,	/* Slot 8  - unused */
+  	0,	/* Slot 9  - unused */
+  	0,	/* Slot 10 - unused */
+  	0,	/* Slot 11 - unused */
+  	3,	/* Slot 12 - SCSI */
+  	0,	/* Slot 13 - unused */
+  	1,	/* Slot 14 - Ethernet */
+  	0,	/* Slot 15 - unused */
+  };
+
+static char Blackhawk_pci_IRQ_routes[] =
+   {
+   	0,	/* Line 0 - Unused */
+   	9,	/* Line 1 */
+   	11,	/* Line 2 */
+   	14,	/* Line 3 */
+   	15	/* Line 4 */
+   };
+   
+/* Motorola MVME16xx */
+static char Genesis_pci_IRQ_map[16] =
+  {
+  	0,	/* Slot 0  - unused */
+  	0,	/* Slot 1  - unused */
+  	0,	/* Slot 2  - unused */
+  	0,	/* Slot 3  - unused */
+  	0,	/* Slot 4  - unused */
+  	0,	/* Slot 5  - unused */
+  	0,	/* Slot 6  - unused */
+  	0,	/* Slot 7  - unused */
+  	0,	/* Slot 8  - unused */
+  	0,	/* Slot 9  - unused */
+  	0,	/* Slot 10 - unused */
+  	0,	/* Slot 11 - unused */
+  	3,	/* Slot 12 - SCSI */
+  	0,	/* Slot 13 - unused */
+  	1,	/* Slot 14 - Ethernet */
+  	0,	/* Slot 15 - unused */
+  };
+
+static char Genesis_pci_IRQ_routes[] =
+   {
+   	0,	/* Line 0 - Unused */
+   	10,	/* Line 1 */
+   	11,	/* Line 2 */
+   	14,	/* Line 3 */
+   	15	/* Line 4 */
+   };
+   
+/* Motorola Series-E */
+static char Comet_pci_IRQ_map[16] =
+  {
+  	0,	/* Slot 0  - unused */
+  	0,	/* Slot 1  - unused */
+  	0,	/* Slot 2  - unused */
+  	0,	/* Slot 3  - unused */
+  	0,	/* Slot 4  - unused */
+  	0,	/* Slot 5  - unused */
+  	0,	/* Slot 6  - unused */
+  	0,	/* Slot 7  - unused */
+  	0,	/* Slot 8  - unused */
+  	0,	/* Slot 9  - unused */
+  	0,	/* Slot 10 - unused */
+  	0,	/* Slot 11 - unused */
+  	3,	/* Slot 12 - SCSI */
+  	0,	/* Slot 13 - unused */
+  	1,	/* Slot 14 - Ethernet */
+  	0,	/* Slot 15 - unused */
+  };
+
+static char Comet_pci_IRQ_routes[] =
+   {
+   	0,	/* Line 0 - Unused */
+   	10,	/* Line 1 */
+   	11,	/* Line 2 */
+   	14,	/* Line 3 */
+   	15	/* Line 4 */
+   };
+
+/* BeBox */
+static char BeBox_pci_IRQ_map[16] =
+  {
+  	0,	/* Slot 0  - unused */
+  	0,	/* Slot 1  - unused */
+  	0,	/* Slot 2  - unused */
+  	0,	/* Slot 3  - unused */
+  	0,	/* Slot 4  - unused */
+  	0,	/* Slot 5  - unused */
+  	0,	/* Slot 6  - unused */
+  	0,	/* Slot 7  - unused */
+  	0,	/* Slot 8  - unused */
+  	0,	/* Slot 9  - unused */
+  	0,	/* Slot 10 - unused */
+  	0,	/* Slot 11 - unused */
+  	16,	/* Slot 12 - SCSI */
+  	0,	/* Slot 13 - unused */
+  	0,	/* Slot 14 - unused */
+  	0,	/* Slot 15 - unused */
+  };
+
+static char BeBox_pci_IRQ_routes[] =
+   {
+   	0,	/* Line 0 - Unused */
+   	9,	/* Line 1 */
+   	11,	/* Line 2 */
+   	14,	/* Line 3 */
+   	15	/* Line 4 */
+   };
+
 /* #define PCI_DEBUG */
 
+#ifdef PCI_STATS
 int PCI_conversions[2];
+#endif
 
 unsigned long pcibios_init(unsigned long mem_start,
 			   unsigned long mem_end)
 {
-	printk("PPC init stub -- cort\n");
-
 	return mem_start;
 }
 
@@ -24,11 +162,14 @@
   return mem_start;
 }
 
+
 unsigned long
 _LE_to_BE_long(unsigned long val)
 {
 	unsigned char *p = (unsigned char *)&val;
+#ifdef PCI_STATS
 	PCI_conversions[0]++;
+#endif	
 	return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0] << 0));
 }
 
@@ -36,7 +177,9 @@
 _LE_to_BE_short(unsigned long val)
 {
 	unsigned char *p = (unsigned char *)&val;
+#ifdef PCI_STATS
 	PCI_conversions[1]++;
+#endif	
 	return ((p[3] << 8) | (p[2] << 0));
 }
 
@@ -44,7 +187,7 @@
 pcibios_present (void)
 {
 #ifdef PCI_DEBUG	
-	_printk("PCI [BIOS] present?\n");
+	printk("PCI [BIOS] present?\n");
 #endif	
 	return (1);
 }
@@ -57,7 +200,7 @@
 	unsigned long *ptr;
 	dev >>= 3;
 #ifdef PCI_DEBUG	
-	_printk("PCI Read config dword[%d.%d.%x] = ", bus, dev, offset);
+	printk("PCI Read config dword[%d.%d.%x] = ", bus, dev, offset);
 #endif	
 	if ((bus != 0) || (dev < 11) || (dev > 16))
 	{
@@ -67,12 +210,12 @@
 	{
 		ptr = (unsigned long *)(0x80800000 | (1<<dev) | offset);
 #ifdef PCI_DEBUG	
-		_printk("[%x] ", ptr);
+		printk("[%x] ", ptr);
 #endif		
 		_val = _LE_to_BE_long(*ptr);
 	}
 #ifdef PCI_DEBUG	
-	_printk("%x\n", _val);
+	printk("%x\n", _val);
 #endif	
 	*val = _val;
 	return PCIBIOS_SUCCESSFUL;
@@ -86,22 +229,22 @@
 	unsigned short *ptr;
 	dev >>= 3;
 #ifdef PCI_DEBUG	
-	_printk("PCI Read config word[%d.%d.%x] = ", bus, dev, offset);
+	printk("PCI Read config word[%d.%d.%x] = ", bus, dev, offset);
 #endif	
 	if ((bus != 0) || (dev < 11) || (dev > 16))
 	{
-		*val =(unsigned short) 0xFFFFFFFF;
+		*val = 0xFFFFFFFF;
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	} else
 	{
 		ptr = (unsigned short *)(0x80800000 | (1<<dev) | offset);
 #ifdef PCI_DEBUG	
-		_printk("[%x] ", ptr);
+		printk("[%x] ", ptr);
 #endif		
 		_val = _LE_to_BE_short(*ptr);
 	}
 #ifdef PCI_DEBUG	
-	_printk("%x\n", _val);
+	printk("%x\n", _val);
 #endif		
 	*val = _val;
 	return PCIBIOS_SUCCESSFUL;
@@ -112,26 +255,41 @@
     unsigned char dev, unsigned char offset, unsigned char *val)
 {
 	unsigned char _val;
-	unsigned char *ptr;
+	volatile unsigned char *ptr;
 	dev >>= 3;
+	/* Note: the configuration registers don't always have this right! */
+	if (offset == PCI_INTERRUPT_LINE)
+	{
+		if (Motherboard_map[dev] <= 4)
+		{
+			*val = Motherboard_routes[Motherboard_map[dev]];
+		} else
+		{ /* Pseudo interrupts [for BeBox] */
+			*val = Motherboard_map[dev];
+		}
 #ifdef PCI_DEBUG	
-	_printk("PCI Read config byte[%d.%d.%x] = ", bus, dev, offset);
+		printk("PCI Read Interrupt Line[%d.%d] = %d\n", bus, dev, *val);
+#endif		
+		return PCIBIOS_SUCCESSFUL;
+	}
+#ifdef PCI_DEBUG	
+	printk("PCI Read config byte[%d.%d.%x] = ", bus, dev, offset);
 #endif		
 	if ((bus != 0) || (dev < 11) || (dev > 16))
 	{
-		*val = (unsigned char) 0xFFFFFFFF;
+		*val = 0xFFFFFFFF;
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	} else
 	{
 		ptr = (unsigned char *)(0x80800000 | (1<<dev) | offset ^ 1);
 #ifdef PCI_DEBUG	
-		_printk("[%x] ", ptr);
+		printk("[%x] ", ptr);
 #endif		
 		_val = *ptr;
 	}
 #ifdef PCI_DEBUG	
-	_printk("%x\n", _val);
-#endif		
+	printk("%x\n", _val);
+#endif
 	*val = _val;
 	return PCIBIOS_SUCCESSFUL;
 }
@@ -145,7 +303,7 @@
 	dev >>= 3;
 	_val = _LE_to_BE_long(val);
 #ifdef PCI_DEBUG	
-	_printk("PCI Write config dword[%d.%d.%x] = %x\n", bus, dev, offset, _val);
+	printk("PCI Write config dword[%d.%d.%x] = %x\n", bus, dev, offset, _val);
 #endif		
 	if ((bus != 0) || (dev < 11) || (dev > 16))
 	{
@@ -167,7 +325,7 @@
 	dev >>= 3;
 	_val = _LE_to_BE_short(val);
 #ifdef PCI_DEBUG	
-	_printk("PCI Write config word[%d.%d.%x] = %x\n", bus, dev, offset, _val);
+	printk("PCI Write config word[%d.%d.%x] = %x\n", bus, dev, offset, _val);
 #endif		
 	if ((bus != 0) || (dev < 11) || (dev > 16))
 	{
@@ -189,7 +347,7 @@
 	dev >>= 3;
 	_val = val;
 #ifdef PCI_DEBUG	
-	_printk("PCI Write config byte[%d.%d.%x] = %x\n", bus, dev, offset, _val);
+	printk("PCI Write config byte[%d.%d.%x] = %x\n", bus, dev, offset, _val);
 #endif		
 	if ((bus != 0) || (dev < 11) || (dev > 16))
 	{
@@ -207,7 +365,7 @@
 		     unsigned short index, unsigned char *bus,
 		     unsigned char *dev)
 {
-	unsigned int w, desired = (device_id << 16) | vendor;
+	unsigned long w, desired = (device_id << 16) | vendor;
 	int devnr;
 
 	if (vendor == 0xffff) {
@@ -233,9 +391,98 @@
 pcibios_find_class (unsigned int class_code, unsigned short index, 
     unsigned char *bus, unsigned char *dev)
 {
-	printk("pcibios_find_class\n");
-	return PCIBIOS_FUNC_NOT_SUPPORTED;
+	int dev_nr, class, indx;
+	indx = 0;
+#ifdef PCI_DEBUG	
+	printk("pcibios_find_class - class: %x, index: %x", class_code, index);
+#endif	
+	for (dev_nr = 11;  dev_nr < 16;  dev_nr++)
+	{
+		pcibios_read_config_dword(0, dev_nr<<3, PCI_CLASS_REVISION, &class);
+		if ((class>>8) == class_code)
+		{
+			if (index == indx)
+			{
+				*bus = 0;
+				*dev = dev_nr<<3;
+#ifdef PCI_DEBUG
+	printk(" - device: %x\n", dev_nr);
+#endif	
+				return (0);
+			}
+			indx++;
+		}
+	}
+#ifdef PCI_DEBUG
+	printk(" - not found\n");
+#endif	
+	return PCIBIOS_DEVICE_NOT_FOUND;
 }    
 
-const char *pcibios_strerror(int error) { _panic("pcibios_strerror"); } 
-/*int get_pci_list(char *buf) { _panic("get_pci_list"); } */
+const char *pcibios_strerror(int error)
+{
+	static char buf[32];
+	switch (error)
+	{	case PCIBIOS_SUCCESSFUL:
+			return ("PCI BIOS: no error");
+		case PCIBIOS_FUNC_NOT_SUPPORTED:
+			return ("PCI BIOS: function not supported");
+		case PCIBIOS_BAD_VENDOR_ID:
+			return ("PCI BIOS: bad vendor ID");
+		case PCIBIOS_DEVICE_NOT_FOUND:
+			return ("PCI BIOS: device not found");
+		case PCIBIOS_BAD_REGISTER_NUMBER:
+			return ("PCI BIOS: bad register number");
+		case PCIBIOS_SET_FAILED:
+			return ("PCI BIOS: set failed");
+		case PCIBIOS_BUFFER_TOO_SMALL:
+			return ("PCI BIOS: buffer too small");
+		default:
+			sprintf(buf, "PCI BIOS: invalid error #%d", error);
+			return(buf);
+	}
+}
+
+/*
+ * Note: This routine has to access the PCI configuration space
+ * for the PCI bridge chip (Intel 82378).
+ */
+ 
+void route_PCI_interrupts(void)
+{
+	unsigned char *ibc_pirq = (unsigned char *)0x80800860;
+	unsigned char *ibc_pcicon = (unsigned char *)0x80800840;
+	extern unsigned long isBeBox[];
+	int i;
+	/* Decide which motherboard this is & how the PCI interrupts are routed */
+	if (isBeBox[0])
+	{
+		Motherboard_map = BeBox_pci_IRQ_map;
+		Motherboard_routes = BeBox_pci_IRQ_routes;
+	} else
+	{ /* Motorola hardware */
+		switch (inb(0x800) & 0xF0)
+		{
+			case 0x10: /* MVME16xx */
+				Motherboard_map = Genesis_pci_IRQ_map;
+				Motherboard_routes = Genesis_pci_IRQ_routes;
+				break;
+			case 0x20: /* Series E */
+				Motherboard_map = Comet_pci_IRQ_map;
+				Motherboard_routes = Comet_pci_IRQ_routes;
+				break;
+			case 0x40: /* PowerStack */
+			default: /* Can't hurt, can it? */
+				Motherboard_map = Blackhawk_pci_IRQ_map;
+				Motherboard_routes = Blackhawk_pci_IRQ_routes;
+				break;
+		}
+	}
+	/* Set up mapping from slots */
+	for (i = 1;  i <= 4;  i++)
+	{
+		ibc_pirq[i-1] = Motherboard_routes[i];
+	}
+	/* Enable PCI interrupts */
+	*ibc_pcicon |= 0x20;
+} 
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/port_io.c linux/arch/ppc/kernel/port_io.c
--- pre2.0.7/linux/arch/ppc/kernel/port_io.c	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/kernel/port_io.c	Mon May 27 12:00:58 1996
@@ -24,6 +24,41 @@
 	return (_LE_to_BE_long(*((unsigned  long *)(_IO_BASE+port))));
 }
 
+void insb(int port, char *ptr, int len)
+{
+	unsigned char *io_ptr = (unsigned char *)(_IO_BASE+port);
+	while (len-- > 0)
+	{
+		*ptr++ = *io_ptr;
+	}
+}
+
+#if 0
+void insw(int port, short *ptr, int len)
+{
+	unsigned short *io_ptr = (unsigned short *)(_IO_BASE+port);
+	while (len-- > 0)
+	{
+		*ptr++ = _LE_to_BE_short(*io_ptr);
+	}
+}
+#else
+void insw(int port, short *ptr, int len)
+{
+	unsigned short *io_ptr = (unsigned short *)(_IO_BASE+port);
+	_insw(io_ptr, ptr, len);
+}
+#endif
+
+void insw_unswapped(int port, short *ptr, int len)
+{
+	unsigned short *io_ptr = (unsigned short *)(_IO_BASE+port);
+	while (len-- > 0)
+	{
+		*ptr++ = *io_ptr;
+	}
+}
+
 void insl(int port, long *ptr, int len)
 {
 	unsigned long *io_ptr = (unsigned long *)(_IO_BASE+port);
@@ -56,6 +91,41 @@
 {
 	*((unsigned  long *)(_IO_BASE+port)) = _LE_to_BE_long(val);
 	return (val);
+}
+
+void outsb(int port, char *ptr, int len)
+{
+	unsigned char *io_ptr = (unsigned char *)(_IO_BASE+port);
+	while (len-- > 0)
+	{
+		*io_ptr = *ptr++;
+	}
+}
+
+#if 0
+void outsw(int port, short *ptr, int len)
+{
+	unsigned short *io_ptr = (unsigned short *)(_IO_BASE+port);
+	while (len-- > 0)
+	{
+		*io_ptr = _LE_to_BE_short(*ptr++);
+	}
+}
+#else
+void outsw(int port, short *ptr, int len)
+{
+	unsigned short *io_ptr = (unsigned short *)(_IO_BASE+port);
+	_outsw(io_ptr, ptr, len);
+}
+#endif
+
+void outsw_unswapped(int port, short *ptr, int len)
+{
+	unsigned short *io_ptr = (unsigned short *)(_IO_BASE+port);
+	while (len-- > 0)
+	{
+		*io_ptr = *ptr++;
+	}
 }
 
 void outsl(int port, long *ptr, int len)
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/ppc_asm.tmpl linux/arch/ppc/kernel/ppc_asm.tmpl
--- pre2.0.7/linux/arch/ppc/kernel/ppc_asm.tmpl	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/kernel/ppc_asm.tmpl	Mon May 27 12:00:58 1996
@@ -165,7 +165,4 @@
 /* Missing instructions */
 #define bdne	bc 0,2,
 
-#include <asm/ppc_machine.h>
-
-
-
+#include "ppc_machine.h"
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/ppc_defs.h linux/arch/ppc/kernel/ppc_defs.h
--- pre2.0.7/linux/arch/ppc/kernel/ppc_defs.h	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/kernel/ppc_defs.h	Mon May 27 12:00:58 1996
@@ -6,9 +6,13 @@
 #define BLOCKED 16
 #define SIGNAL 12
 #define KERNEL_STACK_PAGE 88
-#define TSS 504
+#define TSS 528
 #define KSP 0
 #define LAST_PC 72
+#define USER_STACK 76
+#define PT_REGS 340
+#define PF_TRACESYS 32
+#define TASK_FLAGS 20
 #define MMU_SEG0 8
 #define MMU_SEG1 12
 #define MMU_SEG2 16
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/ppc_machine.h linux/arch/ppc/kernel/ppc_machine.h
--- pre2.0.7/linux/arch/ppc/kernel/ppc_machine.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/ppc_machine.h	Mon May 27 12:00:58 1996
@@ -0,0 +1,50 @@
+/*
+ * PowerPC machine specifics
+ */
+
+#ifndef _PPC_MACHINE_H_
+#define _PPC_MACHINE_H_ 
+
+/* Bit encodings for Machine State Register (MSR) */
+#define MSR_POW		(1<<18)		/* Enable Power Management */
+#define MSR_TGPR	(1<<17)		/* TLB Update registers in use */
+#define MSR_ILE		(1<<16)		/* Interrupt Little-Endian enable */
+#define MSR_EE		(1<<15)		/* External Interrupt enable */
+#define MSR_PR		(1<<14)		/* Supervisor/User privelege */
+#define MSR_FP		(1<<13)		/* Floating Point enable */
+#define MSR_ME		(1<<12)		/* Machine Check enable */
+#define MSR_FE0		(1<<11)		/* Floating Exception mode 0 */
+#define MSR_SE		(1<<10)		/* Single Step */
+#define MSR_BE		(1<<9)		/* Branch Trace */
+#define MSR_FE1		(1<<8)		/* Floating Exception mode 1 */
+#define MSR_IP		(1<<6)		/* Exception prefix 0x000/0xFFF */
+#define MSR_IR		(1<<5)		/* Instruction MMU enable */
+#define MSR_DR		(1<<4)		/* Data MMU enable */
+#define MSR_RI		(1<<1)		/* Recoverable Exception */
+#define MSR_LE		(1<<0)		/* Little-Endian enable */
+
+#define MSR_		MSR_FP|MSR_FE0|MSR_FE1|MSR_ME
+#define MSR_USER	MSR_|MSR_PR|MSR_EE|MSR_IR|MSR_DR
+
+/* Bit encodings for Hardware Implementation Register (HID0) */
+#define HID0_EMCP	(1<<31)		/* Enable Machine Check pin */
+#define HID0_EBA	(1<<29)		/* Enable Bus Address Parity */
+#define HID0_EBD	(1<<28)		/* Enable Bus Data Parity */
+#define HID0_SBCLK	(1<<27)
+#define HID0_EICE	(1<<26)
+#define HID0_ECLK	(1<<25)
+#define HID0_PAR	(1<<24)
+#define HID0_DOZE	(1<<23)
+#define HID0_NAP	(1<<22)
+#define HID0_SLEEP	(1<<21)
+#define HID0_DPM	(1<<20)
+#define HID0_ICE	(1<<15)		/* Instruction Cache Enable */
+#define HID0_DCE	(1<<14)		/* Data Cache Enable */
+#define HID0_ILOCK	(1<<13)		/* Instruction Cache Lock */
+#define HID0_DLOCK	(1<<12)		/* Data Cache Lock */
+#define HID0_ICFI	(1<<11)		/* Instruction Cache Flash Invalidate */
+#define HID0_DCI	(1<<10)		/* Data Cache Invalidate */
+#define HID0_SIED	(1<<7)		/* Serial Instruction Execution [Disable] */
+#define HID0_BHTE	(1<<2)		/* Branch History Table Enable */
+ 
+#endif
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
--- pre2.0.7/linux/arch/ppc/kernel/process.c	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/kernel/process.c	Mon May 27 12:00:58 1996
@@ -1,10 +1,8 @@
-/* * Last edited: Dec 14 17:32 1995 (cort) */
 /*
  *  linux/arch/ppc/kernel/process.c
  *
  *  Copyright (C) 1995  Linus Torvalds
- *  Adapted for PowerPC by Gary Thomas
- *  Modified by Cort Dougan
+ *  Adapted for PowerPC by Gary THomas
  */
 
 /*
@@ -28,45 +26,44 @@
 #include <asm/system.h>
 #include <asm/io.h>
 
-#include <asm/ppc_machine.h>
+#include "ppc_machine.h"
 
-int dump_fpu (struct user_i387_struct* fpu)
+int
+dump_fpu()
 {
-  return 1;		/* all ppc's have a fpu */
+	return (1);
 }
 
 void
-switch_to(struct task_struct *new)
+switch_to(struct task_struct *prev, struct task_struct *new)
 {
 	struct pt_regs *regs;
 	struct thread_struct *new_tss, *old_tss;
-	int s;
-	regs = (struct pt_regs *)new->tss.ksp;
-/*
-printk("Task %x(%d) -> %x(%d)", current, current->pid, new, new->pid);
-printk(" - IP: %x, SR: %x, SP: %x\n", regs->nip, regs->msr, regs);
-*/
-	s = _disable_interrupts();
+	int s = _disable_interrupts();
+	regs = new->tss.ksp;
+#if 0
+	printk("Task %x(%d) -> %x(%d)", current, current->pid, new, new->pid);
+	printk(" - IP: %x, SR: %x, SP: %x\n", regs->nip, regs->msr, regs);
+	cnpause();
+#endif
 	new_tss = &new->tss;
 	old_tss = &current->tss;
-	current = new;
+	current_set[0] = new;	/* FIX ME! */
 	_switch(old_tss, new_tss);
-
-/*	printk("Back in task %x(%d)\n", current, current->pid);*/
-
+#if 0
+	printk("Back in task %x(%d)\n", current, current->pid);
+#endif
 	_enable_interrupts(s);
 }
 
 asmlinkage int sys_idle(void)
 {
-
 	if (current->pid != 0)
 		return -EPERM;
-/*panic("process.c: sys_idle()\n");*/
+
 	/* endless idle loop with no priority at all */
 	current->counter = -100;
 	for (;;) {
-
 		schedule();
 	}
 }
@@ -92,6 +89,11 @@
 {
 }
 
+void
+release_thread(struct task_struct *t)
+{
+}
+
 /*
  * Copy a thread..
  */
@@ -101,17 +103,26 @@
 	int i;
 	SEGREG *segs;
 	struct pt_regs * childregs;
-
-/*printk("copy thread - NR: %d, Flags: %x, USP: %x, Task: %x, Regs: %x\n", nr, clone_flags, usp, p, regs);*/
-
+#if 0
+printk("copy thread - NR: %d, Flags: %x, USP: %x, Task: %x, Regs: %x\n", nr, clone_flags, usp, p, regs);
+cnpause();
+#endif
 	/* Construct segment registers */
-	segs = (SEGREG *)p->tss.segs;
+	segs = p->tss.segs;
 	for (i = 0;  i < 8;  i++)
 	{
 		segs[i].ks = 0;
 		segs[i].kp = 1;
 		segs[i].vsid = i | (nr << 4);
 	}
+	if ((p->mm->context == 0) || (p->mm->count == 1))
+	{
+		p->mm->context = (nr<<4);
+#if 0		
+printk("Setting MM[%x] Context = %x Task = %x Current = %x/%x\n", p->mm, p->mm->context, p, current, current->mm);
+cnpause();
+#endif
+	}
 	/* Last 8 are shared with kernel & everybody else... */
 	for (i = 8;  i < 16;  i++)
 	{
@@ -120,13 +131,17 @@
 		segs[i].vsid = i;
 	}
 	/* Copy registers */
+#ifdef STACK_HAS_TWO_PAGES
 	childregs = ((struct pt_regs *) (p->kernel_stack_page + 2*PAGE_SIZE)) - 2;
+#else	
+	childregs = ((struct pt_regs *) (p->kernel_stack_page + 1*PAGE_SIZE)) - 2;
+#endif	
 	*childregs = *regs;	/* STRUCT COPY */
 	childregs->gpr[3] = 0;  /* Result from fork() */
-	p->tss.ksp = (unsigned long)childregs;
+	p->tss.ksp = childregs;
 	if (usp >= (unsigned long)regs)
 	{ /* Stack is in kernel space - must adjust */
-		childregs->gpr[1] = (long)(childregs+1);
+		childregs->gpr[1] = childregs+1;
 	} else
 	{ /* Provided stack is in user space */
 		childregs->gpr[1] = usp;
@@ -140,47 +155,44 @@
 {
 }
 
-#if 0 /* mfisk */
+#if 0
 /*
  * Do necessary setup to start up a newly executed thread.
  */
 void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp)
 {
-  regs->nip = eip;
-  regs->gpr[1] = esp;
-  regs->msr = MSR_USER;
+	regs->nip = eip;
+	regs->gpr[1] = esp;
+	regs->msr = MSR_USER;
 #if 0
-/*  printk("current = %x current->mm = %x\n", current, current->mm);
-  printk("task[0] = %x task[0]->mm = %x\n", task[0],task[0]->mm);*/
-  printk("Start thread [%x] at PC: %x, SR: %x, SP: %x\n",
-    regs, eip, regs->msr, esp);
-/*  dump_buf(esp, 64);*/
-/*  dump_buf(eip, 64);*/
-#endif
-}
-#endif
-
-asmlinkage int sys_newselect(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs)
 {
-  panic("sys_newselect unimplemented");
+	int len;
+	len = (unsigned long)0x80000000 - esp;
+	if (len > 128) len = 128;
+	printk("Start thread [%x] at PC: %x, SR: %x, SP: %x\n", regs, eip, regs->msr, esp);
+	dump_buf(esp, len);
+	dump_buf(eip, 0x80);
+	cnpause();
+}
+#endif	
 }
+#endif
 
 asmlinkage int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs)
 {
-  int i;
-  char *a;
-#if 0
-  for ( i = 0 ; i <= 0x400 ; i++)
-  {
-    printk("going to do kmalloc(%d)\n",i);
-    a = kmalloc(i,GFP_KERNEL);
-    a = kmalloc(i,GFP_KERNEL);
-    printk("a = %x\n",a);
-  }
-#endif
-  return do_fork( SIGCHLD, regs->gpr[1], regs);
+	return do_fork(SIGCHLD, regs->gpr[1], regs);
 }
 
+/*
+ * sys_execve() executes a new program.
+ *
+ * This works due to the PowerPC calling sequence: the first 6 args
+ * are gotten from registers, while the rest is on the stack, so
+ * we get a0-a5 for free, and then magically find "struct pt_regs"
+ * on the stack for us..
+ *
+ * Don't do this at home.
+ */
 asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
 	unsigned long a3, unsigned long a4, unsigned long a5,
 	struct pt_regs *regs)
@@ -188,50 +200,45 @@
 	int error;
 	char * filename;
 
-#if 1
-	/* paranoia check.  I really don't trust head.S  -- Cort */
-	if ( regs->marker != 0xDEADDEAD )
-	{
-	  panic("process.c: sys_execve(): regs->marker != DEADDEAD\n");
-	}
-#endif
 	error = getname((char *) a0, &filename);
 	if (error)
-	  return error;
+	{
+printk("Error getting EXEC name: %d\n", error);		
+		return error;
+	}
+	flush_instruction_cache();
 	error = do_execve(filename, (char **) a1, (char **) a2, regs);
-
+#if 0
+if (error)
+{	
+printk("EXECVE - file = '%s', error = %d\n", filename, error);
+}
+#endif
 	putname(filename);
 	return error;
 }
 
-
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long usp, unsigned long a2,
-	unsigned long a3, unsigned long a4, unsigned long a5,
-	struct pt_regs *regs)
+/*
+ * This doesn't actually work correctly like this: we need to do the
+ * same stack setups that fork() does first.
+ */
+asmlinkage int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs)
 {
-  int i;
-  
-  if (!usp)
-    usp = regs->gpr[1];
-  
-
-  /* I hard coded in all the arguments to clone since clone() is inlined
-     and has trouble with its args  with our gcc -- Cort*/
-  return do_fork(/*clone_flags*/CLONE_VM, /*usp*/ regs->gpr[1], regs);
+	unsigned long clone_flags = p1;
+	int res;
+	res = do_fork(clone_flags, regs->gpr[1], regs);
+	return res;
 }
 
-
-
 void
-print_backtrace(void)
+print_backtrace(unsigned long *sp)
 {
-	unsigned long *sp = (unsigned long *)_get_SP();
 	int cnt = 0;
 	printk("... Call backtrace:\n");
 	while (*sp)
 	{
-		printk("%08X ", sp[2]);
-		sp = (unsigned long *)*sp;
+		printk("%08X ", sp[1]);
+		sp = *sp;
 		if (++cnt == 8)
 		{
 			printk("\n");
@@ -241,3 +248,27 @@
 	printk("\n");
 }
 
+void
+print_user_backtrace(unsigned long *sp)
+{
+	int cnt = 0;
+	printk("... [User] Call backtrace:\n");
+	while (valid_addr(sp) && *sp)
+	{
+		printk("%08X ", sp[1]);
+		sp = *sp;
+		if (++cnt == 8)
+		{
+			printk("\n");
+		}
+		if (cnt > 16) break;
+	}
+	printk("\n");
+}
+
+void
+print_kernel_backtrace(void)
+{
+	unsigned long *_get_SP(void);
+	print_backtrace(_get_SP());
+}
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/ptrace.c linux/arch/ppc/kernel/ptrace.c
--- pre2.0.7/linux/arch/ppc/kernel/ptrace.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/ptrace.c	Mon May 27 12:00:58 1996
@@ -0,0 +1,579 @@
+/*
+ *  linux/arch/ppc/kernel/ptrace.c
+ *
+ *  Copyright (C) 1994 by Hamish Macdonald
+ *  Taken from linux/kernel/ptrace.c and modified for M680x0.
+ *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+ *
+ * Adapted from 'linux/arch/m68k/kernel/ptrace.c'
+ * PowerPC version by Gary Thomas (gdt@linuxppc.org)
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file README.legal in the main directory of
+ * this archive for more details.
+ */
+
+#include <stddef.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/* Find the stack offset for a register, relative to tss.ksp. */
+#define PT_REG(reg)	((long)&((struct pt_regs *)0)->reg)
+/* Mapping from PT_xxx to the stack offset at which the register is
+   saved.  Notice that usp has no stack-slot and needs to be treated
+   specially (see get_reg/put_reg below). */
+static int regoff[] = {
+};
+
+/* change a pid into a task struct. */
+static inline struct task_struct * get_task(int pid)
+{
+	int i;
+
+	for (i = 1; i < NR_TASKS; i++) {
+		if (task[i] != NULL && (task[i]->pid == pid))
+			return task[i];
+	}
+	return NULL;
+}
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline long get_reg(struct task_struct *task, int regno)
+{
+	struct pt_regs *regs = task->tss.regs;
+	if (regno <= PT_R31)
+	{
+		return (regs->gpr[regno]);
+	} else
+	if (regno == PT_NIP)
+	{
+		return (regs->nip);
+	} else
+	if (regno == PT_MSR)
+	{
+		return (regs->msr);
+	} else
+	if (regno == PT_ORIG_R3)
+	{
+		return (regs->orig_gpr3);
+	} else
+	if (regno == PT_CTR)
+	{
+		return (regs->ctr);
+	} else
+	if (regno == PT_LNK)
+	{
+		return (regs->link);
+	} else
+	if (regno == PT_XER)
+	{
+		return (regs->xer);
+	} else
+	if (regno == PT_CCR)
+	{
+		return (regs->ccr);
+	}
+	return (0);
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int put_reg(struct task_struct *task, int regno,
+			  unsigned long data)
+{
+	struct pt_regs *regs = task->tss.regs;
+	if (regno <= PT_R31)
+	{
+		regs->gpr[regno] = data;
+	} else
+	if (regno == PT_NIP)
+	{
+		regs->nip = data;
+	} else
+	if (regno == PT_MSR)
+	{
+		regs->msr = data;
+	} else
+	if (regno == PT_CTR)
+	{
+		regs->ctr = data;
+	} else
+	if (regno == PT_LNK)
+	{
+		regs->link = data;
+	} else
+	if (regno == PT_XER)
+	{
+		regs->xer = data;
+	} else
+	if (regno == PT_CCR)
+	{
+		regs->ccr = data;
+	} else
+	{ /* Invalid register */
+		return (-1);
+	}
+	return (0);
+}
+
+static inline
+set_single_step(struct task_struct *task)
+{
+	struct pt_regs *regs = task->tss.regs;
+printk("Set single step - Task: %x, Regs: %x", task, regs);
+printk(", MSR: %x/", regs->msr);	
+	regs->msr |= MSR_SE;
+printk("%x\n", regs->msr);	
+}
+
+static inline
+clear_single_step(struct task_struct *task)
+{
+	struct pt_regs *regs = task->tss.regs;
+	regs->msr &= ~MSR_SE;
+}
+
+/*
+ * This routine gets a long from any process space by following the page
+ * tables. NOTE! You should check that the long isn't on a page boundary,
+ * and that it is in the task area before calling this: this routine does
+ * no checking.
+ *
+ */
+static unsigned long get_long(struct task_struct * tsk, 
+	struct vm_area_struct * vma, unsigned long addr)
+{
+	pgd_t * pgdir;
+	pmd_t * pgmiddle;
+	pte_t * pgtable;
+	unsigned long page;
+
+repeat:
+	pgdir = pgd_offset(vma->vm_mm, addr);
+	if (pgd_none(*pgdir)) {
+		do_no_page(tsk, vma, addr, 0);
+		goto repeat;
+	}
+	if (pgd_bad(*pgdir)) {
+		printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir));
+		pgd_clear(pgdir);
+		return 0;
+	}
+	pgmiddle = pmd_offset(pgdir,addr);
+	if (pmd_none(*pgmiddle)) {
+		do_no_page(tsk, vma, addr, 0);
+		goto repeat;
+	}
+	if (pmd_bad(*pgmiddle)) {
+		printk("ptrace: bad page directory %08lx\n",
+		       pmd_val(*pgmiddle));
+		pmd_clear(pgmiddle);
+		return 0;
+	}
+	pgtable = pte_offset(pgmiddle, addr);
+	if (!pte_present(*pgtable)) {
+		do_no_page(tsk, vma, addr, 0);
+		goto repeat;
+	}
+	page = pte_page(*pgtable);
+/* this is a hack for non-kernel-mapped video buffers and similar */
+	if (page >= high_memory)
+		return 0;
+	page += addr & ~PAGE_MASK;
+	return *(unsigned long *) page;
+}
+
+/*
+ * This routine puts a long into any process space by following the page
+ * tables. NOTE! You should check that the long isn't on a page boundary,
+ * and that it is in the task area before calling this: this routine does
+ * no checking.
+ *
+ * Now keeps R/W state of page so that a text page stays readonly
+ * even if a debugger scribbles breakpoints into it.  -M.U-
+ */
+static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, unsigned long addr,
+	unsigned long data)
+{
+	pgd_t *pgdir;
+	pmd_t *pgmiddle;
+	pte_t *pgtable;
+	unsigned long page;
+		
+repeat:
+	pgdir = pgd_offset(vma->vm_mm, addr);
+	if (!pgd_present(*pgdir)) {
+		do_no_page(tsk, vma, addr, 1);
+		goto repeat;
+	}
+	if (pgd_bad(*pgdir)) {
+		printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir));
+		pgd_clear(pgdir);
+		return;
+	}
+	pgmiddle = pmd_offset(pgdir,addr);
+	if (pmd_none(*pgmiddle)) {
+		do_no_page(tsk, vma, addr, 1);
+		goto repeat;
+	}
+	if (pmd_bad(*pgmiddle)) {
+		printk("ptrace: bad page directory %08lx\n",
+		       pmd_val(*pgmiddle));
+		pmd_clear(pgmiddle);
+		return;
+	}
+	pgtable = pte_offset(pgmiddle, addr);
+	if (!pte_present(*pgtable)) {
+		do_no_page(tsk, vma, addr, 1);
+		goto repeat;
+	}
+	page = pte_page(*pgtable);
+	if (!pte_write(*pgtable)) {
+		do_wp_page(tsk, vma, addr, 2);
+		goto repeat;
+	}
+/* this is a hack for non-kernel-mapped video buffers and similar */
+	if (page < high_memory) {
+		*(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
+	}
+/* we're bypassing pagetables, so we have to set the dirty bit ourselves */
+/* this should also re-instate whatever read-only mode there was before */
+	*pgtable = pte_mkdirty(mk_pte(page, vma->vm_page_prot));
+	flush_tlb_all();
+}
+
+static struct vm_area_struct * find_extend_vma(struct task_struct * tsk, unsigned long addr)
+{
+	struct vm_area_struct * vma;
+
+	addr &= PAGE_MASK;
+	vma = find_vma(tsk,addr);
+	if (!vma)
+		return NULL;
+	if (vma->vm_start <= addr)
+		return vma;
+	if (!(vma->vm_flags & VM_GROWSDOWN))
+		return NULL;
+	if (vma->vm_end - addr > tsk->rlim[RLIMIT_STACK].rlim_cur)
+		return NULL;
+	vma->vm_offset -= vma->vm_start - addr;
+	vma->vm_start = addr;
+	return vma;
+}
+
+/*
+ * This routine checks the page boundaries, and that the offset is
+ * within the task area. It then calls get_long() to read a long.
+ */
+static int read_long(struct task_struct * tsk, unsigned long addr,
+	unsigned long * result)
+{
+	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
+
+	if (!vma)
+		return -EIO;
+	if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
+		unsigned long low,high;
+		struct vm_area_struct * vma_low = vma;
+
+		if (addr + sizeof(long) >= vma->vm_end) {
+			vma_low = vma->vm_next;
+			if (!vma_low || vma_low->vm_start != vma->vm_end)
+				return -EIO;
+		}
+		high = get_long(tsk, vma,addr & ~(sizeof(long)-1));
+		low = get_long(tsk, vma_low,(addr+sizeof(long)) & ~(sizeof(long)-1));
+		switch (addr & (sizeof(long)-1)) {
+			case 3:
+				low >>= 8;
+				low |= high << 24;
+				break;
+			case 2:
+				low >>= 16;
+				low |= high << 16;
+				break;
+			case 1:
+				low >>= 24;
+				low |= high << 8;
+				break;
+		}
+		*result = low;
+	} else
+		*result = get_long(tsk, vma,addr);
+	return 0;
+}
+
+/*
+ * This routine checks the page boundaries, and that the offset is
+ * within the task area. It then calls put_long() to write a long.
+ */
+static int write_long(struct task_struct * tsk, unsigned long addr,
+	unsigned long data)
+{
+	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
+
+	if (!vma)
+		return -EIO;
+	if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
+		unsigned long low,high;
+		struct vm_area_struct * vma_low = vma;
+
+		if (addr + sizeof(long) >= vma->vm_end) {
+			vma_low = vma->vm_next;
+			if (!vma_low || vma_low->vm_start != vma->vm_end)
+				return -EIO;
+		}
+		high = get_long(tsk, vma,addr & ~(sizeof(long)-1));
+		low = get_long(tsk, vma_low,(addr+sizeof(long)) & ~(sizeof(long)-1));
+		switch (addr & (sizeof(long)-1)) {
+			case 0: /* shouldn't happen, but safety first */
+				high = data;
+				break;
+			case 3:
+				low &= 0x000000ff;
+				low |= data << 8;
+				high &= ~0xff;
+				high |= data >> 24;
+				break;
+			case 2:
+				low &= 0x0000ffff;
+				low |= data << 16;
+				high &= ~0xffff;
+				high |= data >> 16;
+				break;
+			case 1:
+				low &= 0x00ffffff;
+				low |= data << 24;
+				high &= ~0xffffff;
+				high |= data >> 8;
+				break;
+		}
+		put_long(tsk, vma,addr & ~(sizeof(long)-1),high);
+		put_long(tsk, vma_low,(addr+sizeof(long)) & ~(sizeof(long)-1),low);
+	} else
+		put_long(tsk, vma,addr,data);
+	return 0;
+}
+
+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	struct user * dummy;
+
+	dummy = NULL;
+
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->flags & PF_PTRACED)
+			return -EPERM;
+		/* set the ptrace bit in the process flags. */
+		current->flags |= PF_PTRACED;
+		return 0;
+	}
+	if (pid == 1)		/* you may not mess with init */
+		return -EPERM;
+	if (!(child = get_task(pid)))
+		return -ESRCH;
+	if (request == PTRACE_ATTACH) {
+		if (child == current)
+			return -EPERM;
+		if ((!child->dumpable ||
+		    (current->uid != child->euid) ||
+		    (current->uid != child->uid) ||
+	 	    (current->gid != child->egid) ||
+	 	    (current->gid != child->gid)) && !suser())
+			return -EPERM;
+		/* the same process cannot be attached many times */
+		if (child->flags & PF_PTRACED)
+			return -EPERM;
+		child->flags |= PF_PTRACED;
+		if (child->p_pptr != current) {
+			REMOVE_LINKS(child);
+			child->p_pptr = current;
+			SET_LINKS(child);
+		}
+		send_sig(SIGSTOP, child, 1);
+		return 0;
+	}
+	if (!(child->flags & PF_PTRACED))
+		return -ESRCH;
+	if (child->state != TASK_STOPPED) {
+		if (request != PTRACE_KILL)
+			return -ESRCH;
+	}
+	if (child->p_pptr != current)
+		return -ESRCH;
+
+	switch (request) {
+	/* If I and D space are separate, these will need to be fixed. */
+		case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+		case PTRACE_PEEKDATA: {
+			unsigned long tmp;
+			int res;
+
+			res = read_long(child, addr, &tmp);
+			if (res < 0)
+				return res;
+			res = verify_area(VERIFY_WRITE, (void *) data, sizeof(long));
+			if (!res)
+				put_user(tmp, (unsigned long *) data);
+			return res;
+		}
+
+	/* read the word at location addr in the USER area. */
+		case PTRACE_PEEKUSR: {
+			unsigned long tmp;
+			int res;
+			
+			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
+				return -EIO;
+			
+			res = verify_area(VERIFY_WRITE, (void *) data,
+					  sizeof(long));
+			if (res)
+				return res;
+			tmp = 0;  /* Default return condition */
+			addr = addr >> 2; /* temporary hack. */
+			if (addr < PT_FPR0) {
+				tmp = get_reg(child, addr);
+			}
+#if 0			
+			else if (addr >= PT_FPR0 && addr < PT_FPR31)
+				tmp = child->tss.fpr[addr - PT_FPR0];
+#endif				
+			else
+				return -EIO;
+			put_user(tmp,(unsigned long *) data);
+			return 0;
+		}
+
+      /* If I and D space are separate, this will have to be fixed. */
+		case PTRACE_POKETEXT: /* write the word at location addr. */
+		case PTRACE_POKEDATA:
+			return write_long(child,addr,data);
+
+		case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
+				return -EIO;
+
+			addr = addr >> 2; /* temporary hack. */
+			    
+			if (addr == PT_ORIG_R3)
+				return -EIO;
+#if 0 /* Let this check be in 'put_reg' */				
+			if (addr == PT_SR) {
+				data &= SR_MASK;
+				data <<= 16;
+				data |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
+			}
+#endif			
+			if (addr < PT_FPR0) {
+				if (put_reg(child, addr, data))
+					return -EIO;
+				return 0;
+			}
+#if 0			
+			if (addr >= 21 && addr < 48)
+			{
+				child->tss.fp[addr - 21] = data;
+				return 0;
+			}
+#endif			
+			return -EIO;
+
+		case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+		case PTRACE_CONT: { /* restart after signal. */
+			if ((unsigned long) data >= NSIG)
+				return -EIO;
+			if (request == PTRACE_SYSCALL)
+				child->flags |= PF_TRACESYS;
+			else
+				child->flags &= ~PF_TRACESYS;
+			child->exit_code = data;
+			wake_up_process(child);
+			/* make sure the single step bit is not set. */
+			clear_single_step(child);
+			return 0;
+		}
+
+/*
+ * make the child exit.  Best I can do is send it a sigkill. 
+ * perhaps it should be put in the status that it wants to 
+ * exit.
+ */
+		case PTRACE_KILL: {
+			if (child->state == TASK_ZOMBIE) /* already dead */
+				return 0;
+			wake_up_process(child);
+			child->exit_code = SIGKILL;
+			/* make sure the single step bit is not set. */
+			clear_single_step(child);
+			return 0;
+		}
+
+		case PTRACE_SINGLESTEP: {  /* set the trap flag. */
+			if ((unsigned long) data >= NSIG)
+				return -EIO;
+			child->flags &= ~PF_TRACESYS;
+			set_single_step(child);
+			wake_up_process(child);
+			child->exit_code = data;
+			/* give it a chance to run. */
+			return 0;
+		}
+
+		case PTRACE_DETACH: { /* detach a process that was attached. */
+			if ((unsigned long) data >= NSIG)
+				return -EIO;
+			child->flags &= ~(PF_PTRACED|PF_TRACESYS);
+			wake_up_process(child);
+			child->exit_code = data;
+			REMOVE_LINKS(child);
+			child->p_pptr = child->p_opptr;
+			SET_LINKS(child);
+			/* make sure the single step bit is not set. */
+			clear_single_step(child);
+			return 0;
+		}
+
+		default:
+			return -EIO;
+	}
+}
+
+asmlinkage void syscall_trace(void)
+{
+	if ((current->flags & (PF_PTRACED|PF_TRACESYS))
+			!= (PF_PTRACED|PF_TRACESYS))
+		return;
+	current->exit_code = SIGTRAP;
+	current->state = TASK_STOPPED;
+	notify_parent(current);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code)
+		current->signal |= (1 << (current->exit_code - 1));
+	current->exit_code = 0;
+	return;
+}
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/ramdisk_drvr.c linux/arch/ppc/kernel/ramdisk_drvr.c
--- pre2.0.7/linux/arch/ppc/kernel/ramdisk_drvr.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/ramdisk_drvr.c	Mon May 27 12:00:58 1996
@@ -0,0 +1,84 @@
+/*
+ *  linux/kernel/blk_drv/ramdisk.c
+ *
+ *  Written by Theodore Ts'o, 12/2/91
+ *
+ * Modifications by Fred N. van Kempen to allow for bootable root
+ * disks (which are used in LINUX/Pro).  Also some cleanups.  03/03/93
+ */
+
+
+#include <linux/sched.h>
+#include <linux/minix_fs.h>
+#include <linux/ext2_fs.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+
+#include <asm/system.h>
+#include <asm/segment.h>
+
+#define MAJOR_NR  MEM_MAJOR
+#include <linux/blk.h>
+
+#define RAMDISK_MINOR	1
+
+char	*rd_start;
+int	rd_length = 0;
+static int rd_blocksizes[2] = {0, 0};
+
+static void rd_request(void)
+{
+	int	len;
+	char	*addr;
+
+repeat:
+	INIT_REQUEST;
+	addr = rd_start + (CURRENT->sector << 9);
+	len = CURRENT->current_nr_sectors << 9;
+
+	if (CURRENT-> cmd == WRITE) {
+		(void ) memcpy(addr,
+			      CURRENT->buffer,
+			      len);
+	} else if (CURRENT->cmd == READ) {
+		(void) memcpy(CURRENT->buffer, 
+			      addr,
+			      len);
+	} else
+		panic("RAMDISK: unknown RAM disk command !\n");
+	end_request(1);
+	goto repeat;
+}
+
+static struct file_operations rd_fops = {
+	NULL,			/* lseek - default */
+	block_read,		/* read - general block-dev read */
+	block_write,		/* write - general block-dev write */
+	NULL,			/* readdir - bad */
+	NULL,			/* select */
+	NULL,			/* ioctl */
+	NULL,			/* mmap */
+	NULL,			/* no special open code */
+	NULL,			/* no special release code */
+	block_fsync		/* fsync */
+};
+
+void
+rd_preloaded_init(char *start, int length)
+{
+	int	i;
+
+	if (register_blkdev(MEM_MAJOR,"rd",&rd_fops)) {
+		printk("RAMDISK: Unable to get major %d.\n", MEM_MAJOR);
+		return 0;
+	}
+	blk_dev[MEM_MAJOR].request_fn = DEVICE_REQUEST;
+	rd_start = start;
+	rd_length = length;
+	for(i=0;i<2;i++) rd_blocksizes[i] = 1024;
+	blksize_size[MAJOR_NR] = rd_blocksizes;
+	/* We loaded the file system image.  Prepare for mounting it. */
+	ROOT_DEV = to_kdev_t((MEM_MAJOR << 8) | RAMDISK_MINOR);
+}
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/raw_printf.c linux/arch/ppc/kernel/raw_printf.c
--- pre2.0.7/linux/arch/ppc/kernel/raw_printf.c	Fri Apr 12 15:51:47 1996
+++ linux/arch/ppc/kernel/raw_printf.c	Mon May 27 12:00:58 1996
@@ -2,66 +2,12 @@
 #define TRUE  1
 #include <stdarg.h>
 
-extern void cnputc(char c);
-char cngetc(void);
-int cntstc(void);
-void _cnpause(void);
-void cnpause(void);
-void video_on(void);
-int CRT_init(void);
-int kbd(int noblock);
-int scankbd(void);
-static char *_sprintk_ptr;
-void kbdreset(void);
-int CRT_test(void);
-int CRT_putc(int , unsigned char );
-/*int CRT_putc(int port, u_char c)*/
-int CRT_getc(void);
-int _vprintk(   int (*putc)(), const char *fmt0, va_list ap);
-static _cvt(unsigned long val, char *buf, long radix, char *digits);
-static void cursor(void);
-static void initscreen(void );
-
-/*
- * COM1 NS16550 support
- */
-
-struct NS16550
-	{
-		unsigned char rbr;  /* 0 */
-		unsigned char ier;  /* 1 */
-		unsigned char fcr;  /* 2 */
-		unsigned char lcr;  /* 3 */
-		unsigned char mcr;  /* 4 */
-		unsigned char lsr;  /* 5 */
-		unsigned char msr;  /* 6 */
-		unsigned char scr;  /* 7 */
-	};
-
-#define thr rbr
-#define iir fcr
-#define dll rbr
-#define dlm ier
-
-#define LSR_DR   0x01  /* Data ready */
-#define LSR_OE   0x02  /* Overrun */
-#define LSR_PE   0x04  /* Parity error */
-#define LSR_FE   0x08  /* Framing error */
-#define LSR_BI   0x10  /* Break */
-#define LSR_THRE 0x20  /* Xmit holding register empty */
-#define LSR_TEMT 0x40  /* Xmitter empty */
-#define LSR_ERR  0x80  /* Error */
+extern int isBeBox[];
 
-#define COM1	0x800003F8
-#define COM2	0x800002F8
-
-typedef struct NS16550 *NS16550_t;
+extern void cnputc(char c);
 
-const NS16550_t COM_PORTS[] = { COM1,COM2};
+static char *_sprintk_ptr;
 
-volatile struct NS16550 *NS16550_init(int chan);
-void NS16550_putc(volatile struct NS16550 *com_port, unsigned char c);
-unsigned char NS16550_getc(volatile struct NS16550 *com_port);
 static _sputc(char c)
 {
    *_sprintk_ptr++ = c;
@@ -102,7 +48,11 @@
 
 #define is_digit(c) ((c >= '0') && (c <= '9'))
 
-int _vprintk(   int (*putc)(), const char *fmt0, va_list ap)
+int
+_vprintk(putc, fmt0, ap)
+   int (*putc)();
+   const char *fmt0;
+   va_list ap;
 {
    char c, sign, *cp;
    int left_prec, right_prec, zero_fill, length, pad, pad_on_right;
@@ -262,6 +212,7 @@
 /*
  * Console I/O interface
  */
+
 typedef const (*proc)();
 typedef int dev_t;
 
@@ -276,24 +227,24 @@
 static int line_num = 0;
 #define MAX_LINES 24
 
-char cngetc(void)
+char
+cngetc()
 {
    int s = _disable_interrupts();
    char c = '\0';
    if (port == CRT_PORT)
    {
-/*      c = CRT_getc(port);*/
-     c = CRT_getc();
+      c = CRT_getc(port);
    } else
    if (port)
    {
-      c = NS16550_getc((struct NS16550 *)port);
+      c = NS16550_getc(port);
    }
    _enable_interrupts(s);
    return (c);
 }
 
-int cntstc(void)
+cntstc()
 {
    return (0);
 }
@@ -319,7 +270,7 @@
          port = CRT_PORT;
       } else
       {
-         port =(int) NS16550_init(0);
+         port = NS16550_init(0);
       }
       init = TRUE;
    }
@@ -329,7 +280,7 @@
    } else
    if (port)
    {
-      NS16550_putc((struct NS16550 *)port, c);
+      NS16550_putc(port, c);
    }
    if (c == '\n')
    {
@@ -345,7 +296,7 @@
    }
 }
 
-void _cnpause(void)
+_cnpause()
 {
    int c;
    int s = _disable_interrupts();
@@ -374,17 +325,56 @@
    _enable_interrupts(s);
 }
 
-void cnpause(void)
+cnpause()
 {
    int c;
    int s = _disable_interrupts();
+   flush_data_cache();
    printk("-- More? ");
    while ((c = cngetc()) == 0);
    printk("\r         \r");  /* Erase prompt */
    _enable_interrupts(s);
 }
 
-volatile struct NS16550 *NS16550_init(int chan)
+/*
+ * COM1 NS16550 support
+ */
+
+struct NS16550
+	{
+		unsigned char rbr;  /* 0 */
+		unsigned char ier;  /* 1 */
+		unsigned char fcr;  /* 2 */
+		unsigned char lcr;  /* 3 */
+		unsigned char mcr;  /* 4 */
+		unsigned char lsr;  /* 5 */
+		unsigned char msr;  /* 6 */
+		unsigned char scr;  /* 7 */
+	};
+
+#define thr rbr
+#define iir fcr
+#define dll rbr
+#define dlm ier
+
+#define LSR_DR   0x01  /* Data ready */
+#define LSR_OE   0x02  /* Overrun */
+#define LSR_PE   0x04  /* Parity error */
+#define LSR_FE   0x08  /* Framing error */
+#define LSR_BI   0x10  /* Break */
+#define LSR_THRE 0x20  /* Xmit holding register empty */
+#define LSR_TEMT 0x40  /* Xmitter empty */
+#define LSR_ERR  0x80  /* Error */
+
+#define COM1	0x800003F8
+#define COM2	0x800002F8
+
+typedef struct NS16550 *NS16550_t;
+
+const NS16550_t COM_PORTS[] = { COM1, COM2};
+
+volatile struct NS16550 *
+NS16550_init(int chan)
 {
 	volatile struct NS16550 *com_port;
 	volatile unsigned char xx;
@@ -406,14 +396,13 @@
 }
 
 
-void NS16550_putc(volatile struct NS16550 *com_port, unsigned char c)
+NS16550_putc(volatile struct NS16550 *com_port, unsigned char c)
 {
 	volatile int i;
 	while ((com_port->lsr & LSR_THRE) == 0) ;
 	com_port->thr = c;
 }
 
-
 unsigned char NS16550_getc(volatile struct NS16550 *com_port)
 {
 	while ((com_port->lsr & LSR_DR) == 0) ;
@@ -495,7 +484,8 @@
 /*
  * cursor() sets an offset (0-1999) into the 80x25 text area   
  */
-static void cursor(void)
+static void
+cursor()
 {
  	int pos = screen.cp - Crtat;
 
@@ -508,7 +498,8 @@
 	}
 }
 
-static void initscreen(void )
+static void
+initscreen()
 {
 	struct screen *d = &screen;
 
@@ -545,7 +536,8 @@
  * "ca" is the color/attributes value (left-shifted by 8)
  * or 0 if the current regular color for that screen is to be used.
  */
-int CRT_putc(int port, unsigned char c)
+void 
+CRT_putc(int port, u_char c)
 {
 	struct screen *d = &screen;
 	u_short *base;
@@ -790,20 +782,21 @@
 	cursor();
 }
 
-void video_on(void)
+video_on()
 { /* Enable video */
 	outb(0x3C4, 0x01);
 	outb(0x3C5, inb(0x3C5)&~20);
 }
 
-int CRT_init(void)
+CRT_init()
 {
 	unsigned long *PCI_base = (unsigned long *)0x80808010;  /* Magic */
 	struct screen *d = &screen;
-	if (*PCI_base)
+	if (!isBeBox[0] && *PCI_base)
 	{ /* No CRT configured */
 		return (0);
 	}
+	/* Assume BeBox uses only VGA */
 	video_on();
 	d->cp = Crtat = (u_short *)&ISA_mem[0x0B8000];
 	addr_6845 = CGA_BASE;
@@ -975,7 +968,9 @@
 	_x__, 0x4E, 0x51, 0x4A, _x__, 0x49, 0x46, 0x54, /* 0x78-0x7F */
 };
 
-int kbd(int noblock)
+int
+kbd(noblock)
+	int noblock;
 {
 	unsigned char dt, brk, act;
 	int first = 1;	
@@ -1050,12 +1045,11 @@
 	goto loop;
 }
 
-int scankbd(void)
-{
+scankbd() {
 	return (kbd(1) != -1);
 }
 
-void kbdreset(void)
+kbdreset()
 {
 	unsigned char c;
 
@@ -1076,14 +1070,14 @@
 		;
 }
 
-int CRT_getc(void)
+CRT_getc()
 {
 	int c;
 	while ((c = kbd(0)) == 0) ;
 	return(c);
 }
 
-int CRT_test(void)
+CRT_test()
 {
 	return ((inb(KBSTATP) & KBINRDY) != 0);
 }
@@ -1195,3 +1189,12 @@
 }
 
 
+do_cnpause()
+{
+	static int line = 0;
+	if (++line > MAX_LINES)
+	{
+		cnpause();
+		line = 0;
+	}
+}
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c
--- pre2.0.7/linux/arch/ppc/kernel/setup.c	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/kernel/setup.c	Mon May 27 12:00:58 1996
@@ -22,16 +22,20 @@
 #include <linux/a.out.h>
 #include <linux/tty.h>
 
+#define SIO_CONFIG_RA	0x398
+#define SIO_CONFIG_RD	0x399
+
 #include <asm/pgtable.h>
+
+extern unsigned long *end_of_DRAM;
 extern PTE *Hash;
 extern unsigned long Hash_size, Hash_mask;
 
 char sda_root[] = "root=/dev/sda1";
+extern int root_mountflags;
 
 unsigned char aux_device_present;
-int get_cpuinfo(char *buffer)
-{
-}
+
 /*
  * The format of "screen_info" is strange, and due to early
  * i386-setup code. This is just enough to make the console
@@ -43,8 +47,12 @@
 	0,			/* orig-video-page */
 	0,			/* orig-video-mode */
 	80,			/* orig-video-cols */
-	0,0,0,			/* ega_ax, ega_bx, ega_cx */
-	25			/* orig-video-lines */
+	0,			/* unused [short] */
+	0,			/* ega_bx */
+	0,			/* unused [short] */
+	25,			/* orig-video-lines */
+	0,			/* isVGA */
+	16			/* video points */
 };
 
 unsigned long bios32_init(unsigned long memory_start, unsigned long memory_end)
@@ -57,7 +65,7 @@
 	unsigned char dram_size = inb(0x0804);
 	unsigned long total;
 _printk("DRAM Size = %x\n", dram_size);
-_printk("Config registers = %x/%x/%x\n", inb(0x0800), inb(0x0801), inb(0x0802));
+_printk("Config registers = %x/%x/%x/%x\n", inb(0x0800), inb(0x0801), inb(0x0802), inb(0x0803));
 	switch (dram_size & 0x07)
 	{
 		case 0:
@@ -112,9 +120,8 @@
 			total += 0x00000000;  /* Module not present */
 			break;
 	}
-_printk("register total = %08X\n", total);	
 /* TEMP */ total = 0x01000000;
-/*_cnpause();	*/
+/* _cnpause();	*/
 /* CAUTION!! This can be done more elegantly! */	
 	if (total < 0x01000000)
 	{
@@ -132,25 +139,28 @@
 
 int size_memory;
 
-#define DEFAULT_ROOT_DEVICE 0x0200	/* fd0 */
+/* #define DEFAULT_ROOT_DEVICE 0x0200	/* fd0 */
+#define DEFAULT_ROOT_DEVICE 0x0801	/* sda1 */
 
 void setup_arch(char **cmdline_p,
 	unsigned long * memory_start_p, unsigned long * memory_end_p)
 {
-
-  extern int _end;
+	extern int _end;
 	extern char cmd_line[];
+	unsigned char reg;
 
-	ROOT_DEV = DEFAULT_ROOT_DEVICE;
+	/* Set up floppy in PS/2 mode */
+	outb(0x09, SIO_CONFIG_RA);
+	reg = inb(SIO_CONFIG_RD);
+	reg = (reg & 0x3F) | 0x40;
+	outb(reg, SIO_CONFIG_RD);
+	outb(reg, SIO_CONFIG_RD);	/* Have to write twice to change! */
+	ROOT_DEV = to_kdev_t(DEFAULT_ROOT_DEVICE);
 	aux_device_present = 0xaa;
 	*cmdline_p = cmd_line;
 	*memory_start_p = (unsigned long) &_end;
-	*memory_end_p = (unsigned long *)Hash;
+	*memory_end_p = (unsigned long *)end_of_DRAM;
 	size_memory = *memory_end_p - KERNELBASE;  /* Relative size of memory */
-
-/*	_printk("setup_arch() done!  memory_start = %08X memory_end = %08X\n"
-		,*memory_start_p,*memory_end_p);*/
-
 }
 
 asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
@@ -164,9 +174,40 @@
 void
 builtin_ramdisk_init(void)
 {
-	if (ROOT_DEV == DEFAULT_ROOT_DEVICE)
+	if ((ROOT_DEV == to_kdev_t(DEFAULT_ROOT_DEVICE)) && (builtin_ramdisk_size != 0))
 	{
 		rd_preloaded_init(&builtin_ramdisk_image, builtin_ramdisk_size);
+	} else
+	{  /* Not ramdisk - assume root needs to be mounted read only */
+		root_mountflags |= MS_RDONLY;
 	}
 }
 
+#define MAJOR(n) (((n)&0xFF00)>>8)
+#define MINOR(n) ((n)&0x00FF)
+
+int
+get_cpuinfo(char *buffer)
+{
+	int pvr = _get_PVR();
+	char *model;
+	switch (pvr>>16)
+	{
+		case 3:
+			model = "603";
+			break;
+		case 4:
+			model = "604";
+			break;
+		case 6:
+			model = "603e";
+			break;
+		case 7:
+			model = "603ev";
+			break;
+		default:
+			model = "unknown";
+			break;
+	}
+	return sprintf(buffer, "PowerPC %s rev %d.%d\n", model, MAJOR(pvr), MINOR(pvr));
+}
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/signal.c linux/arch/ppc/kernel/signal.c
--- pre2.0.7/linux/arch/ppc/kernel/signal.c	Mon Mar 11 09:39:33 1996
+++ linux/arch/ppc/kernel/signal.c	Mon May 27 12:00:58 1996
@@ -56,7 +56,13 @@
 	sc++;  /* Pop signal 'context' */
 	if (sc == (struct sigcontext_struct *)(int_regs))
 	{ /* Last stacked signal */
+#if 0	
+		/* This doesn't work - it blows away the return address! */
 		memcpy(regs, int_regs, sizeof(*regs));
+#else
+		/* Don't mess up 'my' stack frame */
+		memcpy(&regs->gpr, &int_regs->gpr, sizeof(*regs)-sizeof(regs->_overhead));
+#endif		
 		if ((int)regs->orig_gpr3 >= 0 &&
 		    ((int)regs->result == -ERESTARTNOHAND ||
 		     (int)regs->result == -ERESTARTSYS ||
@@ -111,7 +117,7 @@
 			if (signr & (1<<bitno)) break;
 		}
 		signr = bitno;
-#endif		
+#endif
 		current->signal &= ~(1<<signr);  /* Clear bit */
 		sa = current->sig->action + signr;
 		signr++;
@@ -166,7 +172,6 @@
 				/* fall through */
 			default:
 				current->signal |= _S(signr & 0x7f);
-				current->flags |= PF_SIGNALED;
 				do_exit(signr);
 			}
 		}
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/stubs.c linux/arch/ppc/kernel/stubs.c
--- pre2.0.7/linux/arch/ppc/kernel/stubs.c	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/kernel/stubs.c	Mon May 27 12:00:58 1996
@@ -1,23 +1,13 @@
 #include <linux/in.h>
 
-unsigned int csum_tcpudp_magic(void);
-void halt(void);
-void _do_bottom_half(void);
-
-void sys_ptrace(void) { _panic("sys_ptrace"); }
 void sys_iopl(void) { _panic("sys_iopl"); }
 void sys_vm86(void) { _panic("sys_vm86"); }
 void sys_modify_ldt(void) { _panic("sys_modify_ldt"); }
-void sys_quotactl(void) { _panic("sys_quotactl"); }
 
-void sys_pipe(void) {_panic("sys_pipe"); }
 void sys_ipc(void) {_panic("sys_ipc"); }
-void sys_mmap(void) {_panic("sys_mmap"); }
-/* unneeded 
-void sys_readdir(void) {panic("sys_readdir"); }
-*/
+void sys_newselect(void) {_panic("sys_newselect"); }
 
-void halt(void)
+halt()
 {
 	_printk("\n...Halt!\n");
 	abort();
@@ -35,86 +25,35 @@
 	_printk("*** Warning: %s UNIMPLEMENTED!\n", msg);
 }
 
-extern unsigned short _ip_fast_csum(unsigned char *buf, int len);
-
-unsigned short
-ip_fast_csum(unsigned char *buf, int len)
-{
-	unsigned short _val;
-	_val = _ip_fast_csum(buf, len);
-#if 0	
-	printk("IP CKSUM(%x, %d) = %x\n", buf, len, _val);
-#endif	
-	return (_val);
-}
-
-extern unsigned short _ip_compute_csum(unsigned char *buf, int len);
 
-unsigned short
-ip_compute_csum(unsigned char *buf, int len)
+void
+saved_command_line(void)
 {
-	unsigned short _val;
-	_val = _ip_compute_csum(buf, len);
-#if 0	
-	printk("Compute IP CKSUM(%x, %d) = %x\n", buf, len, _val);
-#endif	
-	return (_val);
+	panic("saved_command_line");
 }
 
-unsigned short
-_udp_check(unsigned char *buf, int len, int saddr, int daddr, int hdr);
-
-unsigned short
-udp_check(unsigned char *buf, int len, int saddr, int daddr)
+void
+KSTK_EIP(void)
 {
-	unsigned short _val;
-	int hdr;
-	hdr = (len << 16) + IPPROTO_UDP;
-	_val = _udp_check(buf, len, saddr, daddr, hdr);
-#if 0	
-	printk("UDP CSUM(%x,%d,%x,%x) = %x\n", buf, len, saddr, daddr, _val);
-	dump_buf(buf, len);
-#endif	
-	return (_val);
+	panic("KSTK_EIP");
 }
-#if 0
-unsigned short
-_tcp_check(unsigned char *buf, int len, int saddr, int daddr, int hdr);
 
-unsigned short
-tcp_check(unsigned char *buf, int len, int saddr, int daddr)
+void
+KSTK_ESP(void)
 {
-	unsigned short _val;
-	int hdr;
-	hdr = (len << 16) + IPPROTO_TCP;
-	if (saddr == 0) saddr = ip_my_addr();
-	_val = _tcp_check(buf, len, saddr, daddr, hdr);
-#if 0	
-	printk("TCP CSUM(%x,%d,%x,%x) = %x\n", buf, len, saddr, daddr, _val);
-	dump_buf(buf, len);
-#endif	
-	return (_val);
+	panic("KSTK_ESP");
 }
-#endif
 
-void _do_bottom_half(void)
+void
+scsi_register_module(void)
 {
-	_enable_interrupts(1);
-	do_bottom_half();
-	_disable_interrupts();
+	panic("scsi_register_module");
 }
 
-unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum)
+void
+scsi_unregister_module(void)
 {
-  panic("csum_partial");
+	panic("scsi_unregister_module");
 }
 
 
-unsigned int csum_partial_copy(char *src, char *dst, int len, int sum)
-{
-  panic("csum_partial_copy");
-}
-
-unsigned int csum_tcpudp_magic()
-{
-  }
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/support.c linux/arch/ppc/kernel/support.c
--- pre2.0.7/linux/arch/ppc/kernel/support.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/support.c	Mon May 27 12:00:58 1996
@@ -0,0 +1,84 @@
+/*
+ * Miscallaneous support routines
+ */
+
+#include <asm/bitops.h>
+
+/*extern __inline__*/ int find_first_zero_bit(void *add, int len)
+{
+	int	mask, nr, i;
+	BITFIELD *addr = add;
+	nr = 0;
+	while (len)
+	{
+		if (~*addr != 0)
+		{ /* Contains at least one zero */
+			for (i = 0;  i < 32;  i++, nr++)
+			{
+				mask = BIT(nr);
+				if ((mask & *addr) == 0)
+				{
+					return (nr);
+				}
+			}
+		}
+		len -= 32;
+		addr++;
+		nr += 32;
+	}
+	return (0);  /* Shouldn't happen */
+}
+
+/*extern __inline__*/ int find_next_zero_bit(void *add, int last_bit, int nr)
+{
+	int	mask, i;
+	BITFIELD *addr = add;
+#if 0	
+printk("Find next (%x, %x)", addr, nr);
+#endif
+	addr += nr >> 5;
+#if 0	
+printk(" - Pat: %x(%08X)\n", addr, *addr);
+#endif
+	if ((nr & 0x1F) != 0)
+	{ 
+		if (*addr != 0xFFFFFFFF)
+		{ /* At least one more bit available in this longword */
+			for (i = (nr&0x1F);  i < 32;  i++, nr++)
+			{
+				mask = BIT(nr);
+				if ((mask & *addr) == 0)
+				{
+#if 0					
+printk("(1)Bit: %x(%d), Pat: %x(%08x)\n", nr, nr&0x1F, addr, *addr);
+#endif
+					return (nr);
+				}
+			}
+		}
+		addr++;
+		nr = (nr + 0x1F) & ~0x1F;
+	}
+	while (nr < last_bit)
+	{
+		if (*addr != 0xFFFFFFFF)
+		{ /* Contains at least one zero */
+			for (i = 0;  i < 32;  i++, nr++)
+			{
+				mask = BIT(nr);
+				if ((mask & *addr) == 0)
+				{
+#if 0					
+printk("(2)Bit: %x(%d), Pat: %x(%08x)\n", nr, nr&0x1F, addr, *addr);
+#endif
+					return (nr);
+				}
+			}
+		}
+		addr++;
+		nr += 32;
+	}
+	return (nr);  /* Shouldn't happen */
+}
+
+
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/syscalls.c linux/arch/ppc/kernel/syscalls.c
--- pre2.0.7/linux/arch/ppc/kernel/syscalls.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/syscalls.c	Mon May 27 12:00:58 1996
@@ -0,0 +1,188 @@
+/*
+ * linux/arch/ppc/kernel/sys_ppc.c
+ *
+ * Adapted from the i386 version by Gary Thomas
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/PPC
+ * platform.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix tranditionally does this, though.
+ */
+asmlinkage int sys_pipe(unsigned long * fildes)
+{
+	int error;
+	error = verify_area(VERIFY_WRITE,fildes,8);
+	if (error)
+		return error;
+	error = do_pipe(fildes);
+	if (error)
+		return error;
+	return 0;
+}
+
+asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, int prot,
+                                  int flags, int fd, off_t offset)
+{
+	struct file * file = NULL;
+
+	if (!(flags & MAP_ANONYMOUS)) {
+		if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+			return -EBADF;
+	}
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	return do_mmap(file, addr, len, prot, flags, offset);
+}
+
+#if 0
+/*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/i386 didn't use to be able to handle more than
+ * 4 system call parameters, so these system calls used a memory
+ * block for parameter passing..
+ */
+asmlinkage int old_mmap(unsigned long *buffer)
+{
+	int error;
+	unsigned long flags;
+	struct file * file = NULL;
+
+	error = verify_area(VERIFY_READ, buffer, 6*sizeof(long));
+	if (error)
+		return error;
+	flags = get_user(buffer+3);
+	if (!(flags & MAP_ANONYMOUS)) {
+		unsigned long fd = get_user(buffer+4);
+		if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+			return -EBADF;
+	}
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	return do_mmap(file, get_user(buffer), get_user(buffer+1),
+		       get_user(buffer+2), flags, get_user(buffer+5));
+}
+
+extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+
+asmlinkage int old_select(unsigned long *buffer)
+{
+	int n;
+	fd_set *inp;
+	fd_set *outp;
+	fd_set *exp;
+	struct timeval *tvp;
+
+	n = verify_area(VERIFY_READ, buffer, 5*sizeof(unsigned long));
+	if (n)
+		return n;
+	n = get_user(buffer);
+	inp = (fd_set *) get_user(buffer+1);
+	outp = (fd_set *) get_user(buffer+2);
+	exp = (fd_set *) get_user(buffer+3);
+	tvp = (struct timeval *) get_user(buffer+4);
+	return sys_select(n, inp, outp, exp, tvp);
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
+{
+	int version;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	if (call <= SEMCTL)
+		switch (call) {
+		case SEMOP:
+			return sys_semop (first, (struct sembuf *)ptr, second);
+		case SEMGET:
+			return sys_semget (first, second, third);
+		case SEMCTL: {
+			union semun fourth;
+			int err;
+			if (!ptr)
+				return -EINVAL;
+			if ((err = verify_area (VERIFY_READ, ptr, sizeof(long))))
+				return err;
+			fourth.__pad = (void *) get_fs_long(ptr);
+			return sys_semctl (first, second, third, fourth);
+			}
+		default:
+			return -EINVAL;
+		}
+	if (call <= MSGCTL) 
+		switch (call) {
+		case MSGSND:
+			return sys_msgsnd (first, (struct msgbuf *) ptr, 
+					   second, third);
+		case MSGRCV:
+			switch (version) {
+			case 0: {
+				struct ipc_kludge tmp;
+				int err;
+				if (!ptr)
+					return -EINVAL;
+				if ((err = verify_area (VERIFY_READ, ptr, sizeof(tmp))))
+					return err;
+				memcpy_fromfs (&tmp,(struct ipc_kludge *) ptr,
+					       sizeof (tmp));
+				return sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
+				}
+			case 1: default:
+				return sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third);
+			}
+		case MSGGET:
+			return sys_msgget ((key_t) first, second);
+		case MSGCTL:
+			return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+	if (call <= SHMCTL) 
+		switch (call) {
+		case SHMAT:
+			switch (version) {
+			case 0: default: {
+				ulong raddr;
+				int err;
+				if ((err = verify_area(VERIFY_WRITE, (ulong*) third, sizeof(ulong))))
+					return err;
+				err = sys_shmat (first, (char *) ptr, second, &raddr);
+				if (err)
+					return err;
+				put_fs_long (raddr, (ulong *) third);
+				return 0;
+				}
+			case 1:	/* iBCS2 emulator entry point */
+				if (get_fs() != get_ds())
+					return -EINVAL;
+				return sys_shmat (first, (char *) ptr, second, (ulong *) third);
+			}
+		case SHMDT: 
+			return sys_shmdt ((char *)ptr);
+		case SHMGET:
+			return sys_shmget (first, second, third);
+		case SHMCTL:
+			return sys_shmctl (first, second, (struct shmid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+	return -EINVAL;
+}
+#endif
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/time.c linux/arch/ppc/kernel/time.c
--- pre2.0.7/linux/arch/ppc/kernel/time.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/time.c	Mon May 27 12:00:58 1996
@@ -0,0 +1,336 @@
+/*
+ *  linux/arch/i386/kernel/time.c
+ *
+ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *
+ * Adapted for PowerPC (PreP) by Gary Thomas
+ *
+ * This file contains the PC-specific time handling details:
+ * reading the RTC at bootup, etc..
+ * 1994-07-02    Alan Modra
+ *	fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
+ * 1995-03-26    Markus Kuhn
+ *      fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
+ *      precision CMOS clock update
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/nvram.h>
+#include <asm/mc146818rtc.h>
+
+#include <linux/timex.h>
+#include <linux/config.h>
+
+extern int isBeBox[];
+
+#define TIMER_IRQ 0
+
+/* Cycle counter value at the previous timer interrupt.. */
+static unsigned long long last_timer_cc = 0;
+static unsigned long long init_timer_cc = 0;
+
+static inline int CMOS_READ(int addr)
+{
+	outb(addr>>8, NVRAM_AS1);
+	outb(addr, NVRAM_AS0);
+	return (inb(NVRAM_DATA));
+}
+
+/* This function must be called with interrupts disabled 
+ * It was inspired by Steve McCanne's microtime-i386 for BSD.  -- jrs
+ * 
+ * However, the pc-audio speaker driver changes the divisor so that
+ * it gets interrupted rather more often - it loads 64 into the
+ * counter rather than 11932! This has an adverse impact on
+ * do_gettimeoffset() -- it stops working! What is also not
+ * good is that the interval that our timer function gets called
+ * is no longer 10.0002 ms, but 9.9767 ms. To get around this
+ * would require using a different timing source. Maybe someone
+ * could use the RTC - I know that this can interrupt at frequencies
+ * ranging from 8192Hz to 2Hz. If I had the energy, I'd somehow fix
+ * it so that at startup, the timer code in sched.c would select
+ * using either the RTC or the 8253 timer. The decision would be
+ * based on whether there was any other device around that needed
+ * to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz,
+ * and then do some jiggery to have a version of do_timer that 
+ * advanced the clock by 1/1024 s. Every time that reached over 1/100
+ * of a second, then do all the old code. If the time was kept correct
+ * then do_gettimeoffset could just return 0 - there is no low order
+ * divider that can be accessed.
+ *
+ * Ideally, you would be able to use the RTC for the speaker driver,
+ * but it appears that the speaker driver really needs interrupt more
+ * often than every 120 us or so.
+ *
+ * Anyway, this needs more thought....		pjsg (1993-08-28)
+ * 
+ * If you are really that interested, you should be reading
+ * comp.protocols.time.ntp!
+ */
+
+#define TICK_SIZE tick
+
+static unsigned long do_slow_gettimeoffset(void)
+{
+	int count;
+	unsigned long offset = 0;
+
+	/* timer count may underflow right here */
+	outb_p(0x00, 0x43);	/* latch the count ASAP */
+	count = inb_p(0x40);	/* read the latched count */
+	count |= inb(0x40) << 8;
+	/* we know probability of underflow is always MUCH less than 1% */
+	if (count > (LATCH - LATCH/100)) {
+		/* check for pending timer interrupt */
+		outb_p(0x0a, 0x20);
+		if (inb(0x20) & 1)
+			offset = TICK_SIZE;
+	}
+	count = ((LATCH-1) - count) * TICK_SIZE;
+	count = (count + LATCH/2) / LATCH;
+	return offset + count;
+}
+
+static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	*tv = xtime;
+	tv->tv_usec += do_gettimeoffset();
+	if (tv->tv_usec >= 1000000) {
+		tv->tv_usec -= 1000000;
+		tv->tv_sec++;
+	}
+	restore_flags(flags);
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	cli();
+	/* This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+	tv->tv_usec -= do_gettimeoffset();
+
+	if (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime = *tv;
+	time_state = TIME_BAD;
+	time_maxerror = 0x70000000;
+	time_esterror = 0x70000000;
+	sti();
+}
+
+
+/*
+ * In order to set the CMOS clock precisely, set_rtc_mmss has to be
+ * called 500 ms after the second nowtime has started, because when
+ * nowtime is written into the registers of the CMOS clock, it will
+ * jump to the next second precisely 500 ms later. Check the Motorola
+ * MC146818A or Dallas DS12887 data sheet for details.
+ */
+static int set_rtc_mmss(unsigned long nowtime)
+{
+	int retval = 0;
+	int real_seconds, real_minutes, cmos_minutes;
+	unsigned char save_control, save_freq_select;
+
+#ifdef __powerpc__
+return (-1);  /* Not implemented */
+#else	
+
+	save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
+	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
+
+	save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
+	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+	cmos_minutes = CMOS_READ(RTC_MINUTES);
+	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+		BCD_TO_BIN(cmos_minutes);
+
+	/*
+	 * since we're only adjusting minutes and seconds,
+	 * don't interfere with hour overflow. This avoids
+	 * messing with unknown time zones but requires your
+	 * RTC not to be off by more than 15 minutes
+	 */
+	real_seconds = nowtime % 60;
+	real_minutes = nowtime / 60;
+	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+		real_minutes += 30;		/* correct for half hour time zone */
+	real_minutes %= 60;
+
+	if (abs(real_minutes - cmos_minutes) < 30) {
+		if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+			BIN_TO_BCD(real_seconds);
+			BIN_TO_BCD(real_minutes);
+		}
+		CMOS_WRITE(real_seconds,RTC_SECONDS);
+		CMOS_WRITE(real_minutes,RTC_MINUTES);
+	} else
+		retval = -1;
+
+	/* The following flags have to be released exactly in this order,
+	 * otherwise the DS12887 (popular MC146818A clone with integrated
+	 * battery and quartz) will not reset the oscillator and will not
+	 * update precisely 500 ms later. You won't find this mentioned in
+	 * the Dallas Semiconductor data sheets, but who believes data
+	 * sheets anyway ...                           -- Markus Kuhn
+	 */
+	CMOS_WRITE(save_control, RTC_CONTROL);
+	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+
+	return retval;
+#endif	
+}
+
+/* last time the cmos clock got updated */
+static long last_rtc_update = 0;
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+static inline void timer_interrupt(int irq, void *dev, struct pt_regs * regs)
+{
+	do_timer(regs);
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec > 500000 - (tick >> 1) &&
+	    xtime.tv_usec < 500000 + (tick >> 1))
+	  if (set_rtc_mmss(xtime.tv_sec) == 0)
+	    last_rtc_update = xtime.tv_sec;
+	  else
+	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+#if 0
+	/* As we return to user mode fire off the other CPU schedulers.. this is 
+	   basically because we don't yet share IRQ's around. This message is
+	   rigged to be safe on the 386 - basically its a hack, so don't look
+	   closely for now.. */
+	smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); 
+#endif	    
+}
+
+/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+ *
+ * [For the Julian calendar (which was used in Russia before 1917,
+ * Britain & colonies before 1752, anywhere else before 1582,
+ * and is still in use by some communities) leave out the
+ * -year/100+year/400 terms, and add 10.]
+ *
+ * This algorithm was first published by Gauss (I think).
+ *
+ * WARNING: this function will overflow on 2106-02-07 06:28:16 on
+ * machines were long is 32-bit! (However, as time_t is signed, we
+ * will already get problems at other places on 2038-01-19 03:14:08)
+ */
+static inline unsigned long mktime(unsigned int year, unsigned int mon,
+	unsigned int day, unsigned int hour,
+	unsigned int min, unsigned int sec)
+{
+	if (0 >= (int) (mon -= 2)) {	/* 1..12 -> 11,12,1..10 */
+		mon += 12;	/* Puts Feb last since it has leap day */
+		year -= 1;
+	}
+	return (((
+	    (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
+	      year*365 - 719499
+	    )*24 + hour /* now have hours */
+	   )*60 + min /* now have minutes */
+	  )*60 + sec; /* finally seconds */
+}
+
+unsigned long get_cmos_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+	int i;
+
+	if (isBeBox[0])
+	{
+#ifndef __powerpc__	
+	/* The Linux interpretation of the CMOS clock register contents:
+	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+	 * RTC registers show the second which has precisely just started.
+	 * Let's hope other operating systems interpret the RTC the same way.
+	 */
+	/* read RTC exactly on falling edge of update flag */
+	for (i = 0 ; i < 1000000 ; i++)	/* may take up to 1 second... */
+		if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
+			break;
+	for (i = 0 ; i < 1000000 ; i++)	/* must try at least 2.228 ms */
+		if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+			break;
+#endif			
+		do { /* Isn't this overkill ? UIP above should guarantee consistency */
+			sec = CMOS_MCRTC_READ(MCRTC_SECONDS);
+			min = CMOS_MCRTC_READ(MCRTC_MINUTES);
+			hour = CMOS_MCRTC_READ(MCRTC_HOURS);
+			day = CMOS_MCRTC_READ(MCRTC_DAY_OF_MONTH);
+			mon = CMOS_MCRTC_READ(MCRTC_MONTH);
+			year = CMOS_MCRTC_READ(MCRTC_YEAR);
+		} while (sec != CMOS_MCRTC_READ(MCRTC_SECONDS));
+	} else
+	{ /* Motorola PowerStack etc. */
+		do { /* Isn't this overkill ? UIP above should guarantee consistency */
+			sec = CMOS_READ(RTC_SECONDS);
+			min = CMOS_READ(RTC_MINUTES);
+			hour = CMOS_READ(RTC_HOURS);
+			day = CMOS_READ(RTC_DAY_OF_MONTH);
+			mon = CMOS_READ(RTC_MONTH);
+			year = CMOS_READ(RTC_YEAR);
+		} while (sec != CMOS_READ(RTC_SECONDS));
+		BCD_TO_BIN(sec);
+		BCD_TO_BIN(min);
+		BCD_TO_BIN(hour);
+		BCD_TO_BIN(day);
+		BCD_TO_BIN(mon);
+		BCD_TO_BIN(year);
+	}
+#if 0	
+printk("CMOS TOD - M/D/Y H:M:S = %d/%d/%d %d:%02d:%02d\n", mon, day, year, hour, min, sec);
+#endif
+	if ((year += 1900) < 1970)
+		year += 100;
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+void time_init(void)
+{
+	void (*irq_handler)(int, struct pt_regs *);
+	xtime.tv_sec = get_cmos_time();
+	xtime.tv_usec = 0;
+
+	/* If we have the CPU hardware time counters, use them */
+	irq_handler = timer_interrupt;
+	if (request_irq(TIMER_IRQ, irq_handler, 0, "timer", NULL) != 0)
+		panic("Could not allocate timer IRQ!");
+}
+
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c
--- pre2.0.7/linux/arch/ppc/kernel/traps.c	Fri Apr 12 15:51:47 1996
+++ linux/arch/ppc/kernel/traps.c	Mon May 27 12:00:58 1996
@@ -26,7 +26,7 @@
 #include <asm/system.h>
 #include <asm/io.h>
 
-#include <asm/ppc_machine.h>
+#include "ppc_machine.h"
 
 /*
  * Trap & Exception support
@@ -41,7 +41,7 @@
 _exception(int signr, struct pt_regs *regs)
 {
 	dump_regs(regs);
-	send_sig(signr, current, 1);
+	force_sig(signr, current);
 	if (!user_mode(regs))
 	{
 		printk("Failure in kernel at PC: %x, MSR: %x\n", regs->nip, regs->msr);
@@ -51,25 +51,27 @@
 
 MachineCheckException(struct pt_regs *regs)
 {
-	unsigned long *eagle_ip = (unsigned long *)0x80000CF8;
-	unsigned long *eagle_id = (unsigned long *)0x80000CFC;
 	printk("Machine check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
-#if 0	
-	*eagle_ip = 0xC0000080;  /* Memory error register */
-	printk("Error regs = %08X", *eagle_id);
-	*eagle_ip = 0xC4000080;  /* Memory error register */
-	printk("/%08X", *eagle_id);
-	*eagle_ip = 0xC8000080;  /* Memory error register */
-	printk("/%08X\n", *eagle_id);
-#endif
 	_exception(SIGSEGV, regs);	
 }
 
 ProgramCheckException(struct pt_regs *regs)
 {
 	printk("Program check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
-	while(1) ;
-	_exception(SIGILL, regs);
+	if (current->flags & PF_PTRACED)
+	{
+		_exception(SIGTRAP, regs);
+	} else
+	{
+		_exception(SIGILL, regs);
+	}
+}
+
+SingleStepException(struct pt_regs *regs)
+{
+	printk("Single step at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
+	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
+	_exception(SIGTRAP, regs);	
 }
 
 FloatingPointCheckException(struct pt_regs *regs)
@@ -80,6 +82,9 @@
 
 AlignmentException(struct pt_regs *regs)
 {
+	printk("Alignment error at PC: %x, SR: %x\n", regs->nip, regs->msr);
+	dump_regs(regs);
+	cnpause();
 	printk("Alignment error at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
 	_exception(SIGBUS, regs);	
 }
@@ -95,7 +100,9 @@
 {
 	int i;
 	printk("NIP: %08X, MSR: %08X, XER: %08X, LR: %08X, FRAME: %08X\n", regs->nip, regs->msr, regs->xer, regs->link, regs);
+#if 0	
 	printk("HASH = %08X/%08X, MISS = %08X/%08X, CMP = %08X/%08X\n", regs->hash1, regs->hash2, regs->imiss, regs->dmiss, regs->icmp, regs->dcmp);
+#endif	
 	printk("TASK = %x[%d] '%s'\n", current, current->pid, current->comm);
 	for (i = 0;  i < 32;  i++)
 	{
@@ -109,12 +116,21 @@
 			printk("\n");
 		}
 	}
-	dump_buf(regs->nip, 32);
+#if 0	
+	if (regs->nip >= 0x1000)
+		dump_buf(regs->nip-32, 64);
 	dump_buf((regs->nip&0x0FFFFFFF)|KERNELBASE, 32);
+#endif
 }
 
 trace_syscall(struct pt_regs *regs)
 {
-	printk("Task: %08X(%d), PC: %08X/%08X, Syscall: %3d, Result: %d\n", current, current->pid, regs->nip, regs->link, regs->gpr[0], regs->gpr[3]);
+	static int count;
+	printk("Task: %08X(%d), PC: %08X/%08X, Syscall: %3d, Result: %s%d\n", current, current->pid, regs->nip, regs->link, regs->gpr[0], regs->ccr&0x10000000?"Error=":"", regs->gpr[3]);
+	if (++count == 20)
+	{
+		count = 0;
+		cnpause();
+	}
 }
 
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/ld.script linux/arch/ppc/ld.script
--- pre2.0.7/linux/arch/ppc/ld.script	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/ld.script	Mon May 27 12:00:58 1996
@@ -1,5 +1,5 @@
 OUTPUT_ARCH(powerpc)
-/*SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib);*/ SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
 /* Do we need any of these for elf?
    __DYNAMIC = 0;    */
 SECTIONS
@@ -41,6 +41,7 @@
   .ctors     : { *(.ctors)   }
   .dtors     : { *(.dtors)   }
   /* Read-write section, merged into data segment: */
+  . = (. + 0x0FFF) & 0xFFFFF000;
   .data    :
   {
     *(.data)
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/lib/Makefile linux/arch/ppc/lib/Makefile
--- pre2.0.7/linux/arch/ppc/lib/Makefile	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/lib/Makefile	Mon May 27 12:00:58 1996
@@ -0,0 +1,11 @@
+#
+# Makefile for i386-specific library files..
+#
+
+L_TARGET = lib.o
+L_OBJS  = checksum.o cksum_support.o
+
+${L_TARGET}: $(L_OBJS)
+	$(LD) -r -o ${L_TARGET} $(L_OBJS)
+
+fastdep:
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/lib/checksum.c linux/arch/ppc/lib/checksum.c
--- pre2.0.7/linux/arch/ppc/lib/checksum.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/lib/checksum.c	Mon May 27 12:00:58 1996
@@ -0,0 +1,136 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		IP/TCP/UDP checksumming routines
+ *
+ * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
+ *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *		Tom May, <ftom@netcom.com>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ * Adapted for PowerPC by Gary Thomas <gdt@mc.com>
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+
+#include <net/checksum.h>
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
+{
+	unsigned long result = ~_csum_partial(buff, len, sum);
+#if 0	
+printk("Csum partial(%x, %d, %x) = %x\n", buff, len, sum, result);
+dump_buf(buff, len);
+#endif
+	return result;
+}
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit boundary
+ */
+
+unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum)
+{
+	/*
+	 * The whole idea is to do the copy and the checksum at
+	 * the same time, but we do it the easy way now.
+	 *
+	 * At least csum on the source, not destination, for cache
+	 * reasons..
+	 */
+	sum = csum_partial(src, len, sum);
+	memcpy(dst, src, len);
+	return sum;
+}
+
+extern unsigned short _ip_fast_csum(unsigned char *buf);
+
+unsigned short
+ip_fast_csum(unsigned char *buf, unsigned int len)
+{
+	unsigned short _val;
+	_val = _ip_fast_csum(buf);
+#if 0
+	printk("IP CKSUM(%x, %d) = %x\n", buf, len, _val);
+	dump_buf(buf, len*4);
+#endif	
+	return (_val);
+}
+
+extern unsigned short _ip_compute_csum(unsigned char *buf, int len);
+
+unsigned short
+ip_compute_csum(unsigned char *buf, int len)
+{
+	unsigned short _val;
+	_val = _ip_compute_csum(buf, len);
+#if 0
+	printk("Compute IP CKSUM(%x, %d) = %x\n", buf, len, _val);
+	dump_buf(buf, len);
+#endif	
+	return (_val);
+}
+
+unsigned short
+_udp_check(unsigned char *buf, int len, int saddr, int daddr, int hdr);
+
+unsigned short
+udp_check(unsigned char *buf, int len, int saddr, int daddr)
+{
+	unsigned short _val;
+	int hdr;
+	hdr = (len << 16) + IPPROTO_UDP;
+	_val = _udp_check(buf, len, saddr, daddr, hdr);
+#if 0
+	printk("UDP CSUM(%x,%d,%x,%x) = %x\n", buf, len, saddr, daddr, _val);
+	dump_buf(buf, len);
+#endif	
+	return (_val);
+}
+
+unsigned short
+_tcp_check(unsigned char *buf, int len, int saddr, int daddr, int hdr);
+
+unsigned short
+csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len, unsigned short proto, unsigned int sum)
+{
+	unsigned short _val;
+	_val = _csum_tcpudp_magic(saddr, daddr, sum, (len<<16)+proto);
+#if 0
+	printk("TCP Magic(%x, %x, %x, %x) = %x\n", saddr, daddr, (len<<16)+proto, sum, _val);
+#endif
+	return (_val);
+}
+
+/*
+ *	Fold a partial checksum without adding pseudo headers
+ */
+
+unsigned short csum_fold(unsigned int sum)
+{
+	sum = (sum & 0xffff) + (sum >> 16);
+	sum = (sum & 0xffff) + (sum >> 16);
+	return ~sum;
+}
+
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/lib/cksum_support.S linux/arch/ppc/lib/cksum_support.S
--- pre2.0.7/linux/arch/ppc/lib/cksum_support.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/lib/cksum_support.S	Mon May 27 12:00:58 1996
@@ -0,0 +1,125 @@
+/*
+ * This module contains the PowerPC interrupt fielders
+ * set of code at specific locations, based on function
+ */
+
+#include <linux/sys.h>
+#include "../kernel/ppc_asm.tmpl"
+
+_TEXT()
+
+/*
+ * Compute IP checksums
+ *   _ip_fast_csum(buf, len) -- Optimized for IP header
+ *   _ip_compute_csum(buf, len)
+ */
+
+_GLOBAL(_ip_fast_csum)
+	li	r0,0
+	addic	r0,r0,0		/* Clear initial carry */
+	lwz	r4,0(r3)
+	lwz	r5,4(r3)
+	adde	r0,r0,r4
+	lwz	r4,8(r3)
+	adde	r0,r0,r5
+	lwz	r5,12(r3)
+	adde	r0,r0,r4
+	lwz	r4,16(r3)
+	adde	r0,r0,r5
+	adde	r0,r0,r4
+	mr	r3,r0
+	andi.	r3,r3,0xFFFF
+	srwi	r0,r0,16
+	adde	r3,r3,r0
+	andis.	r0,r3,1
+	beq	10f
+	addi	r3,r3,1
+10:	not	r3,r3
+	andi.	r3,r3,0xFFFF
+	blr
+
+_GLOBAL(_ip_compute_csum)
+	li	r0,0
+	addic	r0,r0,0
+finish_ip_csum:	
+	subi	r3,r3,4
+	andi.	r5,r3,2		/* Align buffer to longword boundary */
+	beq	10f
+	lhz	r5,4(r3)
+	adde	r0,r0,r5
+	addi	r3,r3,2
+	subi	r4,r4,2
+10:	cmpi	0,r4,16		/* unrolled loop - 16 bytes at a time */
+	blt	20f
+	lwz	r5,4(r3)
+	lwz	r6,8(r3)
+	adde	r0,r0,r5
+	lwz	r5,12(r3)
+	adde	r0,r0,r6
+	lwzu	r6,16(r3)
+	adde	r0,r0,r5
+	adde	r0,r0,r6
+	subi	r4,r4,16
+	b	10b
+20:	cmpi	0,r4,4
+	blt	30f
+	lwzu	r5,4(r3)
+	adde	r0,r0,r5
+	subi	r4,r4,4
+	b	20b
+30:	cmpi	0,r4,2
+	blt	40f
+	lhz	r5,4(r3)
+	addi	r3,r3,2
+	adde	r0,r0,r5
+	subi	r4,r4,2
+40:	cmpi	0,r4,1
+	bne	50f
+	lbz	r5,4(r3)
+	slwi	r5,r5,8		/* Upper byte of word */
+	adde	r0,r0,r5
+50:	mr	r3,r0
+	andi.	r3,r3,0xFFFF
+	srwi	r0,r0,16
+	adde	r3,r3,r0
+	andis.	r0,r3,1
+	beq	60f
+	addi	r3,r3,1
+60:	not	r3,r3
+	andi.	r3,r3,0xFFFF
+	blr
+
+_GLOBAL(_udp_check)
+	addc	r0,r5,r6	/* Add in header fields */
+	adde	r0,r0,r7
+	b	finish_ip_csum	
+
+_GLOBAL(_tcp_check)
+	addc	r0,r5,r6	/* Add in header fields */
+	adde	r0,r0,r7
+	b	finish_ip_csum	
+
+_GLOBAL(_csum_partial)
+	li	r0,0
+	addc	r0,r5,r0
+	b	finish_ip_csum	
+
+/*
+ * Compute 16 bit sum:
+ *   _csum_tcpudp_magic(int saddr, int daddr, int sum, int proto)
+ */	
+_GLOBAL(_csum_tcpudp_magic)
+	addc	r0,r3,r4
+	adde	r0,r0,r5
+	adde	r0,r0,r6
+	mr	r3,r0
+	andi.	r3,r3,0xFFFF
+	srwi	r0,r0,16
+	adde	r3,r3,r0
+	andis.	r0,r3,1			/* Carry out of 16 bits? */
+	beq	10f
+	addi	r3,r3,1
+10:	not	r3,r3
+	andi.	r3,r3,0xFFFF
+	blr
+
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/mm/Makefile linux/arch/ppc/mm/Makefile
--- pre2.0.7/linux/arch/ppc/mm/Makefile	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/mm/Makefile	Mon May 27 12:00:59 1996
@@ -23,9 +23,8 @@
 
 dep:
 	$(CPP) -M *.c > .depend
-
+	
 fastdep:
-	$(CPP) -M *.c > .depend
 
 #
 # include a dependency file if one exists
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/mm/fault.c linux/arch/ppc/mm/fault.c
--- pre2.0.7/linux/arch/ppc/mm/fault.c	Fri Apr 12 15:51:48 1996
+++ linux/arch/ppc/mm/fault.c	Mon May 27 12:00:59 1996
@@ -1,4 +1,3 @@
-/* * Last edited: Nov 29 18:14 1995 (cort) */
 /*
  *  ARCH/ppc/mm/fault.c
  *
@@ -6,9 +5,6 @@
  *  Ported to PPC by Gary Thomas
  */
 
-/*#define NOISY_DATAFAULT*/
-/*#define NOISY_INSTRFAULT*/
-
 #include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
@@ -27,146 +23,105 @@
 extern void die_if_kernel(char *, struct pt_regs *, long);
 extern void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
 
-#if 0
 #define SHOW_FAULTS
-#endif
+#undef  SHOW_FAULTS
+#define PAUSE_AFTER_FAULT
+#undef  PAUSE_AFTER_FAULT
 
 void
 DataAccessException(struct pt_regs *regs)
 {
-  pgd_t *dir;
-  pmd_t *pmd;
-  pte_t *pte;
-  int tries, mode = 0;
-  if (user_mode(regs)) mode |= 0x04;
-  if (regs->dsisr & 0x02000000) mode |= 0x02;  /* Load/store */
-  if (regs->dsisr & 0x08000000) mode |= 0x01;  /* Protection violation */
-#ifdef NOISY_DATAFAULT
-  printk("Data fault on %x\n",regs->dar);
-#endif
-  if (mode & 0x01)
-  {
-#if 0
-    printk("Write Protect Fault - Loc: %x, DSISR: %x, PC: %x\n", regs->dar, regs->dsisr, regs->nip);
-#endif
-#ifdef NOISY_DATAFAULT
-    printk("Write Protect fault\n ");
+	pgd_t *dir;
+	pmd_t *pmd;
+	pte_t *pte;
+	int tries, mode = 0;
+	if (user_mode(regs)) mode |= 0x04;
+	if (regs->dsisr & 0x02000000) mode |= 0x02;  /* Load/store */
+	if (regs->dsisr & 0x08000000) mode |= 0x01;  /* Protection violation */
+#ifdef SHOW_FAULTS
+	printk("Data Access Fault - Loc: %x, DSISR: %x, PC: %x\n", regs->dar, regs->dsisr, regs->nip);
+#ifdef PAUSE_AFTER_FAULT
+cnpause();
+#endif			
 #endif
-    do_page_fault(regs, regs->dar, mode);
-#ifdef NOISY_DATAFAULT    
-    printk("Write Protect fault handled\n");
-#endif
-    return;
-  }
-/*   printk("trying\n"); */
-  for (tries = 0;  tries < 1;  tries++)
-  {
-    dir = pgd_offset(current->mm, regs->dar & PAGE_MASK);
-    if (dir)
-    {
-      pmd = pmd_offset(dir, regs->dar & PAGE_MASK);
-      if (pmd && pmd_present(*pmd))
-      {
-	pte = pte_offset(pmd, regs->dar & PAGE_MASK);
-	if (pte && pte_present(*pte))
+	if (mode & 0x01)
 	{
-#if 0
-	  printk("Page mapped - PTE: %x[%x]\n", pte, *(long *)pte);
+#ifdef SHOW_FAULTS
+printk("Write Protect Fault - Loc: %x, DSISR: %x, PC: %x\n", regs->dar, regs->dsisr, regs->nip);
 #endif
-	  MMU_hash_page(&current->tss, regs->dar & PAGE_MASK, pte);
-	  return;
+		do_page_fault(regs, regs->dar, mode);
+		return;
+	}
+	for (tries = 0;  tries < 1;  tries++)
+	{
+		dir = pgd_offset(current->mm, regs->dar & PAGE_MASK);
+		if (dir)
+		{
+			pmd = pmd_offset(dir, regs->dar & PAGE_MASK);
+			if (pmd && pmd_present(*pmd))
+			{
+				pte = pte_offset(pmd, regs->dar & PAGE_MASK);
+				if (pte && pte_present(*pte))
+				{
+#ifdef SHOW_FAULTS
+					printk("Page mapped - PTE: %x[%x], Context: %x\n", pte, *(long *)pte, current->mm->context);
+#endif					
+					MMU_hash_page(&current->tss, regs->dar & PAGE_MASK, pte);
+					return;
+				}
+			}
+		} else
+		{
+			printk("No PGD\n");
+		}
+		do_page_fault(regs, regs->dar, mode);
 	}
-      }
-    } else
-    {
-      printk("No PGD\n");
-    }
-#ifdef NOISY_DATAFAULT    
-    printk("fall through page fault addr=%x; ip=%x\n",
-	   regs->dar,regs->nip);
-    printk("beforefault: pgd[0] = %x[%x]\n",current->mm->pgd,*(current->mm->pgd));
-#endif
-    do_page_fault(regs, regs->dar, mode);
-#ifdef NOISY_DATAFAULT    
-    printk("handled: pgd[0] = %x[%x]\n",current->mm->pgd,*(current->mm->pgd));
-#endif
-  }
 }
 
 void
 InstructionAccessException(struct pt_regs *regs)
 {
-  pgd_t *dir;
-  pmd_t *pmd;
-  pte_t *pte;
-  int tries, mode = 0;
-  
-#if NOISY_INSTRFAULT
-  printk("Instr fault on %x\n",regs->dar);
+	pgd_t *dir;
+	pmd_t *pmd;
+	pte_t *pte;
+	int tries, mode = 0;
+	unsigned long addr = regs->nip;
+	if (user_mode(regs)) mode |= 0x04;
+#ifdef SHOW_FAULTS
+	printk("Instruction Access Fault - Loc: %x, DSISR: %x, PC: %x\n", regs->dar, regs->dsisr, regs->nip);
+#ifdef PAUSE_AFTER_FAULT
+cnpause();
 #endif
-  if (user_mode(regs)) mode |= 0x04;
-  if (regs->dsisr & 0x02000000) mode |= 0x02;  /* Load/store */
-  if (regs->dsisr & 0x08000000) mode |= 0x01;  /* Protection violation */
-  
-  if (mode & 0x01)
-  {
-    do_page_fault(regs, regs->dar, mode); 
-    return;
-  }
-  for (tries = 0;  tries < 1;  tries++)
-  {
-    /*     dir = pgd_offset(current->mm, regs->nip & PAGE_MASK); */
-    dir = pgd_offset(current->mm, regs->dar & PAGE_MASK);
-#ifdef NOISY_INSTRFAULT
-/*	printk("regs->dar=%x current=%x current->mm=%x current->mm->pgd=%x current->tss.pg_tables=%x\n",
-	       regs->dar,current,current->mm,current->mm->pgd,current->tss.pg_tables);*/
-#endif
-    if (dir)
-    {
-      pmd = pmd_offset(dir, regs->dar & PAGE_MASK); 
-      if (pmd && pmd_present(*pmd))
-      {
- 	pte = pte_offset(pmd, regs->dar & PAGE_MASK); 
-
-#ifdef NOISY_INSTRFAULT
-/*	printk("dir %x(%x) pmd %x(%x) pte %x\n",dir,*dir,pmd,*pmd,pte);*/
-#if 0
-	printk("pgd_offset mm=%x mm->pgd=%x dirshouldbe=%x\n",
-	       current->mm, current->mm->pgd,
-	       current->mm->pgd+((regs->dar&PAGE_MASK) >> PGDIR_SHIFT));
-	printk("dir is %x\n", dir);
-	
-	/* 	printk("got pte\n"); */
-	if (pte) {
-	  printk("pgd=%x; dir=%x->%x; pmd=%x->%x; pte=%x; \n",
-		 current->mm->pgd,dir,*dir,pmd,*pmd,pte);
-	  if (pte_present(*pte)) {
-	    printk("pte present\n");
-	  } else {
-	    printk("pte not present\n");
-	  }
-	} else {
-	  printk("pte false\n");
+#endif	
+	if (mode & 0x01)
+	{
+		do_page_fault(regs, addr, mode);
+		return;
 	}
-#endif
-#endif
-	if (pte && pte_present(*pte))
+	for (tries = 0;  tries < 1;  tries++)
 	{
-/* 	  MMU_hash_page(&current->tss, regs->nip & PAGE_MASK, pte); */
- 	  MMU_hash_page(&current->tss, regs->dar & PAGE_MASK, pte); 
-	  return;
-	}
-      }
-    } else
-    {
-#ifdef NOISY_INSTRFAULT      
-      panic("No PGD Instruction Access Fault - Loc: %x, DSISR: %x, PC: %x current->mm\n",
-	    regs->dar, regs->dsisr, regs->nip, current->mm);
-#endif
-    }
-/*     do_page_fault(regs, regs->nip, mode); */
-     do_page_fault(regs, regs->dar, mode);
-  }
+		dir = pgd_offset(current->mm, addr & PAGE_MASK);
+		if (dir)
+		{
+			pmd = pmd_offset(dir, addr & PAGE_MASK);
+			if (pmd && pmd_present(*pmd))
+			{
+				pte = pte_offset(pmd, addr & PAGE_MASK);
+				if (pte && pte_present(*pte))
+				{
+#ifdef SHOW_FAULTS
+					printk("Page mapped - PTE: %x[%x], Context: %x\n", pte, *(long *)pte, current->mm->context);
+#endif					
+					MMU_hash_page(&current->tss, addr & PAGE_MASK, pte);
+					return;
+				}
+			}
+		} else
+		{
+			printk("No PGD\n");
+		}
+		do_page_fault(regs, addr, mode);
+	}
 }
 
 /*
@@ -182,160 +137,148 @@
  */
 void do_page_fault(struct pt_regs *regs, unsigned long address, unsigned long error_code)
 {
-  struct vm_area_struct * vma;
-  unsigned long page;
+	struct vm_area_struct * vma;
+	unsigned long page;
 
-/*   printk("In do_page_fault()\n"); */
-#if 1
-  for (vma = current->mm->mmap ; ; vma = vma->vm_next)
-  {
-    if (!vma)
-    {
-      panic("!vma: ip = %x; current=%x[%d]; mm=%x; mmap=%x; address = %x error_code = %x\n",
-	    regs->nip, current,current->pid,current->mm,current->mm->mmap, address, error_code);
-      goto bad_area;
-    }
-    if (vma->vm_end > address)
-      break;
-  }
-#else
-  vma = find_vma(current, address);
-  if (!vma)
-  {
-  }
-    goto bad_area;
+	for (vma = current->mm->mmap ; ; vma = vma->vm_next)
+	{
+#ifdef SHOW_FAULTS
+printk("VMA(%x) - Start: %x, End: %x, Flags: %x\n", vma, vma->vm_start, vma->vm_end, vma->vm_flags);		
 #endif
-  if (vma->vm_start <= address){
-    goto good_area;
-  }
-  if (!(vma->vm_flags & VM_GROWSDOWN))
-  {
-    printk("stack: gpr[1]=%x ip = %x; current=%x[%d]; mm=%x; mmap=%x; address = %x error_code = %x\n",regs->gpr[1],regs->nip, current,current->pid,current->mm,current->mm->mmap, address, error_code);
-    panic("stack\n");
-    goto bad_area;
-  }
-  if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
-  {
-    printk("stack2: vma->vm_end-address %x rlim %x\n", vma->vm_end - address,
-	   current->rlim[RLIMIT_STACK].rlim_cur);
-    printk("stack2: vm_end %x address = %x\n", vma->vm_end,address);
-    printk("stack2: gpr[1]=%x ip = %x; current=%x[%d]; mm=%x; mmap=%x; address = %x error_code = %x\n",regs->gpr[1],regs->nip, current,current->pid,current->mm,current->mm->mmap, address, error_code);
-    panic("stack2\n");
-    goto bad_area;
-  }
-  vma->vm_offset -= vma->vm_start - (address & PAGE_MASK);
-  vma->vm_start = (address & PAGE_MASK);
-  
-  /*
-   * Ok, we have a good vm_area for this memory access, so
-   * we can handle it..
-   */
+		if (!vma)
+			goto bad_area;
+		if (vma->vm_end > address)
+			break;
+	}
+	if (vma->vm_start <= address)
+		goto good_area;
+	if (!(vma->vm_flags & VM_GROWSDOWN))
+		goto bad_area;
+	if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
+		goto bad_area;
+	vma->vm_offset -= vma->vm_start - (address & PAGE_MASK);
+	vma->vm_start = (address & PAGE_MASK);
+/*
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
 good_area:
-  /*
-   * was it a write?
-   */
-  if (error_code & 2) {
-    if (!(vma->vm_flags & VM_WRITE))
-    {
-      panic("do_page_fault()  write\n");
-      panic("do_page_fault() write! current: %x, address:%x, vm_flags: %x, mm: %x; vma(%x) %x to %x\n",
-	    current,address,vma->vm_flags,current->mm,vma,vma->vm_start,vma->vm_end);
-      goto bad_area;
-    }
-  } else {
-    /* read with protection fault? */
-    if (error_code & 1)
-    {
-      panic("do_page_fault()  error code thing\n");	    
-      goto bad_area;
-    }
-    if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
-    {
-#if 0
-      _printk("vma = %x\n", vma);
-      _printk("vma->vm_flags = %x\n", vma->vm_flags);      
-      _printk("VM_READ = %x VM_EXEC = %x\n",VM_READ,VM_EXEC);
-#endif
+	/*
+	 * was it a write?
+	 */
+	if (error_code & 2) {
+		if (!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+	} else {
+		/* read with protection fault? */
+		if (error_code & 1)
+			goto bad_area;
+		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+			goto bad_area;
+	}
+	handle_mm_fault(vma, address, error_code & 2);
+	flush_page(address);  /* Flush & Invalidate cache - note: address is OK now */
+	return;
+
+/*
+ * Something tried to access memory that isn't in our memory map..
+ * Fix it, but check if it's kernel or user first..
+ */
+bad_area:
+printk("Task: %x, PC: %x/%x, bad area! - Addr: %x\n", current, regs->nip, current->tss.last_pc, address);
+print_user_backtrace(current->tss.user_stack);
+print_kernel_backtrace();
 #if 0
-      printk("vma = %x VM_READ = %x VM_EXEC = %x\n",
-	     vma, VM_READ,VM_EXEC);
-      printk("vma->vm_start = %x vma->vm_end = %d\n",
-	     vma->vm_start, vma->vm_end);
-      printk("error_code = %x\n", error_code);      
-      printk("regs = %x\n", regs);
-      printk("vma->vm_flags = %x\n", vma->vm_flags);
+cnpause();
+if (!user_mode(regs))
+{
+   print_backtrace(regs->gpr[1]);
+}
 #endif
-/*      printk("do_page_fault()  multi thing\n"); */
-      goto bad_area; 
-    }
-  }
-/*   printk("premm: pgd[0] = %x[%x]\n",current->mm->pgd,*(current->mm->pgd)); */
-  handle_mm_fault(vma, address, error_code & 2); 
-/*   printk("handled fault for %x in %x to %x flags %x\n", */
-/* 	 address,vma->vm_start,vma->vm_end,vma->vm_flags); */
-  return;
-  
-  /*
-   * Something tried to access memory that isn't in our memory map..
-   * Fix it, but check if it's kernel or user first..
-   */
-bad_area:
-  if (user_mode(regs)) {
-    printk("Task: %x, PC: %x, bad area! - Addr: %x\n", current, regs->nip, address);
-    send_sig(SIGSEGV, current, 1);
-    return;
-  }
+dump_regs(regs);
+	if (user_mode(regs)) {
 #if 0
-  panic("KERNEL! Task: %x, PC: %x, bad area! - Addr: %x, PGDIR: %x\n",
-	 current, regs->nip, address, current->tss.pg_tables);
-#else
-  /*  panic("KERNEL mm! current: %x,  address:%x, vm_flags: %x, mm: %x; \nvma(%x) %x to %x swapper_pg_dir %x\n",
-	current,address,vma->vm_flags,current->mm,vma,vma->vm_start,vma->vm_end,
-	swapper_pg_dir);*/
-  printk("KERNEL mm! current: %x,  address:%x, vm_flags: %x, mm: %x; vma(%x) %x to %x\n",
-	current,address,vma->vm_flags,current->mm,vma,vma->vm_start,vma->vm_end);
-  panic("Kernel access of bad area\n");
-	 
+		current->tss.cp0_badvaddr = address;
+		current->tss.error_code = error_code;
+		current->tss.trap_no = 14;
 #endif
-  
-  while (1) ;
+		force_sig(SIGSEGV, current);
+		return;
+	}
+printk("KERNEL! Task: %x, PC: %x, bad area! - Addr: %x, PGDIR: %x\n", current, regs->nip, address, current->tss.pg_tables);
+dump_regs(regs);
+while (1) ;
+#if 0	
+	/*
+	 * Oops. The kernel tried to access some bad page. We'll have to
+	 * terminate things with extreme prejudice.
+	 */
+	if ((unsigned long) (address-TASK_SIZE) < PAGE_SIZE) {
+		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+		pg0[0] = pte_val(mk_pte(0, PAGE_SHARED));
+	} else
+		printk(KERN_ALERT "Unable to handle kernel paging request");
+	printk(" at virtual address %08lx\n",address);
+	page = current->tss.pg_dir;
+	printk(KERN_ALERT "current->tss.pg_dir = %08lx\n", page);
+	page = ((unsigned long *) page)[address >> PGDIR_SHIFT];
+	printk(KERN_ALERT "*pde = %08lx\n", page);
+	if (page & 1) {
+		page &= PAGE_MASK;
+		address &= 0x003ff000;
+		page = ((unsigned long *) page)[address >> PAGE_SHIFT];
+		printk(KERN_ALERT "*pte = %08lx\n", page);
+	}
+	die_if_kernel("Oops", regs, error_code);
+#endif	
+	do_exit(SIGKILL);
 }
 
 va_to_phys(unsigned long address)
 {
-  pgd_t *dir;
-  pmd_t *pmd;
-  pte_t *pte;
-  dir = pgd_offset(current->mm, address & PAGE_MASK);
-  if (dir)
-  {
-    pmd = pmd_offset(dir, address & PAGE_MASK);
-    if (pmd && pmd_present(*pmd))
-    {
-      pte = pte_offset(pmd, address & PAGE_MASK);
-      if (pte && pte_present(*pte))
-      {
-	return(pte_page(*pte) | (address & ~(PAGE_MASK-1)));
-      }
-    } else
-    {
-      return (0);
-    }
-  } else
-  {
-    return (0);
-  }
+	pgd_t *dir;
+	pmd_t *pmd;
+	pte_t *pte;
+	dir = pgd_offset(current->mm, address & PAGE_MASK);
+	if (dir)
+	{
+		pmd = pmd_offset(dir, address & PAGE_MASK);
+		if (pmd && pmd_present(*pmd))
+		{
+			pte = pte_offset(pmd, address & PAGE_MASK);
+			if (pte && pte_present(*pte))
+			{
+				return(pte_page(*pte) | (address & ~(PAGE_MASK-1)));
+			}
+		} else
+		{
+			return (0);
+		}
+	} else
+	{
+		return (0);
+	}
+	return (0);
 }
 
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+ * See if an address should be valid in the current context.
+ */
+valid_addr(unsigned long addr)
+{
+	struct vm_area_struct * vma;
+	for (vma = current->mm->mmap ; ; vma = vma->vm_next)
+	{
+		if (!vma)
+		{
+			return (0);
+		}
+		if (vma->vm_end > addr)
+			break;
+	}
+	if (vma->vm_start <= addr)
+	{
+		return (1);
+	}
+	return (0);
+}
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- pre2.0.7/linux/arch/ppc/mm/init.c	Fri Apr 12 15:51:48 1996
+++ linux/arch/ppc/mm/init.c	Mon May 27 12:00:59 1996
@@ -5,7 +5,6 @@
  *  Ported to PPC by Gary Thomas
  */
 
-
 #include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
@@ -17,37 +16,18 @@
 #include <linux/ptrace.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
+#include <linux/swap.h>
 
-#include <asm/pgtable.h>
-
-
-/* made this a static array since alpha and intel aren't.
-   thomas made it a dynamic array and had to add lots of stuff to other parts
-   of linux to make sure the pages were contiguous and such.  the static array
-   seems much easier
-   making it 8k for now.  will change later.
-      -- Cort
-   */
-pgd_t swapper_pg_dir[1024];
-/*pgd_t *swapper_pg_dir;*/
+#define SHOW_FAULTS
+#undef  SHOW_FAULTS
 
-pte *MMU_get_page(void);
+#define SHOW_INVALIDATES
+#undef  SHOW_INVALIDATES
 
+#include <asm/pgtable.h>
 
-#if 0
-#include <asm/system.h>
-#include <asm/segment.h>
-#include <asm/mipsconfig.h>
-
-extern unsigned long pg0[1024];		/* page table for 0-4MB for everybody */
-#endif
+extern pgd_t swapper_pg_dir[1024*8];
 
-#ifdef CONFIG_DESKSTATION_TYNE
-extern void deskstation_tyne_dma_init(void);
-#endif
-#ifdef CONFIG_SOUND
-extern void sound_mem_init(void);
-#endif
 extern void die_if_kernel(char *,struct pt_regs *,long);
 extern void show_net_buffers(void);
 
@@ -113,13 +93,9 @@
 
 unsigned long __zero_page(void)
 {
-#if 0
-	panic("__zero_page");
-#else	
 	extern char empty_zero_page[PAGE_SIZE];
 	bzero(empty_zero_page, PAGE_SIZE);
 	return (unsigned long) empty_zero_page;
-#endif	
 }
 
 void show_mem(void)
@@ -133,7 +109,7 @@
 	i = high_memory >> PAGE_SHIFT;
 	while (i-- > 0) {
 		total++;
-                if (mem_map[i].reserved)
+		if (PageReserved(mem_map+i))
 			reserved++;
 		else if (!mem_map[i].count)
 			free++;
@@ -161,7 +137,6 @@
  */
 unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
 {
-
 #if 0	
 	pgd_t * pg_dir;
 	pte_t * pg_table;
@@ -194,14 +169,13 @@
 	cacheflush();
 #endif
 	invalidate();
-#endif
+#endif	
 	return free_area_init(start_mem, end_mem);
 }
 
 void mem_init(unsigned long start_mem, unsigned long end_mem)
 {
 	int codepages = 0;
-	int reservedpages = 0;
 	int datapages = 0;
 	unsigned long tmp;
 	extern int etext;
@@ -213,30 +187,14 @@
 	start_mem = PAGE_ALIGN(start_mem);
 
 #if 0
-printk("Mem init - Start: %x, End: %x\n", start_mem, high_memory);
-#endif
-	while (start_mem < high_memory) {
-		mem_map[MAP_NR(start_mem)].reserved = 0;
-		start_mem += PAGE_SIZE;
-	}
-#ifdef CONFIG_DESKSTATION_TYNE
-	deskstation_tyne_dma_init();
-#endif
-#ifdef CONFIG_SOUND
-	sound_mem_init();
+_printk("Mem init - Start: %x, End: %x\n", start_mem, high_memory);
 #endif
 	for (tmp = KERNELBASE ; tmp < high_memory ; tmp += PAGE_SIZE)
 	{
-		if (mem_map[MAP_NR(tmp)].reserved)
+		if (tmp < start_mem)
 		{
-			/*
-			 * We don't have any reserved pages on the
-			 * MIPS systems supported until now
-			 */
-			if (0)
-			{
-				reservedpages++;
-			} else if (tmp < (unsigned long) &etext)
+			set_bit(PG_reserved, &mem_map[MAP_NR(tmp)].flags);
+			if (tmp < (unsigned long) &etext)
 			{
 				codepages++;
 			} else
@@ -245,15 +203,15 @@
 			}
 			continue;
 		}
+		clear_bit(PG_reserved, &mem_map[MAP_NR(tmp)].flags);
 		mem_map[MAP_NR(tmp)].count = 1;
 		free_page(tmp);
 	}
 	tmp = nr_free_pages << PAGE_SHIFT;
-	printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
+	printk("Memory: %luk/%luk available (%dk kernel code, %dk data)\n",
 		tmp >> 10,
 		((int)high_memory - (int)KERNELBASE) >> 10,
 		codepages << (PAGE_SHIFT-10),
-		reservedpages << (PAGE_SHIFT-10),
 		datapages << (PAGE_SHIFT-10));
 	invalidate();
 	return;
@@ -261,26 +219,24 @@
 
 void si_meminfo(struct sysinfo *val)
 {
-#if 0	
 	int i;
 
-	i = high_memory >> PAGE_SHIFT;
+	i = ((int)high_memory & 0x00FFFFFF) >> PAGE_SHIFT;
 	val->totalram = 0;
 	val->sharedram = 0;
 	val->freeram = nr_free_pages << PAGE_SHIFT;
 	val->bufferram = buffermem;
 	while (i-- > 0)  {
-		if (mem_map[i] & MAP_PAGE_RESERVED)
+		if (PageReserved(mem_map+i))
 			continue;
 		val->totalram++;
-		if (!mem_map[i])
+		if (!mem_map[i].count)
 			continue;
-		val->sharedram += mem_map[i]-1;
+		val->sharedram += mem_map[i].count-1;
 	}
 	val->totalram <<= PAGE_SHIFT;
 	val->sharedram <<= PAGE_SHIFT;
 	return;
-#endif	
 }
 
 /* Kernel MMU setup & lowest level hardware support */
@@ -326,8 +282,6 @@
    };
 BAT BAT2 =
    {
-/* map kernel with bats 0 = yes */
-#if 1
    	{
    		0x00000000>>17, 	/* bepi */
    		BL_256M,		/* bl */
@@ -342,22 +296,6 @@
    		0,			/* g */
    		BPP_RW			/* pp */
    	}
-#else
-   	{
-   		0x90000000>>17, 	/* bepi */
-   		BL_256M,		/* bl */
-   		1,			/* vs */
-   		1,			/* vp */
-   	},
-   	{
-   		0x00000000>>17,		/* brpn */
-   		1,			/* w */
-   		0,			/* i (cache enabled) */
-   		0,			/* m */
-   		0,			/* g */
-   		BPP_RW			/* pp */
-   	}
-#endif
    };
 BAT BAT3 =
    {
@@ -380,13 +318,13 @@
    { /* 0x9XXXXXXX -> 0x0XXXXXXX */
    	{
    		0x90000000>>17, 	/* bepi */
-   		BL_256M,		/* bl */
+   		BL_16M,			/* bl */
    		1,			/* vs */
    		1,			/* vp */
    	},
    	{
    		0x00000000>>17,		/* brpn */
-   		1,			/* w */
+   		0,			/* w */
    		0,			/* i (cache enabled) */
    		0,			/* m */
    		0,			/* g */
@@ -397,13 +335,17 @@
 unsigned long _SDR1;		/* Hardware SDR1 image */
 PTE *Hash;
 int Hash_size, Hash_mask;
+unsigned long *end_of_DRAM;
 int cache_is_copyback = 1;
 int kernel_pages_are_copyback = 1;
+/* Note: these need to be in 'data' so they live over the boot */
+unsigned char *BeBox_IO_page = 0;
+unsigned long isBeBox[2] = {0, 0};
 
-#define NUM_MAPPINGS 8
+#define NUM_MAPPINGS 128
 struct
    {
-   	int va, pa, task;
+   	int va, pa, pg, task;
    } last_mappings[NUM_MAPPINGS];
 int next_mapping = 0;
 
@@ -460,13 +402,13 @@
 
 extern char _start[], _end[];
  
-void MMU_init(void)
+MMU_init()
 {
 	int i, p;
 	SEGREG *segs;
-/*	_printk("MMU init - started\n");*/
+	_printk("MMU init - started\n");
 	find_end_of_memory();
-/*	_printk("  Start at 0x%08X, End at 0x%08X, Hash at 0x%08X\n", _start, _end, Hash);*/
+	_printk("  Start at 0x%08X, End at 0x%08X, Hash at 0x%08X\n", _start, _end, Hash);
 	_SDR1 = ((unsigned long)Hash & 0x00FFFFFF) | Hash_mask;
 	p = (int)mmu_pages;
 	p = (p + (MMU_PAGE_SIZE-1)) & ~(MMU_PAGE_SIZE-1);
@@ -477,11 +419,12 @@
 		p += MMU_PAGE_SIZE;
 	}
 	/* Force initial page tables */
-	/*swapper_pg_dir = (pgd_t *)MMU_get_page();*/
+#if 0	
+	swapper_pg_dir = (pgd_t *)MMU_get_page();
+#endif	
 	init_task.tss.pg_tables = (unsigned long *)swapper_pg_dir;
-
 	/* Segment registers */
-	segs = (SEGREG *)init_task.tss.segs;
+	segs = init_task.tss.segs;
 	for (i = 0;  i < 16;  i++)
 	{
 		segs[i].ks = 0;
@@ -489,12 +432,21 @@
 		segs[i].vsid = i;
 	}
 	/* Map kernel TEXT+DATA+BSS */
-#if 0	
-	for (i = (int)_start;  i <= (int)_end;  i += MMU_PAGE_SIZE)
-#else
+	end_of_DRAM = (unsigned long *)Hash;
+	/* Hard map in any special local resources */
+	if (isBeBox[0])
+	{
+		/* Map in one page for the BeBox motherboard I/O */
+		end_of_DRAM = (unsigned long *)((unsigned long)end_of_DRAM - MMU_PAGE_SIZE);
+#if 0		
+		BeBox_IO_page = (unsigned char *)0x7FFFF000;
+#endif
+		BeBox_IO_page = (unsigned char *)end_of_DRAM;
+		MMU_map_page(&init_task.tss, BeBox_IO_page, 0x7FFFF000, PAGE_KERNEL);
+		MMU_disable_cache_for_page(&init_task.tss, BeBox_IO_page);
+	}
 	/* Other parts of the kernel expect ALL RAM to be mapped */	
-	for (i = (int)_start;  i <= (int)Hash;  i += MMU_PAGE_SIZE)
-#endif	
+	for (i = (int)_start;  i < (int)end_of_DRAM;  i += MMU_PAGE_SIZE)
 	{
 		MMU_map_page(&init_task.tss, i, i & 0x00FFFFFF, PAGE_KERNEL);
 	}
@@ -503,26 +455,32 @@
 	{
 		MMU_map_page(&init_task.tss, i, i & 0x00FFFFFF, PAGE_KERNEL);
 	}
-/*	_printk("MMU init - done!\n");*/
+#if 0 /* I'm not sure this is necessary */
+	/* Clear all DRAM not explicitly used by kernel */
+	bzero(_end, (unsigned long)end_of_DRAM-(unsigned long)_end);
+#endif
+	_printk("MMU init - done!\n");
 }
 
 pte *
-MMU_get_page(void)
+MMU_get_page()
 {
 	pte *pg;
 	if ((pg = (pte *)MMU_get_item(&_free_pages)))
 	{
 		bzero((char *)pg, MMU_PAGE_SIZE);
 	}
-/*	_printk("MMU Allocate Page at %08X\n", pg);*/
+	_printk("MMU Allocate Page at %08X\n", pg);
 	return(pg);
 }
 
 MMU_map_page(struct thread_struct *tss, unsigned long va, unsigned long pa, int flags)
 {
 	pte *pd, *pg;
+#if 0
 if (va < (unsigned long)0x90000000)	
-  _printk("Thread: %x, Map VA: %08x -> PA: %08X, Flags: %x\n", tss, va, pa, flags);
+  printk("Thread: %x, Map VA: %08x -> PA: %08X, Flags: %x\n", tss, va, pa, flags);
+#endif
 	if ((pte **)tss->pg_tables == (pte **)NULL)
 	{ /* Allocate upper level page map */
 		(pte **)tss->pg_tables = (pte **)MMU_get_page();
@@ -533,6 +491,7 @@
 	}
 	/* Use upper 10 bits of VA to index the first level map */
 	pd = ((pte **)tss->pg_tables)[(va>>PD_SHIFT)&PD_MASK];
+	pd = (pte *)((int)pd & 0xFFFFF000);
 	if (pd == (pte *)NULL)
 	{ /* Need to allocate second-level table */
 		pd = (pte *)MMU_get_page();
@@ -559,15 +518,15 @@
 	PTE *_pte, *empty, *slot;
 	PTE *slot0, *slot1;
 	extern char _etext;
-
-
-/*	printk("hashing tss = %x va = %x pg = %x\n", tss, va, pg);*/
 /* TEMP */
+if (va < KERNELBASE)		
+{
 	last_mappings[next_mapping].va = va;
 	last_mappings[next_mapping].pa = pg?*(int *)pg:0;
-	last_mappings[next_mapping].task = current;
+	last_mappings[next_mapping].pg = pg;
+	last_mappings[next_mapping].task = current->pid;
 	if (++next_mapping == NUM_MAPPINGS) next_mapping = 0;
-
+}
 /* TEMP */	
 	page_index = ((int)va & 0x0FFFF000) >> 12;
 	segment = (unsigned int)va >> 28;
@@ -689,6 +648,7 @@
 			} else
 			{ /* Read only page */
 				perms = PP_RWRX;
+				perms = PP_RXRX;
 			}
 		} else
 		{ /* Kernel pages */
@@ -697,7 +657,7 @@
 		}
 #ifdef SHOW_FAULTS
 if (va < KERNELBASE)		
-_printk("VA: %08X, PA: %08X, Flags: %x, Perms: %d\n", va, pg->page_num<<12, pg->flags, perms);
+printk("VA: %08X, PA: %08X, Flags: %x, Perms: %d, Vsid: %x\n", va, pg->page_num<<12, pg->flags, perms, vsid);
 #endif
 		slot->pp = perms;
 		return (0);
@@ -708,56 +668,315 @@
 		if (slot->c) flags |= _PAGE_DIRTY;
 		slot->v = 0;
 #ifdef SHOW_FAULTS
-_printk("Pull VA: %08X, Flags: %x\n", va, flags);
+printk("Pull VA: %08X, Flags: %x\n", va, flags);
 #endif
 		return (flags);
 	}
 }
 
 /*
+ * Disable cache for a particular page
+ */
+MMU_disable_cache_for_page(struct thread_struct *tss, unsigned long va)
+{
+	int hash, page_index, segment, i, h, _h, api, vsid, perms;
+	PTE *_pte, *empty, *slot;
+	PTE *slot0, *slot1;
+	extern char _etext;
+	page_index = ((int)va & 0x0FFFF000) >> 12;
+	segment = (unsigned int)va >> 28;
+	api = page_index >> 10;
+	vsid = ((SEGREG *)tss->segs)[segment].vsid;
+	empty = slot = (PTE *)NULL;
+	for (_h = 0;  _h < 2;  _h++)
+	{
+		hash = page_index ^ vsid;		
+		if (_h)
+		{
+			hash = ~hash;  /* Secondary hash uses ones-complement */
+		}
+		hash &= 0x3FF | (Hash_mask << 10);
+		hash *= 8;  /* Eight entries / hash bucket */
+		_pte = &Hash[hash];
+		/* Save slot addresses in case we have to purge */
+		if (_h)
+		{
+			slot1 = _pte;
+		} else
+		{
+			slot0 = _pte;
+		}
+		for (i = 0;  i < 8;  i++, _pte++)
+		{
+			if (_pte->v && _pte->vsid == vsid && _pte->h == _h && _pte->api == api)
+			{ /* Found it! */
+				h = _h;
+				slot = _pte;
+				goto found_it;
+			}
+			if ((empty == (PTE *)NULL) && !_pte->v)
+			{
+				h = _h;
+				empty = _pte;
+			}
+		}
+	}
+found_it:	
+	_tlbie(va); /* Clear TLB */
+	slot->i = 1;
+	slot->m = 0;
+}
+
+/*
+ * Invalidate a hardware [hash] page table entry
+ * Note: this should never be called [currently] for kernel addresses.
+ */
+MMU_invalidate_page(struct mm_struct *mm, unsigned long va, pte *pg)
+{
+	int hash, page_index, segment, i, h, _h, api, vsid, perms;
+	PTE *_pte, *slot;
+	int flags = 0;
+	page_index = ((int)va & 0x0FFFF000) >> 12;
+	segment = (unsigned int)va >> 28;
+	api = page_index >> 10;
+	vsid = mm->context | segment;
+	slot = (PTE *)NULL;
+	for (_h = 0;  _h < 2;  _h++)
+	{
+		hash = page_index ^ vsid;		
+		if (_h)
+		{
+			hash = ~hash;  /* Secondary hash uses ones-complement */
+		}
+		hash &= 0x3FF | (Hash_mask << 10);
+		hash *= 8;  /* Eight entries / hash bucket */
+		_pte = &Hash[hash];
+		for (i = 0;  i < 8;  i++, _pte++)
+		{
+			if (_pte->v && _pte->vsid == vsid && _pte->h == _h && _pte->api == api)
+			{ /* Found it! */
+				_tlbie(va); /* Clear TLB */
+				if (_pte->r) flags |= _PAGE_ACCESSED;
+				if (_pte->c) flags |= _PAGE_DIRTY;
+				_pte->v = 0;
+#ifdef SHOW_FAULTS
+printk("Pull VA: %08X, Flags: %x\n", va, flags);
+#endif
+				return (flags);
+			}
+		}
+	}
+	return (flags);
+}
+
+/*
  * Invalidate the MMU [hardware] tables (for current task?)
  */
 void
 invalidate(void)
 {
-  int i, j, flags;
-  unsigned long address;
-  pgd_t *pgd;
-  pte_t *_pte;
-#if 0
-  _tlbia();  /* Flush TLB entries */
+	int i, j, flags;
+	unsigned long address;
+	pgd_t *pgd;
+	pte_t *_pte;
+	static long _invalidates;
+#ifdef SHOW_INVALIDATES
+printk("invalidate()\n");
+#endif
+	_invalidates++;
+#if 0 /* Unnecessary */
+	_tlbia();  /* Flush TLB entries */
+#endif
+	pgd = pgd_offset(current->mm, 0);
+	if (!pgd) return;  /* No map? */
+	address = 0;
+	for (i = 0 ; (i < PTRS_PER_PGD) && (address < KERNELBASE); i++)
+	{
+		if (*(long *)pgd)
+		{
+			/* I know there are only two levels, but the macros don't */
+			_pte = pte_offset(pmd_offset(pgd,0),0);
+			if (_pte)
+			{
+				for (j = 0;  j < PTRS_PER_PTE;  j++)
+				{
+					if (pte_present(*_pte))
+					{
+						flags = MMU_hash_page(&current->tss, address, 0);
+						((pte *)_pte)->flags |= flags;
+					}
+					_pte++;
+					address += PAGE_SIZE;
+				}
+			} else
+			{
+				address += PAGE_SIZE*PTRS_PER_PTE;
+			}
+		} else
+		{
+			address += PAGE_SIZE*PTRS_PER_PTE;
+		}
+		pgd++;
+	}
+} 
+
+/*
+ * Invalidate the MMU [hardware] tables (for current task?)
+ */
+void
+flush_cache_mm(struct mm_struct *mm)
+{
+	int i, j, flags;
+	unsigned long address;
+	pgd_t *pgd;
+	pte_t *_pte;
+	static long _invalidates;
+#ifdef SHOW_INVALIDATES
+printk("invalidate_mm(%x)\n", mm);
+#endif
+if (!mm) return;	
+	_invalidates++;
+#if 0 /* Unnecessary */
+	_tlbia();  /* Flush TLB entries */
+#endif
+	pgd = pgd_offset(mm, 0);
+	if (!pgd) return;  /* No map? */
+	address = 0;
+	for (i = 0 ; (i < PTRS_PER_PGD) && (address < KERNELBASE); i++)
+	{
+		if (*(long *)pgd)
+		{
+			/* I know there are only two levels, but the macros don't */
+			_pte = pte_offset(pmd_offset(pgd,0),0);
+			if (_pte)
+			{
+				for (j = 0;  j < PTRS_PER_PTE;  j++)
+				{
+					if (pte_present(*_pte))
+					{
+						flags = MMU_invalidate_page(mm, address, 0);
+						((pte *)_pte)->flags |= flags;
+					}
+					_pte++;
+					address += PAGE_SIZE;
+				}
+			} else
+			{
+				address += PAGE_SIZE*PTRS_PER_PTE;
+			}
+		} else
+		{
+			address += PAGE_SIZE*PTRS_PER_PTE;
+		}
+		pgd++;
+	}
+} 
+
+/*
+ * Invalidate the MMU [hardware] tables (for current task?)
+ */
+void
+flush_cache_page(struct vm_area_struct *vma, long va)
+{
+	int i, j, flags;
+	unsigned long address;
+	pgd_t *pgd;
+	pte_t *_pte;
+	static long _invalidates;
+	struct mm_struct *mm = vma->vm_mm;
+#ifdef SHOW_INVALIDATES
+printk("invalidate_page(%x[%x], %x)\n", vma, mm, va);
+#endif
+if (!mm) return;  /* In case VMA lookup fails */	
+	_invalidates++;
+#if 0 /* Unnecessary */
+	_tlbia();  /* Flush TLB entries */
+#endif
+/* Note: this could be MUCH better */
+	pgd = pgd_offset(mm, 0);
+	if (!pgd) return;  /* No map? */
+	address = 0;
+	for (i = 0 ; (i < PTRS_PER_PGD) && (address < KERNELBASE); i++)
+	{
+		if (*(long *)pgd)
+		{
+			/* I know there are only two levels, but the macros don't */
+			_pte = pte_offset(pmd_offset(pgd,0),0);
+			if (_pte)
+			{
+				for (j = 0;  j < PTRS_PER_PTE;  j++)
+				{
+					if ((va == address) && pte_present(*_pte))
+					{
+						flags = MMU_invalidate_page(mm, address, 0);
+						((pte *)_pte)->flags |= flags;
+					}
+					_pte++;
+					address += PAGE_SIZE;
+				}
+			} else
+			{
+				address += PAGE_SIZE*PTRS_PER_PTE;
+			}
+		} else
+		{
+			address += PAGE_SIZE*PTRS_PER_PTE;
+		}
+		pgd++;
+	}
+} 
+
+/*
+ * Invalidate the MMU [hardware] tables (for current task?)
+ */
+void
+flush_cache_range(struct mm_struct *mm, unsigned long va_start, unsigned long va_end)
+{
+	int i, j, flags;
+	unsigned long address;
+	pgd_t *pgd;
+	pte_t *_pte;
+	static long _invalidates;
+#ifdef SHOW_INVALIDATES
+printk("invalidate_range(%x, %x, %x)\n", mm, va_start, va_end);
+#endif
+if (!mm) return;	
+	_invalidates++;
+#if 0 /* Unnecessary */
+	_tlbia();  /* Flush TLB entries */
 #endif
-  pgd = pgd_offset(current->mm, 0);
-  if (!pgd) return;  /* No map? */
-  address = 0;
-  for (i = 0 ; (i < PTRS_PER_PGD) && (address < KERNELBASE); i++)
-  {
-    if (*(long *)pgd)
-    {
-      /* I know there are only two levels, but the macros don't */
-      _pte = pte_offset(pmd_offset(pgd,0),0);
-      if (_pte)
-      {
-	for (j = 0;  j < PTRS_PER_PTE;  j++)
-	{
-	  if (pte_present(*_pte))
-	  {
-	    flags = MMU_hash_page(&current->tss, address, 0);
-	    ((pte *)_pte)->flags |= flags;
-	  }
-	  _pte++;
-	  address += PAGE_SIZE;
-	}
-      } else
-      {
-	address += PAGE_SIZE*PTRS_PER_PTE;
-      }
-    } else
-    {
-      address += PAGE_SIZE*PTRS_PER_PTE;
-    }
-    pgd++;
-  }
+/* Note: this could be MUCH better */
+	pgd = pgd_offset(mm, 0);
+	if (!pgd) return;  /* No map? */
+	address = 0;
+	for (i = 0 ; (i < PTRS_PER_PGD) && (address < KERNELBASE); i++)
+	{
+		if (*(long *)pgd)
+		{
+			/* I know there are only two levels, but the macros don't */
+			_pte = pte_offset(pmd_offset(pgd,0),0);
+			if (_pte)
+			{
+				for (j = 0;  j < PTRS_PER_PTE;  j++)
+				{
+					if ((va_start <= address) && (va_end > address) && pte_present(*_pte))
+					{
+						flags = MMU_invalidate_page(mm, address, 0);
+						((pte *)_pte)->flags |= flags;
+					}
+					_pte++;
+					address += PAGE_SIZE;
+				}
+			} else
+			{
+				address += PAGE_SIZE*PTRS_PER_PTE;
+			}
+		} else
+		{
+			address += PAGE_SIZE*PTRS_PER_PTE;
+		}
+		pgd++;
+	}
 } 
 
 void
@@ -766,4 +985,57 @@
 	cache_is_copyback = ints[0];
 }
 
+_verify_addr(long va)
+{
+	int hash, page_index, segment, i, h, _h, api, vsid, perms;
+	struct thread_struct *tss = &current->tss;
+	PTE *_pte, *empty, *slot;
+	PTE *slot0, *slot1;
+	page_index = ((int)va & 0x0FFFF000) >> 12;
+	segment = (unsigned int)va >> 28;
+	api = page_index >> 10;
+	vsid = ((SEGREG *)tss->segs)[segment].vsid;
+	empty = slot = (PTE *)NULL;
+	printk("Segment = %x/%x\n", *(long *)&tss->segs[segment], _get_SRx(segment));
+	for (_h = 0;  _h < 2;  _h++)
+	{
+		hash = page_index ^ vsid;		
+		if (_h)
+		{
+			hash = ~hash;  /* Secondary hash uses ones-complement */
+		}
+		hash &= 0x3FF | (Hash_mask << 10);
+		hash *= 8;  /* Eight entries / hash bucket */
+		_pte = &Hash[hash];
+		dump_buf(_pte, 64);
+		for (i = 0;  i < 8;  i++, _pte++)
+		{
+			if (_pte->v && _pte->vsid == vsid && _pte->h == _h && _pte->api == api)
+			{ /* Found it! */
+				h = _h;
+				slot = _pte;
+				printk("Found at %x\n", slot);
+				goto found_it;
+			}
+			if ((empty == (PTE *)NULL) && !_pte->v)
+			{
+				h = _h;
+				empty = _pte;
+			}
+		}
+	}
+found_it:	
+	cnpause();
+}
+
+flush_cache_all()
+{
+	printk("flush_cache_all()\n");
+	invalidate();
+}
 
+flush_tlb_all() {}
+flush_tlb_mm() {}
+flush_tlb_page() {}
+flush_tlb_range() {}
+flush_page_to_ram() {}
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/mm/mmu.h linux/arch/ppc/mm/mmu.h
--- pre2.0.7/linux/arch/ppc/mm/mmu.h	Sat Dec 30 15:48:22 1995
+++ linux/arch/ppc/mm/mmu.h	Mon May 27 12:00:59 1996
@@ -29,6 +29,7 @@
 #define PP_RWXX	0	/* Supervisor read/write, User none */
 #define PP_RWRX 1	/* Supervisor read/write, User read */
 #define PP_RWRW 2	/* Supervisor read/write, User read/write */
+#define PP_RXRX 3	/* Supervisor read,       User read */
 
 /* Segment Register */
 
diff -u --recursive --new-file pre2.0.7/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- pre2.0.7/linux/drivers/block/floppy.c	Tue May 21 19:52:33 1996
+++ linux/drivers/block/floppy.c	Mon May 27 13:16:02 1996
@@ -213,13 +213,6 @@
 static unsigned int fake_change = 0;
 static int initialising=1;
 
-#ifdef __sparc__
-/* We hold the FIFO configuration here.  We want to have Polling and
- * Implied Seek enabled on Sun controllers.
- */
-unsigned char fdc_cfg = 0;
-#endif
-
 static inline int TYPE(kdev_t x) {
 	return  (MINOR(x)>>2) & 0x1f;
 }
@@ -1184,15 +1177,10 @@
 {
 	/* Turn on FIFO */
 	output_byte(FD_CONFIGURE);
-#ifdef __sparc__ 
-	output_byte(0x64);	/* Motor off timeout */
-	output_byte(fdc_cfg | 0x0A);
-#else
 	if(need_more_output() != MORE_OUTPUT)
 		return 0;
 	output_byte(0);
 	output_byte(0x10 | (no_fifo & 0x20) | (fifo_depth & 0xf));
-#endif
 	output_byte(0);	/* pre-compensation from track 
 			   0 upwards */
 	return 1;
@@ -1234,12 +1222,7 @@
 		/*DPRINT("FIFO enabled\n");*/
 	}
 
-#ifdef __sparc__
-	/* If doing implied seeks, no specify necessary */
-	if(fdc_cfg&0x40)
-		return;
-#endif
-
+#ifndef __sparc__
 	switch (raw_cmd->rate & 0x03) {
 		case 3:
 			dtr = 1000;
@@ -1294,6 +1277,7 @@
 		output_byte(FDCS->spec1 = spec1);
 		output_byte(FDCS->spec2 = spec2);
 	}
+#endif
 } /* fdc_specify */
 
 /* Set the FDC's data transfer rate on behalf of the specified drive.
@@ -1572,15 +1556,6 @@
 		}
 	}
 
-#ifdef __sparc__
-	if (fdc_cfg&0x40) {
-		/* Implied seeks being done... */
-		DRS->track = raw_cmd->track;
-		setup_rw_floppy();
-		return;
-	}
-#endif
-
 	SET_INTR(seek_interrupt);
 	output_byte(FD_SEEK);
 	output_byte(UNIT(current_drive));
@@ -3982,9 +3957,6 @@
 	blksize_size[MAJOR_NR] = floppy_blocksizes;
 	blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
 	reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT);
-#ifdef __sparc__
-	fdc_cfg = (0x40 | 0x10); /* ImplSeek+Polling+FIFO */
-#endif
 	config_types();
 
 	for (i = 0; i < N_FDC; i++) {
diff -u --recursive --new-file pre2.0.7/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- pre2.0.7/linux/drivers/block/ide.c	Fri May 17 15:32:13 1996
+++ linux/drivers/block/ide.c	Mon May 27 14:01:04 1996
@@ -3207,6 +3207,7 @@
 		 * and then add 1.
 		 */
 		ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371_0, &ide_init_triton, 1);
+		ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, &ide_init_triton, 0);
 #endif /* CONFIG_BLK_DEV_TRITON */
 	}
 #endif /* CONFIG_PCI */
diff -u --recursive --new-file pre2.0.7/linux/drivers/cdrom/mcdx.c linux/drivers/cdrom/mcdx.c
--- pre2.0.7/linux/drivers/cdrom/mcdx.c	Tue May 21 19:52:35 1996
+++ linux/drivers/cdrom/mcdx.c	Tue May 21 19:51:42 1996
@@ -854,8 +854,8 @@
 				printk(KERN_ERR MCDX ": transfer timeout.\n");
 			}
 			/*
-			 * We don't report about !stuffp->introk, sice this is
-			 * allready done in the interrupt routine.
+			 * We don't report about !stuffp->introk, since this is
+			 * already done in the interrupt routine.
 			 */
 			stuffp->busy = 0;
 			stuffp->valid = 0;
diff -u --recursive --new-file pre2.0.7/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- pre2.0.7/linux/drivers/net/de4x5.c	Fri May 17 15:32:15 1996
+++ linux/drivers/net/de4x5.c	Mon May 27 13:36:04 1996
@@ -2642,7 +2642,9 @@
 
     ret = lp->rx_skb[index];
     lp->rx_skb[index] = p;
-    skb_put(ret, len);
+
+    if ((unsigned long) ret > 1)
+	    skb_put(ret, len);
 
     return ret;
 
diff -u --recursive --new-file pre2.0.7/linux/drivers/net/loopback.c linux/drivers/net/loopback.c
--- pre2.0.7/linux/drivers/net/loopback.c	Mon May 20 08:21:01 1996
+++ linux/drivers/net/loopback.c	Mon May 27 13:12:19 1996
@@ -122,7 +122,6 @@
 	dev->mtu		= LOOPBACK_MTU;
 	dev->tbusy		= 0;
 	dev->hard_start_xmit	= loopback_xmit;
-	dev->open		= NULL;
 	dev->hard_header	= eth_header;
 	dev->hard_header_len	= ETH_HLEN;		/* 14			*/
 	dev->addr_len		= ETH_ALEN;		/* 6			*/
diff -u --recursive --new-file pre2.0.7/linux/drivers/net/new_tunnel.c linux/drivers/net/new_tunnel.c
--- pre2.0.7/linux/drivers/net/new_tunnel.c	Tue May  7 16:22:29 1996
+++ linux/drivers/net/new_tunnel.c	Mon May 27 13:11:50 1996
@@ -86,7 +86,6 @@
 #define TUNL_HLEN	(((ETH_HLEN+15)&~15)+tunnel_hlen)
 
 
-#ifdef MODULE
 static int tunnel_open(struct device *dev)
 {
 	MOD_INC_USE_COUNT;
@@ -99,8 +98,6 @@
 	return 0;
 }
 
-#endif
-
 #ifdef TUNNEL_DEBUG
 void print_ip(struct iphdr *ip)
 {
@@ -348,10 +345,8 @@
 	}
 
 	/* Add our tunnel functions to the device */
-#ifdef MODULE
 	dev->open		= tunnel_open;
 	dev->stop		= tunnel_close;
-#endif
 	dev->hard_start_xmit	= tunnel_xmit;
 	dev->get_stats		= tunnel_get_stats;
 	dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL);
diff -u --recursive --new-file pre2.0.7/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- pre2.0.7/linux/drivers/pci/pci.c	Sun Apr 21 12:39:01 1996
+++ linux/drivers/pci/pci.c	Mon May 27 14:01:04 1996
@@ -226,6 +226,9 @@
 	DEVICE( INTEL,		INTEL_82437,	"82437"),
 	DEVICE( INTEL,		INTEL_82371_0,	"82371 Triton PIIX"),
 	DEVICE( INTEL,		INTEL_82371_1,	"82371 Triton PIIX"),
+	DEVICE( INTEL,		INTEL_82439,	"82439HX Triton II"),
+	DEVICE(	INTEL,		INTEL_82371SB_0,"82371SB Triton II PIIX"),
+	DEVICE(	INTEL,		INTEL_82371SB_1,"82371SB Triton II PIIX"),
 	DEVICE( INTEL,		INTEL_P6,	"Orion P6"),
 	DEVICE( ADAPTEC,	ADAPTEC_7850,	"AIC-7850"),
 	DEVICE( ADAPTEC,	ADAPTEC_7855,	"AIC-7855"),
diff -u --recursive --new-file pre2.0.7/linux/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c
--- pre2.0.7/linux/drivers/scsi/seagate.c	Tue May  7 16:22:34 1996
+++ linux/drivers/scsi/seagate.c	Mon May 27 13:37:18 1996
@@ -924,7 +924,7 @@
 			if (STATUS & STAT_BSY) {
 				printk("scsi%d : BST asserted after we've been aborted.\n",
 					hostno);
-				seagate_st0x_reset(NULL);
+				seagate_st0x_reset(NULL, 0);
 				return retcode(DID_RESET);
 			}
 			return retcode(st0x_aborted);
@@ -1597,7 +1597,7 @@
 	the seagate_st0x_reset function resets the SCSI bus
 */
 	
-int seagate_st0x_reset (Scsi_Cmnd * SCpnt)
+int seagate_st0x_reset (Scsi_Cmnd * SCpnt, unsigned int reset_flags)
 	{
 	unsigned clock;
 	/*
diff -u --recursive --new-file pre2.0.7/linux/drivers/scsi/seagate.h linux/drivers/scsi/seagate.h
--- pre2.0.7/linux/drivers/scsi/seagate.h	Tue Nov 14 08:44:04 1995
+++ linux/drivers/scsi/seagate.h	Mon May 27 13:37:18 1996
@@ -18,7 +18,7 @@
 
 int seagate_st0x_abort(Scsi_Cmnd *);
 const char *seagate_st0x_info(struct Scsi_Host *);
-int seagate_st0x_reset(Scsi_Cmnd *); 
+int seagate_st0x_reset(Scsi_Cmnd *, unsigned int); 
 int seagate_st0x_proc_info(char *,char **,off_t,int,int,int);
 
 #ifndef NULL
diff -u --recursive --new-file pre2.0.7/linux/drivers/sound/Readme.linux linux/drivers/sound/Readme.linux
--- pre2.0.7/linux/drivers/sound/Readme.linux	Fri Apr 12 15:52:02 1996
+++ linux/drivers/sound/Readme.linux	Mon May 27 14:07:55 1996
@@ -74,8 +74,19 @@
 
 ----------------- cut here ------------------------------
 #!/bin/sh
+# *****************************************
+# * NOTICE!
+# *
+# * For security reasons read access to /dev/dsp* and /dev/audio* has been
+# * disabled from other than root. Otherwise any user may be able to spy
+# * what is being talked about near the microphone.
+# * This effectively disables audio recording by other than root. In case
+# * this capability is required, you should change AUDIOPERMS (below) to 666
+# * before executing this script.
+# *****************************************
+AUDIOPERMS=622
+#
 #
-#	soundinstall		
 #
 #
 # Create the devices
@@ -161,7 +172,7 @@
 if [ -e /dev/dsp0 ]; then
 	rm -f /dev/dsp0
 fi
-mknod -m 666 /dev/dsp0 c 14 3
+mknod -m $AUDIOPERMS /dev/dsp0 c 14 3
 ln -s /dev/dsp0 /dev/dsp
 
 #
@@ -173,13 +184,13 @@
 if [ -e /dev/dspW0 ]; then
 	rm -f /dev/dspW0
 fi
-mknod -m 666 /dev/dspW0 c 14 5
+mknod -m $AUDIOPERMS /dev/dspW0 c 14 5
 ln -s /dev/dspW0 /dev/dspW
 
 if [ -e /dev/dspW1 ]; then
 	rm -f /dev/dspW1
 fi
-mknod -m 666 /dev/dspW1 c 14 37
+mknod -m $AUDIOPERMS /dev/dspW1 c 14 37
 
 #
 #	SPARC compatible /dev/audio	(14, 4)	
@@ -190,7 +201,7 @@
 if [ -e /dev/audio0 ]; then
 	rm -f /dev/audio0
 fi
-mknod -m 666 /dev/audio0 c 14 4
+mknod -m $AUDIOPERMS /dev/audio0 c 14 4
 ln -s /dev/audio0 /dev/audio
 
 #
@@ -201,7 +212,7 @@
 if [ -e /dev/dsp1 ]; then
 	rm -f /dev/dsp1
 fi
-mknod -m 666 /dev/dsp1 c 14 19
+mknod -m $AUDIOPERMS /dev/dsp1 c 14 19
 #
 #	SPARC audio1	(14, 20) 
 #				/dev/audio for the second soundcard.
@@ -211,7 +222,7 @@
 if [ -e /dev/audio1 ]; then
 	rm -f /dev/audio1
 fi
-mknod -m 666 /dev/audio1 c 14 20
+mknod -m $AUDIOPERMS /dev/audio1 c 14 20
 #
 #	/dev/sndstat	(14,6)	For debugging purposes
 #
diff -u --recursive --new-file pre2.0.7/linux/fs/open.c linux/fs/open.c
--- pre2.0.7/linux/fs/open.c	Wed Apr 10 17:02:25 1996
+++ linux/fs/open.c	Mon May 27 15:47:32 1996
@@ -86,34 +86,37 @@
 	error = namei(path,&inode);
 	if (error)
 		return error;
-	if (S_ISDIR(inode->i_mode)) {
-		iput(inode);
-		return -EACCES;
-	}
-	if ((error = permission(inode,MAY_WRITE)) != 0) {
-		iput(inode);
-		return error;
-	}
-	if (IS_RDONLY(inode)) {
-		iput(inode);
-		return -EROFS;
-	}
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
-		iput(inode);
-		return -EPERM;
-	}
+
+	error = -EACCES;
+	if (S_ISDIR(inode->i_mode))
+		goto out;
+
+	error = permission(inode,MAY_WRITE);
+	if (error)
+		goto out;
+
+	error = -EROFS;
+	if (IS_RDONLY(inode))
+		goto out;
+
+	error = -EPERM;
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		goto out;
+
 	error = get_write_access(inode);
-	if (error) {
-		iput(inode);
-		return error;
-	}
+	if (error)
+		goto out;
+
 	error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, NULL,
 				  length < inode->i_size ? length : inode->i_size,
 				  abs(inode->i_size - length));
-	if (error)
-		return error;
-	error = do_truncate(inode, length);
+	if (!error) {
+		if (inode->i_sb && inode->i_sb->dq_op)
+			inode->i_sb->dq_op->initialize(inode, -1);
+		error = do_truncate(inode, length);
+	}
 	put_write_access(inode);
+out:
 	iput(inode);
 	return error;
 }
@@ -135,9 +138,9 @@
 	error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file,
 				  length < inode->i_size ? length : inode->i_size,
 				  abs(inode->i_size - length));
-	if (error)
-		return error;
-	return do_truncate(inode, length);
+	if (!error)
+		error = do_truncate(inode, length);
+	return error;
 }
 
 #ifndef __alpha__
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/atomic.h linux/include/asm-ppc/atomic.h
--- pre2.0.7/linux/include/asm-ppc/atomic.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/atomic.h	Mon May 27 12:00:59 1996
@@ -0,0 +1,10 @@
+/*
+ * PowerPC atomic operations
+ */
+
+#ifndef _ASM_PPC_ATOMIC_H_ 
+#define _ASM_PPC_ATOMIC_H_
+
+typedef int atomic_t;
+#endif
+
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/bitops.h linux/include/asm-ppc/bitops.h
--- pre2.0.7/linux/include/asm-ppc/bitops.h	Sat Nov 25 19:49:06 1995
+++ linux/include/asm-ppc/bitops.h	Mon May 27 12:00:59 1996
@@ -22,7 +22,6 @@
 typedef unsigned long BITFIELD;
 
 extern __inline__ int set_bit(int nr, void * add)
-/*extern __inline__ int set_bit(int nr, BITFIELD * addr)*/
 {
        int	mask, oldbit;
   BITFIELD *addr = add;
@@ -38,8 +37,6 @@
 	return oldbit;
 }
 
-
-/*extern __inline__ int change_bit(int nr, BITFIELD *addr)*/
 extern __inline__ int change_bit(int nr, void *add)
 {
   	BITFIELD *addr = add;
@@ -53,8 +50,6 @@
 	return retval;
 }
 
-
-/*extern __inline__ int clear_bit(int nr, BITFIELD *addr2)*/
 extern __inline__ int clear_bit(int nr, void *add)
 {
         BITFIELD *addr = add;
@@ -69,7 +64,6 @@
 }
 
 extern __inline__ int test_bit(int nr, void *add)
-/*extern __inline__ int test_bit(int nr, BITFIELD *addr)*/
 {
 	int	mask;
 	BITFIELD *addr = add;
@@ -78,7 +72,59 @@
 	mask = BIT(nr);
 	return ((mask & *addr) != 0);
 }
+#if 0
+extern __inline__ int find_first_zero_bit(void *add, int len)
+{
+	int	mask, nr, i;
+	BITFIELD *addr = add;
+	nr = 0;
+	while (len)
+	{
+		if (~*addr != 0)
+		{ /* Contains at least one zero */
+			for (i = 0;  i < 32;  i++, nr++)
+			{
+				mask = BIT(nr);
+				if ((mask & *addr) == 0)
+				{
+					return (nr);
+				}
+			}
+		}
+		len -= 32;
+		addr++;
+		nr += 32;
+	}
+	return (0);  /* Shouldn't happen */
+}
 
+extern __inline__ int find_next_zero_bit(void *add, int len, int nr)
+{
+	int	mask, i;
+	BITFIELD *addr = add;
+	addr += nr >> 5;
+	len -= nr;
+	while (len)
+	{
+		if (*addr != 0xFFFFFFFF)
+		{ /* Contains at least one zero */
+			for (i = 0;  i < 32;  i++, nr++)
+			{
+				mask = BIT(nr);
+				if ((mask & *addr) == 0)
+				{
+printk("Bit: %d(%d), Pat: %x\n", nr, nr&0x1F, *addr);					
+					return (nr);
+				}
+			}
+		}
+		len -= 32;
+		addr++;
+		nr += 32;
+	}
+	return (0);  /* Shouldn't happen */
+}
+#endif
 #endif /* _ASM_PPC_BITOPS_H */
 
 
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/dma.h linux/include/asm-ppc/dma.h
--- pre2.0.7/linux/include/asm-ppc/dma.h	Sat Nov 25 19:49:06 1995
+++ linux/include/asm-ppc/dma.h	Mon May 27 12:00:59 1996
@@ -5,6 +5,15 @@
  * and John Boyd, Nov. 1992.
  */
 
+/*
+ * Note: Adapted for PowerPC by Gary Thomas
+ *
+ * There may be some comments or restrictions made here which are
+ * not valid for the PowerPC (PreP) platform.  Take what you read
+ * with a grain of salt.
+ */
+ 
+
 #ifndef _ASM_DMA_H
 #define _ASM_DMA_H
 
@@ -70,7 +79,8 @@
 #define MAX_DMA_CHANNELS	8
 
 /* The maximum address that we can perform a DMA transfer to on this platform */
-#define MAX_DMA_ADDRESS      0x1000000
+/* Doesn't really apply... */
+#define MAX_DMA_ADDRESS      0xFFFFFFFF
 
 /* 8237 DMA controllers */
 #define IO_DMA1_BASE	0x00	/* 8 bit slave DMA, channels 0..3 */
@@ -117,13 +127,21 @@
 #define DMA_CNT_6               0xCA
 #define DMA_CNT_7               0xCE
 
-#define DMA_PAGE_0              0x87    /* DMA page registers */
-#define DMA_PAGE_1              0x83
-#define DMA_PAGE_2              0x81
-#define DMA_PAGE_3              0x82
-#define DMA_PAGE_5              0x8B
-#define DMA_PAGE_6              0x89
-#define DMA_PAGE_7              0x8A
+#define DMA_LO_PAGE_0              0x87    /* DMA page registers */
+#define DMA_LO_PAGE_1              0x83
+#define DMA_LO_PAGE_2              0x81
+#define DMA_LO_PAGE_3              0x82
+#define DMA_LO_PAGE_5              0x8B
+#define DMA_LO_PAGE_6              0x89
+#define DMA_LO_PAGE_7              0x8A
+
+#define DMA_HI_PAGE_0              0x487    /* DMA page registers */
+#define DMA_HI_PAGE_1              0x483
+#define DMA_HI_PAGE_2              0x481
+#define DMA_HI_PAGE_3              0x482
+#define DMA_HI_PAGE_5              0x48B
+#define DMA_HI_PAGE_6              0x489
+#define DMA_HI_PAGE_7              0x48A
 
 #define DMA_MODE_READ	0x44	/* I/O to memory, no autoinit, increment, single mode */
 #define DMA_MODE_WRITE	0x48	/* memory to I/O, no autoinit, increment, single mode */
@@ -132,10 +150,19 @@
 /* enable/disable a specific DMA channel */
 static __inline__ void enable_dma(unsigned int dmanr)
 {
+	if (dmanr != 4)
+	{
+		dma_outb(0, DMA2_MASK_REG);  /* This may not be enabled */
+		dma_outb(0, DMA2_CMD_REG);  /* Enable group */
+	}
 	if (dmanr<=3)
+	{
 		dma_outb(dmanr,  DMA1_MASK_REG);
-	else
+		dma_outb(0, DMA1_CMD_REG);  /* Enable group */
+	} else
+	{
 		dma_outb(dmanr & 3,  DMA2_MASK_REG);
+	}
 }
 
 static __inline__ void disable_dma(unsigned int dmanr)
@@ -175,29 +202,30 @@
  * the lower 16 bits of the DMA current address register, but a 64k boundary
  * may have been crossed.
  */
-static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
+static __inline__ void set_dma_page(unsigned int dmanr, int pagenr)
 {
 	switch(dmanr) {
 		case 0:
-			dma_outb(pagenr, DMA_PAGE_0);
+			dma_outb(pagenr, DMA_LO_PAGE_0);
 			break;
 		case 1:
-			dma_outb(pagenr, DMA_PAGE_1);
+			dma_outb(pagenr, DMA_LO_PAGE_1);
 			break;
 		case 2:
-			dma_outb(pagenr, DMA_PAGE_2);
+			dma_outb(pagenr, DMA_LO_PAGE_2);
+			dma_outb(pagenr>>8, DMA_HI_PAGE_2); 
 			break;
 		case 3:
-			dma_outb(pagenr, DMA_PAGE_3);
+			dma_outb(pagenr, DMA_LO_PAGE_3);
 			break;
 		case 5:
-			dma_outb(pagenr & 0xfe, DMA_PAGE_5);
+			dma_outb(pagenr & 0xfe, DMA_LO_PAGE_5);
 			break;
 		case 6:
-			dma_outb(pagenr & 0xfe, DMA_PAGE_6);
+			dma_outb(pagenr & 0xfe, DMA_LO_PAGE_6);
 			break;
 		case 7:
-			dma_outb(pagenr & 0xfe, DMA_PAGE_7);
+			dma_outb(pagenr & 0xfe, DMA_LO_PAGE_7);
 			break;
 	}
 }
@@ -206,16 +234,16 @@
 /* Set transfer address & page bits for specific DMA channel.
  * Assumes dma flipflop is clear.
  */
-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys)
 {
-	set_dma_page(dmanr, a>>16);
 	if (dmanr <= 3)  {
-	    dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
-            dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+	    dma_outb( phys & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+            dma_outb( (phys>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
 	}  else  {
-	    dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
-	    dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+	    dma_outb( (phys>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+	    dma_outb( (phys>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
 	}
+	set_dma_page(dmanr, phys>>16);
 }
 
 
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/errno.h linux/include/asm-ppc/errno.h
--- pre2.0.7/linux/include/asm-ppc/errno.h	Sat Nov 25 19:49:06 1995
+++ linux/include/asm-ppc/errno.h	Mon May 27 12:00:59 1996
@@ -11,7 +11,7 @@
 #define	ENOEXEC		 8	/* Exec format error */
 #define	EBADF		 9	/* Bad file number */
 #define	ECHILD		10	/* No child processes */
-#define	EDEADLK		11	/* Resource deadlock would occur */
+#define	EAGAIN		11	/* Try again */
 #define	ENOMEM		12	/* Out of memory */
 #define	EACCES		13	/* Permission denied */
 #define	EFAULT		14	/* Bad address */
@@ -35,62 +35,15 @@
 #define	EPIPE		32	/* Broken pipe */
 #define	EDOM		33	/* Math argument out of domain of func */
 #define	ERANGE		34	/* Math result not representable */
-#define	EAGAIN		35	/* Try again */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
 #define	EWOULDBLOCK	EAGAIN	/* Operation would block */
-#define	EINPROGRESS	36	/* Operation now in progress */
-#define	EALREADY	37	/* Operation already in progress */
-#define	ENOTSOCK	38	/* Socket operation on non-socket */
-#define	EDESTADDRREQ	39	/* Destination address required */
-#define	EMSGSIZE	40	/* Message too long */
-#define	EPROTOTYPE	41	/* Protocol wrong type for socket */
-#define	ENOPROTOOPT	42	/* Protocol not available */
-#define	EPROTONOSUPPORT	43	/* Protocol not supported */
-#define	ESOCKTNOSUPPORT	44	/* Socket type not supported */
-#define	EOPNOTSUPP	45	/* Operation not supported on transport endpoint */
-#define	EPFNOSUPPORT	46	/* Protocol family not supported */
-#define	EAFNOSUPPORT	47	/* Address family not supported by protocol */
-#define	EADDRINUSE	48	/* Address already in use */
-#define	EADDRNOTAVAIL	49	/* Cannot assign requested address */
-#define	ENETDOWN	50	/* Network is down */
-#define	ENETUNREACH	51	/* Network is unreachable */
-#define	ENETRESET	52	/* Network dropped connection because of reset */
-#define	ECONNABORTED	53	/* Software caused connection abort */
-#define	ECONNRESET	54	/* Connection reset by peer */
-#define	ENOBUFS		55	/* No buffer space available */
-#define	EISCONN		56	/* Transport endpoint is already connected */
-#define	ENOTCONN	57	/* Transport endpoint is not connected */
-#define	ESHUTDOWN	58	/* Cannot send after transport endpoint shutdown */
-#define	ETOOMANYREFS	59	/* Too many references: cannot splice */
-#define	ETIMEDOUT	60	/* Connection timed out */
-#define	ECONNREFUSED	61	/* Connection refused */
-#define	ELOOP		62	/* Too many symbolic links encountered */
-#define	ENAMETOOLONG	63	/* File name too long */
-#define	EHOSTDOWN	64	/* Host is down */
-#define	EHOSTUNREACH	65	/* No route to host */
-#define	ENOTEMPTY	66	/* Directory not empty */
-
-#define	EUSERS		68	/* Too many users */
-#define	EDQUOT		69	/* Quota exceeded */
-#define	ESTALE		70	/* Stale NFS file handle */
-#define	EREMOTE		71	/* Object is remote */
-
-#define	ENOLCK		77	/* No record locks available */
-#define	ENOSYS		78	/* Function not implemented */
-
-#define	ENOMSG		80	/* No message of desired type */
-#define	EIDRM		81	/* Identifier removed */
-#define	ENOSR		82	/* Out of streams resources */
-#define	ETIME		83	/* Timer expired */
-#define	EBADMSG		84	/* Not a data message */
-#define	EPROTO		85	/* Protocol error */
-#define	ENODATA		86	/* No data available */
-#define	ENOSTR		87	/* Device not a stream */
-
-#define	ENOPKG		92	/* Package not installed */
-
-#define	EILSEQ		116	/* Illegal byte sequence */
-
-/* The following are just random noise.. */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
 #define	ECHRNG		44	/* Channel number out of range */
 #define	EL2NSYNC	45	/* Level 2 not synchronized */
 #define	EL3HLT		46	/* Level 3 halted */
@@ -107,13 +60,21 @@
 #define	EBADSLT		57	/* Invalid slot */
 #define	EDEADLOCK	58	/* File locking deadlock error */
 #define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
 #define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
 #define	ENOLINK		67	/* Link has been severed */
 #define	EADV		68	/* Advertise error */
 #define	ESRMNT		69	/* Srmount error */
 #define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
 #define	EMULTIHOP	72	/* Multihop attempted */
 #define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
 #define	EOVERFLOW	75	/* Value too large for defined data type */
 #define	ENOTUNIQ	76	/* Name not unique on network */
 #define	EBADFD		77	/* File descriptor in bad state */
@@ -123,12 +84,50 @@
 #define	ELIBSCN		81	/* .lib section in a.out corrupted */
 #define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
 #define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
 #define	ERESTART	85	/* Interrupted system call should be restarted */
 #define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
 #define	EUCLEAN		117	/* Structure needs cleaning */
 #define	ENOTNAM		118	/* Not a XENIX named type file */
 #define	ENAVAIL		119	/* No XENIX semaphores available */
 #define	EISNAM		120	/* Is a named type file */
 #define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+/* Should never be seen by user programs */
+#define ERESTARTSYS	512
+#define ERESTARTNOINTR	513
+#define ERESTARTNOHAND	514	/* restart if no handler.. */
+#define ENOIOCTLCMD	515	/* No ioctl command */
 
 #endif
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/floppy.h linux/include/asm-ppc/floppy.h
--- pre2.0.7/linux/include/asm-ppc/floppy.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/floppy.h	Mon May 27 12:00:59 1996
@@ -0,0 +1,54 @@
+/*
+ * Architecture specific parts of the Floppy driver
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995
+ */
+#ifndef __ASM_PPC_FLOPPY_H
+#define __ASM_PPC_FLOPPY_H
+
+#define fd_inb(port)			inb_p(port)
+#define fd_outb(port,value)		outb_p(port,value)
+
+#define fd_enable_dma()         enable_dma(FLOPPY_DMA)
+#define fd_disable_dma()        disable_dma(FLOPPY_DMA)
+#define fd_request_dma()        request_dma(FLOPPY_DMA,"floppy")
+#define fd_free_dma()           free_dma(FLOPPY_DMA)
+#define fd_clear_dma_ff()       clear_dma_ff(FLOPPY_DMA)
+#define fd_set_dma_mode(mode)   set_dma_mode(FLOPPY_DMA,mode)
+#define fd_set_dma_addr(addr)   set_dma_addr(FLOPPY_DMA,addr)
+#define fd_set_dma_count(count) set_dma_count(FLOPPY_DMA,count)
+#define fd_enable_irq()         enable_irq(FLOPPY_IRQ)
+#define fd_disable_irq()        disable_irq(FLOPPY_IRQ)
+#define fd_cacheflush(addr,size) /* nothing */
+#define fd_request_irq()        request_irq(FLOPPY_IRQ, floppy_interrupt, \
+					    SA_INTERRUPT|SA_SAMPLE_RANDOM, \
+				            "floppy", NULL)
+#define fd_free_irq()           free_irq(FLOPPY_IRQ, NULL);
+
+__inline__ void virtual_dma_init(void)
+{
+	/* Nothing to do on PowerPC */
+}
+
+static int FDC1 = 0x3f0;
+static int FDC2 = -1;
+
+/*
+ * Again, the CMOS information not available
+ */
+#define FLOPPY0_TYPE 6
+#define FLOPPY1_TYPE 0
+
+#define N_FDC 2			/* Don't change this! */
+#define N_DRIVE 8
+
+/*
+ * The PowerPC has no problems with floppy DMA crossing 64k borders.
+ */
+#define CROSS_64KB(a,s)	(0)
+
+#endif /* __ASM_PPC_FLOPPY_H */
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/ioctls.h linux/include/asm-ppc/ioctls.h
--- pre2.0.7/linux/include/asm-ppc/ioctls.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/ioctls.h	Mon May 27 12:00:59 1996
@@ -0,0 +1,102 @@
+#ifndef _ASM_PPC_IOCTLS_H
+#define _ASM_PPC_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+#define FIOCLEX		_IO('f', 1)
+#define FIONCLEX	_IO('f', 2)
+#define FIOASYNC	_IOW('f', 125, int)
+#define FIONBIO		_IOW('f', 126, int)
+#define FIONREAD	_IOR('f', 127, int)
+#define TIOCINQ		FIONREAD
+
+#define TIOCGETP	_IOR('t', 8, struct sgttyb)
+#define TIOCSETP	_IOW('t', 9, struct sgttyb)
+#define TIOCSETN	_IOW('t', 10, struct sgttyb)	/* TIOCSETP wo flush */
+
+#define TIOCSETC	_IOW('t', 17, struct tchars)
+#define TIOCGETC	_IOR('t', 18, struct tchars)
+#define TCGETS		_IOR('t', 19, struct termios)
+#define TCSETS		_IOW('t', 20, struct termios)
+#define TCSETSW		_IOW('t', 21, struct termios)
+#define TCSETSF		_IOW('t', 22, struct termios)
+
+#define TCGETA		_IOR('t', 23, struct termio)
+#define TCSETA		_IOW('t', 24, struct termio)
+#define TCSETAW		_IOW('t', 25, struct termio)
+#define TCSETAF		_IOW('t', 28, struct termio)
+
+#define TCSBRK		_IO('t', 29)
+#define TCXONC		_IO('t', 30)
+#define TCFLSH		_IO('t', 31)
+
+#define TIOCSWINSZ	_IOW('t', 103, struct winsize)
+#define TIOCGWINSZ	_IOR('t', 104, struct winsize)
+#define	TIOCSTART	_IO('t', 110)		/* start output, like ^Q */
+#define	TIOCSTOP	_IO('t', 111)		/* stop output, like ^S */
+#define TIOCOUTQ        _IOR('t', 115, int)     /* output queue size */
+
+#define TIOCGLTC	_IOR('t', 116, struct ltchars)
+#define TIOCSLTC	_IOW('t', 117, struct ltchars)
+#define TIOCSPGRP	_IOW('t', 118, int)
+#define TIOCGPGRP	_IOR('t', 119, int)
+
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+
+#define TIOCSTI		0x5412
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+# define TIOCM_LE	0x001
+# define TIOCM_DTR	0x002
+# define TIOCM_RTS	0x004
+# define TIOCM_ST	0x008
+# define TIOCM_SR	0x010
+# define TIOCM_CTS	0x020
+# define TIOCM_CAR	0x040
+# define TIOCM_RNG	0x080
+# define TIOCM_DSR	0x100
+# define TIOCM_CD	TIOCM_CAR
+# define TIOCM_RI	TIOCM_RNG
+
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+# define TIOCPKT_DATA		 0
+# define TIOCPKT_FLUSHREAD	 1
+# define TIOCPKT_FLUSHWRITE	 2
+# define TIOCPKT_STOP		 4
+# define TIOCPKT_START		 8
+# define TIOCPKT_NOSTOP		16
+# define TIOCPKT_DOSTOP		32
+
+
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+  /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+# define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+
+#endif /* _ASM_PPC_IOCTLS_H */
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/irq.h linux/include/asm-ppc/irq.h
--- pre2.0.7/linux/include/asm-ppc/irq.h	Sat Nov 25 19:49:06 1995
+++ linux/include/asm-ppc/irq.h	Mon May 27 12:00:59 1996
@@ -1,13 +1,7 @@
 #ifndef _ASM_IRQ_H
 #define _ASM_IRQ_H
 
-
-/*
- * wild guess here.  someone should go look and put
- * the right number in.
- *                      -- Cort
- */
-# define NR_IRQS	16
+#define NR_IRQS	32
 
 extern void disable_irq(unsigned int);
 extern void enable_irq(unsigned int);
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/mc146818rtc.h linux/include/asm-ppc/mc146818rtc.h
--- pre2.0.7/linux/include/asm-ppc/mc146818rtc.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/mc146818rtc.h	Mon May 27 12:00:59 1996
@@ -0,0 +1,109 @@
+/* mc146818rtc.h - register definitions for the Real-Time-Clock / CMOS RAM
+ * Copyright Torsten Duwe <duwe@informatik.uni-erlangen.de> 1993
+ * derived from Data Sheet, Copyright Motorola 1984 (!).
+ * It was written to be part of the Linux operating system.
+ */
+/* permission is hereby granted to copy, modify and redistribute this code
+ * in terms of the GNU Library General Public License, Version 2 or later,
+ * at your option.
+ */
+
+#ifndef _MC146818RTC_H
+#define _MC146818RTC_H
+#include <asm/io.h>
+
+#ifndef MCRTC_PORT
+#define MCRTC_PORT(x)	(0x70 + (x))
+#define MCRTC_ALWAYS_BCD	1
+#endif
+
+#define CMOS_MCRTC_READ(addr) ({ \
+outb_p((addr),MCRTC_PORT(0)); \
+inb_p(MCRTC_PORT(1)); \
+})
+#define CMOS_MCRTC_WRITE(val, addr) ({ \
+outb_p((addr),MCRTC_PORT(0)); \
+outb_p((val),MCRTC_PORT(1)); \
+})
+
+/**********************************************************************
+ * register summary
+ **********************************************************************/
+#define MCRTC_SECONDS		0
+#define MCRTC_SECONDS_ALARM	1
+#define MCRTC_MINUTES		2
+#define MCRTC_MINUTES_ALARM	3
+#define MCRTC_HOURS		4
+#define MCRTC_HOURS_ALARM		5
+/* RTC_*_alarm is always true if 2 MSBs are set */
+# define MCRTC_ALARM_DONT_CARE 	0xC0
+
+#define MCRTC_DAY_OF_WEEK		6
+#define MCRTC_DAY_OF_MONTH	7
+#define MCRTC_MONTH		8
+#define MCRTC_YEAR		9
+
+/* control registers - Moto names
+ */
+#define MCRTC_REG_A		10
+#define MCRTC_REG_B		11
+#define MCRTC_REG_C		12
+#define MCRTC_REG_D		13
+
+/**********************************************************************
+ * register details
+ **********************************************************************/
+#define MCRTC_FREQ_SELECT	MCRTC_REG_A
+
+/* update-in-progress  - set to "1" 244 microsecs before RTC goes off the bus,
+ * reset after update (may take 1.984ms @ 32768Hz RefClock) is complete,
+ * totalling to a max high interval of 2.228 ms.
+ */
+# define MCRTC_UIP		0x80
+# define MCRTC_DIV_CTL		0x70
+   /* divider control: refclock values 4.194 / 1.049 MHz / 32.768 kHz */
+#  define MCRTC_REF_CLCK_4MHZ	0x00
+#  define MCRTC_REF_CLCK_1MHZ	0x10
+#  define MCRTC_REF_CLCK_32KHZ	0x20
+   /* 2 values for divider stage reset, others for "testing purposes only" */
+#  define MCRTC_DIV_RESET1	0x60
+#  define MCRTC_DIV_RESET2	0x70
+  /* Periodic intr. / Square wave rate select. 0=none, 1=32.8kHz,... 15=2Hz */
+# define MCRTC_RATE_SELECT 	0x0F
+
+/**********************************************************************/
+#define MCRTC_CONTROL	MCRTC_REG_B
+# define MCRTC_SET 0x80		/* disable updates for clock setting */
+# define MCRTC_PIE 0x40		/* periodic interrupt enable */
+# define MCRTC_AIE 0x20		/* alarm interrupt enable */
+# define MCRTC_UIE 0x10		/* update-finished interrupt enable */
+# define MCRTC_SQWE 0x08		/* enable square-wave output */
+# define MCRTC_DM_BINARY 0x04	/* all time/date values are BCD if clear */
+# define MCRTC_24H 0x02		/* 24 hour mode - else hours bit 7 means pm */
+# define MCRTC_DST_EN 0x01	/* auto switch DST - works f. USA only */
+
+/**********************************************************************/
+#define MCRTC_INTR_FLAGS	MCRTC_REG_C
+/* caution - cleared by read */
+# define MCRTC_IRQF 0x80		/* any of the following 3 is active */
+# define MCRTC_PF 0x40
+# define MCRTC_AF 0x20
+# define MCRTC_UF 0x10
+
+/**********************************************************************/
+#define MCRTC_VALID	MCRTC_REG_D
+# define MCRTC_VRT 0x80		/* valid RAM and time */
+/**********************************************************************/
+
+/* example: !(CMOS_READ(MCRTC_CONTROL) & MCRTC_DM_BINARY) 
+ * determines if the following two #defines are needed
+ */
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+#endif
+
+#endif /* _MC146818RTC_H */
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/mman.h linux/include/asm-ppc/mman.h
--- pre2.0.7/linux/include/asm-ppc/mman.h	Sat Nov 25 19:49:06 1995
+++ linux/include/asm-ppc/mman.h	Mon May 27 12:00:59 1996
@@ -11,6 +11,7 @@
 #define MAP_TYPE	0x0f		/* Mask for type of mapping */
 #define MAP_FIXED	0x10		/* Interpret addr exactly */
 #define MAP_ANONYMOUS	0x20		/* don't use a file */
+#define MAP_RENAME      MAP_ANONYMOUS   /* In SunOS terminology */
 
 #define MAP_GROWSDOWN	0x0100		/* stack-like segment */
 #define MAP_DENYWRITE	0x0800		/* ETXTBSY */
@@ -20,4 +21,11 @@
 #define MS_INVALIDATE	2		/* invalidate the caches */
 #define MS_SYNC		4		/* synchronous memory sync */
 
-#endif /* __I386_MMAN_H__ */
+#define MCL_CURRENT     0x2000          /* lock all currently mapped pages */
+#define MCL_FUTURE      0x4000          /* lock all additions to address space */
+
+/* compatibility flags */
+#define MAP_ANON	MAP_ANONYMOUS
+#define MAP_FILE	0
+
+#endif /* __PPC_MMAN_H__ */
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/mmu.h linux/include/asm-ppc/mmu.h
--- pre2.0.7/linux/include/asm-ppc/mmu.h	Sat Nov 25 19:49:06 1995
+++ linux/include/asm-ppc/mmu.h	Mon May 27 12:00:59 1996
@@ -29,6 +29,7 @@
 #define PP_RWXX	0	/* Supervisor read/write, User none */
 #define PP_RWRX 1	/* Supervisor read/write, User read */
 #define PP_RWRW 2	/* Supervisor read/write, User read/write */
+#define PP_RXRX 3	/* Supervisor read,       User read */
 
 /* Segment Register */
 
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/mmu_context.h linux/include/asm-ppc/mmu_context.h
--- pre2.0.7/linux/include/asm-ppc/mmu_context.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/mmu_context.h	Mon May 27 12:00:59 1996
@@ -0,0 +1,10 @@
+#ifndef __PPC_MMU_CONTEXT_H
+#define __PPC_MMU_CONTEXT_H
+
+/*
+ * get a new mmu context.. PowerPC's don't know about contexts [yet]
+ */
+#define get_mmu_context(x) do { } while (0)
+
+#endif
+
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/nvram.h linux/include/asm-ppc/nvram.h
--- pre2.0.7/linux/include/asm-ppc/nvram.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/nvram.h	Mon May 27 12:00:59 1996
@@ -0,0 +1,30 @@
+/*
+ * PreP compliant NVRAM access
+ */
+
+#ifndef _PPC_NVRAM_H
+#define _PPC_NVRAM_H
+
+#define NVRAM_AS0  0x74
+#define NVRAM_AS1  0x75
+#define NVRAM_DATA 0x77
+
+/* RTC Offsets */
+
+#define RTC_SECONDS		0x1FF9
+#define RTC_MINUTES		0x1FFA
+#define RTC_HOURS		0x1FFB
+#define RTC_DAY_OF_WEEK		0x1FFC
+#define RTC_DAY_OF_MONTH	0x1FFD
+#define RTC_MONTH		0x1FFE
+#define RTC_YEAR		0x1FFF
+
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+#endif
+
+#endif
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/page.h linux/include/asm-ppc/page.h
--- pre2.0.7/linux/include/asm-ppc/page.h	Sun Nov 26 10:48:54 1995
+++ linux/include/asm-ppc/page.h	Mon May 27 12:00:59 1996
@@ -63,6 +63,7 @@
 #define MAP_PAGE_RESERVED	(1<<15)
 
 
+#if 0  /* Now defined in "mm.h" */
 /*
  * This used to be an unsigned short...
  * 
@@ -75,6 +76,7 @@
 		 dirty:1,
 		 reserved:1;
 } mem_map_t;
+#endif
 
 /* Certain architectures need to do special things when pte's
  * within a page table are directly modified.  Thus, the following
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/pgtable.h linux/include/asm-ppc/pgtable.h
--- pre2.0.7/linux/include/asm-ppc/pgtable.h	Fri Apr 12 15:52:05 1996
+++ linux/include/asm-ppc/pgtable.h	Mon May 27 12:00:59 1996
@@ -111,6 +111,7 @@
 #define _PAGE_ACCESSED	0x020
 #define _PAGE_DIRTY	0x040
 #define _PAGE_COW	0x200	/* implemented in software (one of the AVL bits) */
+#define _PAGE_NO_CACHE	0x400
 
 #define _PAGE_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
 #define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
@@ -120,6 +121,7 @@
 #define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_COW)
 #define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
 #define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
+#define PAGE_KERNEL_NO_CACHE	__pgprot(_PAGE_NO_CACHE | _PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
 
 /*
  * The i386 can't do page protection for execute, and considers that the same are read.
@@ -144,6 +146,28 @@
 #define __S111	PAGE_SHARED
 
 /*
+ * TLB invalidation:
+ *
+ *  - invalidate() invalidates the current mm struct TLBs
+ *  - invalidate_all() invalidates all processes TLBs
+ *  - invalidate_mm(mm) invalidates the specified mm context TLB's
+ *  - invalidate_page(mm, vmaddr) invalidates one page
+ *  - invalidate_range(mm, start, end) invalidates a range of pages
+ *
+ * FIXME: This could be done much better!
+ */
+
+#define invalidate_all() printk("invalidate_all()\n");invalidate()
+#if 0
+#define invalidate_mm(mm_struct) \
+do { if ((mm_struct) == current->mm) invalidate(); else printk("Can't invalidate_mm(%x)\n", mm_struct);} while (0)
+#define invalidate_page(mm_struct,addr) \
+do { if ((mm_struct) == current->mm) invalidate(); else printk("Can't invalidate_page(%x,%x)\n", mm_struct, addr);} while (0)
+#define invalidate_range(mm_struct,start,end) \
+do { if ((mm_struct) == current->mm) invalidate(); else printk("Can't invalidate_range(%x,%x,%x)\n", mm_struct, start, end);} while (0)
+#endif
+
+/*
  * Define this if things work differently on a i386 and a i486:
  * it will (on a i486) warn about kernel memory accesses that are
  * done without a 'verify_area(VERIFY_WRITE,..)'
@@ -198,14 +222,18 @@
 
 extern inline int pte_none(pte_t pte)		{ return !pte_val(pte); }
 extern inline int pte_present(pte_t pte)	{ return pte_val(pte) & _PAGE_PRESENT; }
+#if 0
 extern inline int pte_inuse(pte_t *ptep)	{ return mem_map[MAP_NR(ptep)].reserved; }
 /*extern inline int pte_inuse(pte_t *ptep)	{ return mem_map[MAP_NR(ptep)] != 1; }*/
+#endif
 extern inline void pte_clear(pte_t *ptep)	{ pte_val(*ptep) = 0; }
+#if 0
 extern inline void pte_reuse(pte_t * ptep)
 {
 	if (!mem_map[MAP_NR(ptep)].reserved)
 		mem_map[MAP_NR(ptep)].count++;
 }
+#endif
 /*
    extern inline void pte_reuse(pte_t * ptep)
 {
@@ -228,8 +256,10 @@
 extern inline int pgd_none(pgd_t pgd)		{ return 0; }
 extern inline int pgd_bad(pgd_t pgd)		{ return 0; }
 extern inline int pgd_present(pgd_t pgd)	{ return 1; }
+#if 0
 /*extern inline int pgd_inuse(pgd_t * pgdp)	{ return mem_map[MAP_NR(pgdp)] != 1; }*/
 extern inline int pgd_inuse(pgd_t *pgdp)	{ return mem_map[MAP_NR(pgdp)].reserved;  }
+#endif
 extern inline void pgd_clear(pgd_t * pgdp)	{ }
 
 /*
@@ -310,7 +340,6 @@
  */
 extern inline void pte_free_kernel(pte_t * pte)
 {
-	mem_map[MAP_NR(pte)].reserved = 1;
 	free_page((unsigned long) pte);
 }
 /*extern inline void pte_free_kernel(pte_t * pte)
@@ -391,7 +420,6 @@
 			if (page) {
 /*                                pmd_set(pmd,page);*/
 			pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
-				mem_map[MAP_NR(page)].reserved = 1;
 				return page + address;
 			}
 /*			pmd_set(pmd, BAD_PAGETABLE);*/
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/posix_types.h linux/include/asm-ppc/posix_types.h
--- pre2.0.7/linux/include/asm-ppc/posix_types.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/posix_types.h	Mon May 27 12:00:59 1996
@@ -0,0 +1,98 @@
+#ifndef _PPC_POSIX_TYPES_H
+#define _PPc_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned int	__kernel_dev_t;
+typedef unsigned int	__kernel_ino_t;
+typedef unsigned int	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned int	__kernel_uid_t;
+typedef unsigned int	__kernel_gid_t;
+typedef unsigned long	__kernel_size_t;
+typedef long		__kernel_ssize_t;
+typedef long		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+	int	val[2];
+} __kernel_fsid_t;
+
+#ifndef __GNUC__
+
+#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+#define	__FD_ISSET(d, set)	((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+#define	__FD_ZERO(set)	\
+  ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set)))
+
+#else /* __GNUC__ */
+
+/* With GNU C, use inline functions instead so args are evaluated only once: */
+
+#undef __FD_SET
+static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
+}
+
+#undef __FD_CLR
+static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
+}
+
+#undef __FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
+{ 
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef __FD_ZERO
+static __inline__ void __FD_ZERO(__kernel_fd_set *p)
+{
+	unsigned int *tmp = p->fds_bits;
+	int i;
+
+	if (__builtin_constant_p(__FDSET_INTS)) {
+		switch (__FDSET_INTS) {
+			case 8:
+				tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
+				tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
+				return;
+		}
+	}
+	i = __FDSET_INTS;
+	while (i) {
+		i--;
+		*tmp = 0;
+		tmp++;
+	}
+}
+
+#endif /* __GNUC__ */
+
+#endif /* _PPc_POSIX_TYPES_H */
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/processor.h linux/include/asm-ppc/processor.h
--- pre2.0.7/linux/include/asm-ppc/processor.h	Fri Apr 12 15:52:05 1996
+++ linux/include/asm-ppc/processor.h	Mon May 27 12:00:59 1996
@@ -87,33 +87,29 @@
 	unsigned long	*pg_tables;	/* MMU information */
 	unsigned long	segs[16];	/* MMU Segment registers */
 	unsigned long	last_pc;	/* PC when last entered system */
+	unsigned long	user_stack;	/* [User] Stack when entered kernel */
 	double		fpr[32];	/* Complete floating point set */
+	unsigned long	wchan;		/* Event task is sleeping on */
+	unsigned long	*regs;		/* Pointer to saved register state */
    };
 
 #define INIT_TSS  { \
-	0, 0, 0, \
-	0, 0, 0, \
-	0, 0, 0, \
+	0, 0, {0}, \
+	0, 0, {0}, \
 }
 
 #define INIT_MMAP { &init_mm, 0, 0x40000000, \
 		      PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC }
 
-
-
+#define alloc_kernel_stack()    get_free_page(GFP_KERNEL)
+#define free_kernel_stack(page) free_page((page))
 
 /*
- * Return saved PC of a blocked thread.  This assumes the frame pointer
- * is the 6th saved long on the kernel stack and that the saved return
- * address is the first long in the frame.  This all holds provided the
- * thread blocked through a call to schedule().
+ * Return saved PC of a blocked thread. For now, this is the "user" PC
  */
 static inline unsigned long thread_saved_pc(struct thread_struct *t)
 {
-	unsigned long fp;
-
-	fp = ((unsigned long*)t->ksp)[6];
-	return *(unsigned long*)fp;
+	return (t->last_pc);
 }
 
 #endif
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/ptrace.h linux/include/asm-ppc/ptrace.h
--- pre2.0.7/linux/include/asm-ppc/ptrace.h	Sat Nov 25 19:49:06 1995
+++ linux/include/asm-ppc/ptrace.h	Mon May 27 12:00:59 1996
@@ -46,7 +46,54 @@
 
 #define instruction_pointer(regs) ((regs)->nip)
 #define user_mode(regs) ((regs)->msr & 0x4000)
+#ifdef KERNEL
 extern void show_regs(struct pt_regs *);
+#endif
+
+/* Offsets used by 'ptrace' system call interface */
+/* Note: these should correspond to gpr[x]        */
+#define PT_R0	0
+#define PT_R1	1
+#define PT_R2	2
+#define PT_R3	3
+#define PT_R4	4
+#define PT_R5	5
+#define PT_R6	6
+#define PT_R7	7
+#define PT_R8	8
+#define PT_R9	9
+#define PT_R10	10
+#define PT_R11	11
+#define PT_R12	12
+#define PT_R13	13
+#define PT_R14	14
+#define PT_R15	15
+#define PT_R16	16
+#define PT_R17	17
+#define PT_R18	18
+#define PT_R19	19
+#define PT_R20	20
+#define PT_R21	21
+#define PT_R22	22
+#define PT_R23	23
+#define PT_R24	24
+#define PT_R25	25
+#define PT_R26	26
+#define PT_R27	27
+#define PT_R28	28
+#define PT_R29	29
+#define PT_R30	30
+#define PT_R31	31
+
+#define PT_NIP	32
+#define PT_MSR	33
+#define PT_ORIG_R3 34
+#define PT_CTR	35
+#define PT_LNK	36
+#define PT_XER	37
+#define PT_CCR	38
+
+#define PT_FPR0	48
 
 #endif
 
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/resource.h linux/include/asm-ppc/resource.h
--- pre2.0.7/linux/include/asm-ppc/resource.h	Sat Nov 25 19:49:06 1995
+++ linux/include/asm-ppc/resource.h	Mon May 27 12:00:59 1996
@@ -2,13 +2,6 @@
 #define _PPC_RESOURCE_H
 
 /*
- * These were swiped from asm-i386 so they don't fit well with the
- * powerstack very well at all.  Anyone want to go through them and
- * correct them?
- *                              -- Cort
- */
-
-/*
  * Resource limits
  */
 
@@ -20,11 +13,25 @@
 #define RLIMIT_RSS	5		/* max resident set size */
 #define RLIMIT_NPROC	6		/* max number of processes */
 #define RLIMIT_NOFILE	7		/* max number of open files */
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
+
+#define RLIM_NLIMITS	9
+
+#ifdef __KERNEL__
 
-#ifdef notdef
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space*/
-#endif
+#define INIT_RLIMITS					\
+{							\
+	{ LONG_MAX, LONG_MAX },				\
+	{ LONG_MAX, LONG_MAX },				\
+	{ LONG_MAX, LONG_MAX },				\
+	{ _STK_LIM, _STK_LIM },				\
+	{        0, LONG_MAX },				\
+	{ LONG_MAX, LONG_MAX },				\
+	{ MAX_TASKS_PER_USER, MAX_TASKS_PER_USER },	\
+	{ NR_OPEN, NR_OPEN },				\
+	{ LONG_MAX, LONG_MAX },				\
+}
 
-#define RLIM_NLIMITS	8
+#endif /* __KERNEL__ */
 
 #endif
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/signal.h linux/include/asm-ppc/signal.h
--- pre2.0.7/linux/include/asm-ppc/signal.h	Fri Mar  1 07:50:56 1996
+++ linux/include/asm-ppc/signal.h	Mon May 27 12:00:59 1996
@@ -60,6 +60,17 @@
 #define SA_NOMASK	0x40000000
 #define SA_ONESHOT	0x80000000
 
+#ifdef __KERNEL__
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ */
+#define SA_PROBE SA_ONESHOT
+#define SA_SAMPLE_RANDOM SA_RESTART
+#endif
+
 #define SIG_BLOCK          0	/* for blocking signals */
 #define SIG_UNBLOCK        1	/* for unblocking signals */
 #define SIG_SETMASK        2	/* for setting the signal mask */
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/socket.h linux/include/asm-ppc/socket.h
--- pre2.0.7/linux/include/asm-ppc/socket.h	Sat Nov 25 19:49:06 1995
+++ linux/include/asm-ppc/socket.h	Mon May 27 12:00:59 1996
@@ -25,6 +25,7 @@
 #define SO_NO_CHECK	11
 #define SO_PRIORITY	12
 #define SO_LINGER	13
+#define SO_BSDCOMPAT	14
 /* To add :#define SO_REUSEPORT 14 */
 
 #endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/sockios.h linux/include/asm-ppc/sockios.h
--- pre2.0.7/linux/include/asm-ppc/sockios.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/sockios.h	Mon May 27 12:00:59 1996
@@ -0,0 +1,17 @@
+#ifndef _ASM_PPC_SOCKIOS_H
+#define _ASM_PPC_SOCKIOS_H
+
+#if 0 /* These are defined this way on Alpha - maybe later. */
+/* Socket-level I/O control calls. */
+
+#define FIOGETOWN	_IOR('f', 123, int)
+#define FIOSETOWN 	_IOW('f', 124, int)
+
+#define SIOCATMARK	_IOR('s', 7, int)
+#define SIOCSPGRP	_IOW('s', 8, pid_t)
+#define SIOCGPGRP	_IOR('s', 9, pid_t)
+
+#define SIOCGSTAMP	0x8906		/* Get stamp - linux-specific */
+#endif
+
+#endif /* _ASM_PPC_SOCKIOS_H */
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/stat.h linux/include/asm-ppc/stat.h
--- pre2.0.7/linux/include/asm-ppc/stat.h	Sat Nov 25 19:49:07 1995
+++ linux/include/asm-ppc/stat.h	Mon May 27 12:00:59 1996
@@ -1,6 +1,8 @@
 #ifndef _PPC_STAT_H
 #define _PPC_STAT_H
 
+#include <linux/types.h>
+
 struct old_stat {
 	unsigned short st_dev;
 	unsigned short st_ino;
@@ -16,26 +18,24 @@
 };
 
 struct new_stat {
-	unsigned short st_dev;
-	unsigned short __pad1;
-	unsigned long st_ino;
-	unsigned short st_mode;
-	unsigned short st_nlink;
-	unsigned short st_uid;
-	unsigned short st_gid;
-	unsigned short st_rdev;
-	unsigned short __pad2;
-	unsigned long  st_size;
-	unsigned long  st_blksize;
-	unsigned long  st_blocks;
-	unsigned long  st_atime;
-	unsigned long  __unused1;
-	unsigned long  st_mtime;
-	unsigned long  __unused2;
-	unsigned long  st_ctime;
-	unsigned long  __unused3;
-	unsigned long  __unused4;
-	unsigned long  __unused5;
+	dev_t		st_dev;
+	ino_t		st_ino;
+	mode_t		st_mode;
+	nlink_t		st_nlink;
+	uid_t 		st_uid;
+	gid_t 		st_gid;
+	dev_t		st_rdev;
+	off_t		st_size;
+	unsigned long  	st_blksize;
+	unsigned long  	st_blocks;
+	unsigned long  	st_atime;
+	unsigned long  	__unused1;
+	unsigned long  	st_mtime;
+	unsigned long  	__unused2;
+	unsigned long  	st_ctime;
+	unsigned long  	__unused3;
+	unsigned long  	__unused4;
+	unsigned long  	__unused5;
 };
 
 #endif
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/system.h linux/include/asm-ppc/system.h
--- pre2.0.7/linux/include/asm-ppc/system.h	Sat Nov 25 19:49:07 1995
+++ linux/include/asm-ppc/system.h	Mon May 27 12:00:59 1996
@@ -19,7 +19,7 @@
 extern void bzero(void *, int);
 
 struct task_struct;
-extern void switch_to(struct task_struct *);
+extern void switch_to(struct task_struct *prev, struct task_struct *next);
 
 #define save_flags(flags) __save_flags(&(flags))
 #define restore_flags(flags) __restore_flags(flags)
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/termbits.h linux/include/asm-ppc/termbits.h
--- pre2.0.7/linux/include/asm-ppc/termbits.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/termbits.h	Mon May 27 12:00:59 1996
@@ -0,0 +1,178 @@
+#ifndef _PPC_TERMBITS_H
+#define _PPC_TERMBITS_H
+
+#include <linux/posix_types.h>
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#if 0 /* This is how it's done on Alpha - maybe later. */
+/*
+ * termios type and macro definitions.  Be careful about adding stuff
+ * to this file since it's used in GNU libc and there are strict rules
+ * concerning namespace pollution.
+ */
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_cc[NCCS];		/* control characters */
+	cc_t c_line;			/* line discipline (== c_cc[19]) */
+	speed_t c_ispeed;		/* input speed */
+	speed_t c_ospeed;		/* output speed */
+};
+
+/* c_cc characters */
+#define VEOF 0
+#define VEOL 1
+#define VEOL2 2
+#define VERASE 3
+#define VWERASE 4
+#define VKILL 5
+#define VREPRINT 6
+#define VSWTC 7
+#define VINTR 8
+#define VQUIT 9
+#define VSUSP 10
+#define VSTART 12
+#define VSTOP 13
+#define VLNEXT 14
+#define VDISCARD 15
+#define VMIN 16
+#define VTIME 17
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IXON	0001000
+#define IXOFF	0002000
+#if !defined(KERNEL) || defined(__USE_BSD)
+  /* POSIX.1 doesn't want these... */
+# define IXANY		0004000
+# define IUCLC		0010000
+# define IMAXBEL	0020000
+#endif
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define ONLCR	0000002
+#define OLCUC	0000004
+
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+
+#define OFILL	00000100
+#define OFDEL	00000200
+#define NLDLY	00001400
+#define   NL0	00000000
+#define   NL1	00000400
+#define   NL2	00001000
+#define   NL3	00001400
+#define TABDLY	00006000
+#define   TAB0	00000000
+#define   TAB1	00002000
+#define   TAB2	00004000
+#define   TAB3	00006000
+#define CRDLY	00030000
+#define   CR0	00000000
+#define   CR1	00010000
+#define   CR2	00020000
+#define   CR3	00030000
+#define FFDLY	00040000
+#define   FF0	00000000
+#define   FF1	00040000
+#define BSDLY	00100000
+#define   BS0	00000000
+#define   BS1	00100000
+#define VTDLY	00200000
+#define   VT0	00000000
+#define   VT1	00200000
+#define XTABS	01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
+
+/* c_cflag bit meaning */
+#define CBAUD	0000017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CBAUDEX 0000020
+#define  B57600   00020
+#define  B115200  00021
+#define  B230400  00022
+
+#define CSIZE	00001400
+#define   CS5	00000000
+#define   CS6	00000400
+#define   CS7	00001000
+#define   CS8	00001400
+
+#define CSTOPB	00002000
+#define CREAD	00004000
+#define PARENB	00010000
+#define PARODD	00020000
+#define HUPCL	00040000
+
+#define CLOCAL	00100000
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0x00000080
+#define ICANON	0x00000100
+#define XCASE	0x00004000
+#define ECHO	0x00000008
+#define ECHOE	0x00000002
+#define ECHOK	0x00000004
+#define ECHONL	0x00000010
+#define NOFLSH	0x80000000
+#define TOSTOP	0x00400000
+#define ECHOCTL	0x00000040
+#define ECHOPRT	0x00000020
+#define ECHOKE	0x00000001
+#define FLUSHO	0x00800000
+#define PENDIN	0x20000000
+#define IEXTEN	0x00000400
+
+/* Values for the ACTION argument to `tcflow'.  */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* Values for the QUEUE_SELECTOR argument to `tcflush'.  */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'.  */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+#endif
+
+#endif /* _PPC_TERMBITS_H */
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/termios.h linux/include/asm-ppc/termios.h
--- pre2.0.7/linux/include/asm-ppc/termios.h	Sat May 11 10:42:07 1996
+++ linux/include/asm-ppc/termios.h	Mon May 27 12:00:59 1996
@@ -1,16 +1,15 @@
 #ifndef _PPC_TERMIOS_H
 #define _PPC_TERMIOS_H
 
-
 /*
- * These were swiped from the alpha termios.h.  These probably aren't
- * correct but we can fix them as we come across problems.
- *                                -- Cort
+ * Liberally adapted from alpha/termios.h.  In particular, the c_cc[]
+ * fields have been reordered so that termio & termios share the
+ * common subset in the same order (for brain dead programs that don't
+ * know or care about the differences).
  */
 
-#include <linux/types.h>
-
-#include <asm/ioctl.h>
+#include <asm/ioctls.h>
+#include <asm/termbits.h>
 
 struct sgttyb {
 	char	sg_ispeed;
@@ -109,6 +108,9 @@
 #define TIOCSERGETMULTI 0x545A /* Get multiport config  */
 #define TIOCSERSETMULTI 0x545B /* Set multiport config */
 
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
 #define TIOCPKT_FLUSHREAD	 1
@@ -125,7 +127,7 @@
 	unsigned short ws_ypixel;
 };
 
-#define NCC 8
+#define NCC 10
 struct termio {
 	unsigned short c_iflag;		/* input mode flags */
 	unsigned short c_oflag;		/* output mode flags */
@@ -148,38 +150,36 @@
 };
 
 /* c_cc characters */
-#define VEOF 0
-#define VEOL 1
-#define VEOL2 2
-#define VERASE 3
-#define VWERASE 4
-#define VKILL 5
-#define VREPRINT 6
-#define VSWTC 7
-#define VINTR 8
-#define VQUIT 9
-#define VSUSP 10
-#define VSTART 12
-#define VSTOP 13
-#define VLNEXT 14
-#define VDISCARD 15
-#define VMIN 16
-#define VTIME 17
-
-/*
- * ..and the same for c_cc in the termio structure.. 
- * Oh, how I love being backwardly compatible.
- */
 #define _VINTR	0
 #define _VQUIT	1
 #define _VERASE	2
 #define _VKILL	3
 #define _VEOF	4
-#define _VMIN	4
-#define _VEOL	5
-#define _VTIME	5
-#define _VEOL2	6
-#define _VSWTC	7
+#define _VMIN	5
+#define _VEOL	6
+#define _VTIME	7
+#define _VEOL2	8
+#define _VSWTC	9
+
+#define VINTR 	0
+#define VQUIT 	1
+#define VERASE 	2
+#define VKILL	3
+#define VEOF	4
+#define VMIN	5
+#define VEOL	6
+#define VTIME	7
+#define VEOL2	8
+#define VSWTC	9
+
+#define VWERASE 	10
+#define VREPRINT	11
+#define VSUSP 		12
+#define VSTART		13
+#define VSTOP		14
+#define VLNEXT		15
+#define VDISCARD	16
+
 
 #ifdef __KERNEL__
 /*	eof=^D		eol=\0		eol2=\0		erase=del
@@ -187,8 +187,11 @@
 	intr=^C		quit=^\		susp=^Z		<OSF/1 VDSUSP>
 	start=^Q	stop=^S		lnext=^V	discard=^U
 	vmin=\1		vtime=\0
-*/
 #define INIT_C_CC "\004\000\000\177\027\025\022\000\003\034\032\000\021\023\026\025\001\000"
+*/
+
+/*                   ^C  ^\ del  ^U  ^D   1   0   0   0   0  ^W  ^R  ^Z  ^Q  ^S  ^V  ^U  */
+#define INIT_C_CC "\003\034\177\025\004\001\000\000\000\000\027\022\032\021\023\026\025" 
 #endif
 
 /* c_iflag bits */
@@ -388,7 +391,7 @@
 	termio->c_cc[_VEOL]  = termios->c_cc[VEOL];
 	termio->c_cc[_VEOL2] = termios->c_cc[VEOL2];
 	termio->c_cc[_VSWTC] = termios->c_cc[VSWTC];
-	if (!(termios->c_lflag & ICANON)) {
+	if (1/*!(termios->c_lflag & ICANON)*/) {
 		termio->c_cc[_VMIN]  = termios->c_cc[VMIN];
 		termio->c_cc[_VTIME] = termios->c_cc[VTIME];
 	}
@@ -396,4 +399,4 @@
 
 #endif	/* __KERNEL__ */
 
-#endif	/* _ALPHA_TERMIOS_H */
+#endif	/* _PPC_TERMIOS_H */
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/types.h linux/include/asm-ppc/types.h
--- pre2.0.7/linux/include/asm-ppc/types.h	Sat Nov 25 19:49:07 1995
+++ linux/include/asm-ppc/types.h	Mon May 27 12:00:59 1996
@@ -1,41 +1,7 @@
 #ifndef _PPC_TYPES_H
 #define _PPC_TYPES_H
 
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef int ssize_t;
-#endif
-
-#ifndef _PTRDIFF_T
-#define _PTRDIFF_T
-typedef int ptrdiff_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-
-typedef int pid_t;
-typedef unsigned int uid_t;
-typedef unsigned int gid_t;
-typedef unsigned int dev_t;
-typedef unsigned int ino_t;
-typedef unsigned int mode_t;
-typedef unsigned int umode_t;
-typedef unsigned short nlink_t;
-typedef int daddr_t;
-typedef long off_t;
+typedef unsigned short umode_t;
 
 /*
  * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
@@ -48,8 +14,8 @@
 typedef __signed__ short __s16;
 typedef unsigned short __u16;
 
-typedef __signed__ long __s32;
-typedef unsigned long __u32;
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
 
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
 typedef __signed__ long long __s64;
@@ -67,62 +33,12 @@
 typedef signed short s16;
 typedef unsigned short u16;
 
-typedef signed long s32;
-typedef unsigned long u32;
+typedef signed int s32;
+typedef unsigned int u32;
 
 typedef signed long long s64;
 typedef unsigned long long u64;
 
 #endif /* __KERNEL__ */
-
-#undef __FD_SET
-static __inline__ void __FD_SET(unsigned long fd, fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long fd, fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long fd, fd_set *p)
-{ 
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef __FD_ZERO
-static __inline__ void __FD_ZERO(fd_set *p)
-{
-	unsigned int *tmp = p->fds_bits;
-	int i;
-
-	if (__builtin_constant_p(__FDSET_INTS)) {
-		switch (__FDSET_INTS) {
-			case 8:
-				tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
-				tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
-				return;
-		}
-	}
-	i = __FDSET_INTS;
-	while (i) {
-		i--;
-		*tmp = 0;
-		tmp++;
-	}
-}
 
 #endif
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/unistd.h linux/include/asm-ppc/unistd.h
--- pre2.0.7/linux/include/asm-ppc/unistd.h	Sat Nov 25 19:49:07 1995
+++ linux/include/asm-ppc/unistd.h	Mon May 27 12:00:59 1996
@@ -257,6 +257,14 @@
  * won't be any messing with the stack from main(), but we define
  * some others too.
  */
+
+extern long __kernel_thread(unsigned long, int (*)(void *), void *);
+
+static inline long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	return __kernel_thread(flags | CLONE_VM, fn, arg);
+}
+ 
 /*
    some of these had problems getting the right arguments (namely sys_clone())
    when they were inline.
diff -u --recursive --new-file pre2.0.7/linux/include/asm-ppc/user.h linux/include/asm-ppc/user.h
--- pre2.0.7/linux/include/asm-ppc/user.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/user.h	Mon May 27 12:00:59 1996
@@ -0,0 +1,52 @@
+#ifndef _PPC_USER_H
+#define _PPC_USER_H
+
+/* Adapted from <asm-alpha/user.h> */
+
+#include <linux/ptrace.h>
+#include <asm/page.h>
+
+/*
+ * Core file format: The core file is written in such a way that gdb
+ * can understand it and provide useful information to the user (under
+ * linux we use the `trad-core' bfd, NOT the osf-core).  The file contents
+ * are as follows:
+ *
+ *  upage: 1 page consisting of a user struct that tells gdb
+ *	what is present in the file.  Directly after this is a
+ *	copy of the task_struct, which is currently not used by gdb,
+ *	but it may come in handy at some point.  All of the registers
+ *	are stored as part of the upage.  The upage should always be
+ *	only one page long.
+ *  data: The data segment follows next.  We use current->end_text to
+ *	current->brk to pick up all of the user variables, plus any memory
+ *	that may have been sbrk'ed.  No attempt is made to determine if a
+ *	page is demand-zero or if a page is totally unused, we just cover
+ *	the entire range.  All of the addresses are rounded in such a way
+ *	that an integral number of pages is written.
+ *  stack: We need the stack information in order to get a meaningful
+ *	backtrace.  We need to write the data from usp to
+ *	current->start_stack, so we round each of these in order to be able
+ *	to write an integer number of pages.
+ */
+struct user {
+	struct pt_regs	regs;			/* entire machine state */
+	size_t		u_tsize;		/* text size (pages) */
+	size_t		u_dsize;		/* data size (pages) */
+	size_t		u_ssize;		/* stack size (pages) */
+	unsigned long	start_code;		/* text starting address */
+	unsigned long	start_data;		/* data starting address */
+	unsigned long	start_stack;		/* stack starting address */
+	long int	signal;			/* signal causing core dump */
+	struct regs *	u_ar0;			/* help gdb find registers */
+	unsigned long	magic;			/* identifies a core file */
+	char		u_comm[32];		/* user command name */
+};
+
+#define NBPG			PAGE_SIZE
+#define UPAGES			1
+#define HOST_TEXT_START_ADDR	(u.start_code)
+#define HOST_DATA_START_ADDR	(u.start_data)
+#define HOST_STACK_END_ADDR	(u.start_stack + u.u_ssize * NBPG)
+
+#endif /* _PPC_USER_H */
diff -u --recursive --new-file pre2.0.7/linux/include/asm-sparc/floppy.h linux/include/asm-sparc/floppy.h
--- pre2.0.7/linux/include/asm-sparc/floppy.h	Sat May 11 10:42:07 1996
+++ linux/include/asm-sparc/floppy.h	Mon May 27 13:16:02 1996
@@ -282,6 +282,8 @@
 	char state[128];
 	int tnode, fd_node, num_regs;
 
+	use_virtual_dma = 1;
+	
 	FLOPPY_IRQ = 11;
 	/* Forget it if we aren't on a machine that could possibly
 	 * ever have a floppy drive.
diff -u --recursive --new-file pre2.0.7/linux/include/linux/elf.h linux/include/linux/elf.h
--- pre2.0.7/linux/include/linux/elf.h	Fri Sep  1 16:21:05 1995
+++ linux/include/linux/elf.h	Mon May 27 12:00:59 1996
@@ -36,6 +36,7 @@
 #define EM_88K   5
 #define EM_486   6   /* Perhaps disused */
 #define EM_860   7
+#define EM_PPC   20
 
 /* This is the info that is needed to parse the dynamic section of the file */
 #define DT_NULL		0
diff -u --recursive --new-file pre2.0.7/linux/include/linux/fs.h linux/include/linux/fs.h
--- pre2.0.7/linux/include/linux/fs.h	Fri May 17 15:32:18 1996
+++ linux/include/linux/fs.h	Mon May 27 15:05:33 1996
@@ -272,7 +272,7 @@
 	uid_t		i_uid;
 	gid_t		i_gid;
 	kdev_t		i_rdev;
-	unsigned long	i_size;
+	off_t		i_size;
 	time_t		i_atime;
 	time_t		i_mtime;
 	time_t		i_ctime;
diff -u --recursive --new-file pre2.0.7/linux/include/linux/pci.h linux/include/linux/pci.h
--- pre2.0.7/linux/include/linux/pci.h	Sun Apr 21 12:39:03 1996
+++ linux/include/linux/pci.h	Mon May 27 14:01:04 1996
@@ -547,6 +547,9 @@
 #define PCI_DEVICE_ID_INTEL_82437	0x122d
 #define PCI_DEVICE_ID_INTEL_82371_0	0x122e
 #define PCI_DEVICE_ID_INTEL_82371_1	0x1230
+#define PCI_DEVICE_ID_INTEL_82439	0x1250
+#define PCI_DEVICE_ID_INTEL_82371SB_0	0x7000
+#define PCI_DEVICE_ID_INTEL_82371SB_1	0x7010
 #define PCI_DEVICE_ID_INTEL_P6		0x84c4
 
 #define PCI_VENDOR_ID_ADAPTEC		0x9004
diff -u --recursive --new-file pre2.0.7/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c
--- pre2.0.7/linux/net/ipv4/ip_fw.c	Tue May 21 19:52:39 1996
+++ linux/net/ipv4/ip_fw.c	Mon May 27 14:06:17 1996
@@ -210,7 +210,7 @@
 	__u32			src, dst;
 	__u16			src_port=0xFFFF, dst_port=0xFFFF, icmp_type=0xFF;
 	unsigned short		f_prt=0, prt;
-	char			notcpsyn=1, notcpack=1, match;
+	char			notcpsyn=0, notcpack=0, match;
 	unsigned short		offset;
 	int			answer;
 	unsigned char		tosand, tosxor;
@@ -289,12 +289,12 @@
 			if (!offset) {
 				src_port=ntohs(tcp->source);
 				dst_port=ntohs(tcp->dest);
-				if(tcp->ack)
-					/* We *DO* have ACK, value FALSE */
-					notcpack=0;
-				if(tcp->syn && notcpack)
-					/* We *DO* have SYN, value FALSE */
-					notcpsyn=0;
+				if(!tcp->ack)
+					/* We do NOT have ACK, value TRUE */
+					notcpack=1;
+				if(!tcp->syn || !notcpack)
+					/* We do NOT have SYN, value TRUE */
+					notcpsyn=1;
 			}
 			prt=IP_FW_F_TCP;
 			break;
@@ -401,22 +401,22 @@
 			continue;
 
 #endif
+		/*
+		 * For all non-TCP packets and/or non-first fragments,
+		 * notcpsyn and notcpack will always be FALSE,
+		 * so the IP_FW_F_TCPSYN and IP_FW_F_TCPACK flags
+		 * are actually ignored for these packets.
+		 */
+		 
+		if((f->fw_flg&IP_FW_F_TCPSYN) && notcpsyn)
+		 	continue;
+
+		if((f->fw_flg&IP_FW_F_TCPACK) && notcpack)
+		 	continue;
+
 		f_prt=f->fw_flg&IP_FW_F_KIND;
 		if (f_prt!=IP_FW_F_ALL) 
 		{
-			/*
-			 * This is actually buggy as if you set ACK/SYN flags
-			 * on UDP or ICMP firewall it will never work,but 
-			 * actually it is a concern of software which sets
-			 * firewall entries.
-			 */
-			 
-			if((f->fw_flg&IP_FW_F_TCPSYN) && notcpsyn)
-			 	continue;
-
-			if((f->fw_flg&IP_FW_F_TCPACK) && notcpack)
-			 	continue;
-
 			/*
 			 *	Specific firewall - packet's protocol
 			 *	must match firewall's.
diff -u --recursive --new-file pre2.0.7/linux/net/ipv4/route.c linux/net/ipv4/route.c
--- pre2.0.7/linux/net/ipv4/route.c	Tue May 21 19:52:40 1996
+++ linux/net/ipv4/route.c	Mon May 27 13:09:06 1996
@@ -604,7 +604,8 @@
 		 *	but less metric. We'll delete it 
 		 *	after instantiation of new route.
 		 */
-		if (f1->fib_info->fib_gateway == gw)
+		if (f1->fib_info->fib_gateway == gw &&
+		    (gw || f1->fib_info->fib_dev == dev))
 			dup_fp = fp;
 		fp = &f1->fib_next;
 	}
@@ -643,7 +644,8 @@
 
 	while ((f1 = *fp) != NULL && f1->fib_dst == dst)
 	{
-		if (f1->fib_info->fib_gateway == gw)
+		if (f1->fib_info->fib_gateway == gw &&
+		    (gw || f1->fib_info->fib_dev == dev))
 		{
 			cli();
 			*fp = f1->fib_next;
