]> git.neil.brown.name Git - history.git/commitdiff
Import pre2.0.8 pre2.0.8
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:11:03 +0000 (15:11 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:11:03 +0000 (15:11 -0500)
107 files changed:
CREDITS
Documentation/Changes
Documentation/Configure.help
Documentation/networking/arcnet.txt
Makefile
arch/m68k/amiga/cyberfb.c
arch/ppc/Makefile
arch/ppc/boot/Makefile
arch/ppc/boot/compressed/Makefile [new file with mode: 0644]
arch/ppc/boot/compressed/crypt.h [new file with mode: 0644]
arch/ppc/boot/compressed/gzip.h [new file with mode: 0644]
arch/ppc/boot/compressed/head.S [new file with mode: 0644]
arch/ppc/boot/compressed/inflate.c [new file with mode: 0644]
arch/ppc/boot/compressed/lzw.h [new file with mode: 0644]
arch/ppc/boot/compressed/misc.c [new file with mode: 0644]
arch/ppc/boot/compressed/piggyback.c [new file with mode: 0644]
arch/ppc/boot/compressed/ppc_defs.h [new file with mode: 0644]
arch/ppc/boot/compressed/unzip.c [new file with mode: 0644]
arch/ppc/boot/mk_type41.c [new file with mode: 0644]
arch/ppc/config.in
arch/ppc/kernel/Makefile
arch/ppc/kernel/head.S
arch/ppc/kernel/include/elf/ChangeLog [new file with mode: 0644]
arch/ppc/kernel/include/elf/common.h [new file with mode: 0644]
arch/ppc/kernel/include/elf/dwarf.h [new file with mode: 0644]
arch/ppc/kernel/include/elf/external.h [new file with mode: 0644]
arch/ppc/kernel/include/elf/hppa.h [new file with mode: 0644]
arch/ppc/kernel/include/elf/internal.h [new file with mode: 0644]
arch/ppc/kernel/include/elf/mips.h [new file with mode: 0644]
arch/ppc/kernel/include/elf/ppc.h [new file with mode: 0644]
arch/ppc/kernel/irq.c
arch/ppc/kernel/ksyms.c [new file with mode: 0644]
arch/ppc/kernel/ld.script-user
arch/ppc/kernel/misc.S
arch/ppc/kernel/mk_defs.c
arch/ppc/kernel/mkboot.c
arch/ppc/kernel/mmu.h
arch/ppc/kernel/no_ramdisk.S [new file with mode: 0644]
arch/ppc/kernel/pci.c
arch/ppc/kernel/port_io.c
arch/ppc/kernel/ppc_asm.tmpl
arch/ppc/kernel/ppc_defs.h
arch/ppc/kernel/ppc_machine.h [new file with mode: 0644]
arch/ppc/kernel/process.c
arch/ppc/kernel/ptrace.c [new file with mode: 0644]
arch/ppc/kernel/ramdisk_drvr.c [new file with mode: 0644]
arch/ppc/kernel/raw_printf.c
arch/ppc/kernel/setup.c
arch/ppc/kernel/signal.c
arch/ppc/kernel/stubs.c
arch/ppc/kernel/support.c [new file with mode: 0644]
arch/ppc/kernel/syscalls.c [new file with mode: 0644]
arch/ppc/kernel/time.c [new file with mode: 0644]
arch/ppc/kernel/traps.c
arch/ppc/ld.script
arch/ppc/lib/Makefile [new file with mode: 0644]
arch/ppc/lib/checksum.c [new file with mode: 0644]
arch/ppc/lib/cksum_support.S [new file with mode: 0644]
arch/ppc/mm/Makefile
arch/ppc/mm/fault.c
arch/ppc/mm/init.c
arch/ppc/mm/mmu.h
drivers/block/floppy.c
drivers/block/ide.c
drivers/cdrom/mcdx.c
drivers/net/de4x5.c
drivers/net/loopback.c
drivers/net/new_tunnel.c
drivers/pci/pci.c
drivers/scsi/seagate.c
drivers/scsi/seagate.h
drivers/sound/Readme.linux
fs/open.c
include/asm-ppc/atomic.h [new file with mode: 0644]
include/asm-ppc/bitops.h
include/asm-ppc/dma.h
include/asm-ppc/errno.h
include/asm-ppc/floppy.h [new file with mode: 0644]
include/asm-ppc/ioctls.h [new file with mode: 0644]
include/asm-ppc/irq.h
include/asm-ppc/mc146818rtc.h [new file with mode: 0644]
include/asm-ppc/mman.h
include/asm-ppc/mmu.h
include/asm-ppc/mmu_context.h [new file with mode: 0644]
include/asm-ppc/nvram.h [new file with mode: 0644]
include/asm-ppc/page.h
include/asm-ppc/pgtable.h
include/asm-ppc/posix_types.h [new file with mode: 0644]
include/asm-ppc/processor.h
include/asm-ppc/ptrace.h
include/asm-ppc/resource.h
include/asm-ppc/signal.h
include/asm-ppc/socket.h
include/asm-ppc/sockios.h [new file with mode: 0644]
include/asm-ppc/stat.h
include/asm-ppc/system.h
include/asm-ppc/termbits.h [new file with mode: 0644]
include/asm-ppc/termios.h
include/asm-ppc/types.h
include/asm-ppc/unistd.h
include/asm-ppc/user.h [new file with mode: 0644]
include/asm-sparc/floppy.h
include/linux/elf.h
include/linux/fs.h
include/linux/pci.h
net/ipv4/ip_fw.c
net/ipv4/route.c

diff --git a/CREDITS b/CREDITS
index 8836e147b02dab0e3a8b718779d0c9b5f44f94a3..6657d0167be7c6ca7f72b63fbb677a842fa22c8e 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -163,6 +163,12 @@ S: Bessemerstraat 21
 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 @@ E: ajh@primag.co.uk
 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 @@ D: Credit file compilator
 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
index a83a76e92baa5e5788b034ce8ba8b07f09e775a0..f788f884a7998d99cc7c4c15b1b9da675a730c48 100644 (file)
@@ -373,12 +373,12 @@ to me.
 
 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
 *************************************************
index ae7d3ec1046e035eb9ebe00def56b23781096381..5d59c309f525848e9f04c3cab05c6d62b4e4bc2d 100644 (file)
@@ -1086,7 +1086,7 @@ CONFIG_AX25
   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 @@ CONFIG_CS4232
 /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
index 551841d393d354d9ebaa56df06a3b015960d4908..c8bf5315b5f21f0740673ad94fdc3c3bffea24f7 100644 (file)
@@ -55,13 +55,8 @@ included and seems to be working fine!
 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 @@ Windows 95: Tools are included with Win95 that let you use either the LANMAN
        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 @@ can set up your network then:
    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.
 
index 3599b83c7afa566799aa999fd0e035ab1d9bad08..b3ba1c4638f181c3a246eed8263c8deb527a813a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 99
-SUBLEVEL = 7
+SUBLEVEL = 8
 
 ARCH = i386
 
@@ -225,7 +225,7 @@ include/linux/compile.h: $(CONFIGURATION) include/linux/version.h newversion
         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
index 6011cf90850fe5c88b8eedc3bc4e6914f7def1fb..9d24b227837286995a5e3c93026acd63f132fd25 100644 (file)
@@ -565,7 +565,7 @@ return (0);
 
 
    /*
-    *    (Unb)Blank the screen
+    *    (Un)Blank the screen
     */
 
 void Cyber_blank(int blank)
@@ -663,7 +663,7 @@ Cyber_WaitQueue (0x8000);
 }
 
 /**************************************************************
- * 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)
index e21c627df8d9447aa7d3b27d2e579090308a0e80..3f75e23a6ae70dc35440e9656b5916be54347f70 100644 (file)
 #
 # 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 @@ NM          = /u/cort/ppc-gcc/bin/nm.ppc
 
 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/kernel: dummy
 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
-
-
index c7b4a2f215195d93bda7e3d7042e82ba979ff9ee..2d1177579af634e8d0092d49c001097af3df270d 100644 (file)
@@ -24,14 +24,48 @@ OBJECTS = head.o main.o
 
 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 --git a/arch/ppc/boot/compressed/Makefile b/arch/ppc/boot/compressed/Makefile
new file mode 100644 (file)
index 0000000..665fddc
--- /dev/null
@@ -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 --git a/arch/ppc/boot/compressed/crypt.h b/arch/ppc/boot/compressed/crypt.h
new file mode 100644 (file)
index 0000000..2a4c203
--- /dev/null
@@ -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 --git a/arch/ppc/boot/compressed/gzip.h b/arch/ppc/boot/compressed/gzip.h
new file mode 100644 (file)
index 0000000..2f738b9
--- /dev/null
@@ -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 --git a/arch/ppc/boot/compressed/head.S b/arch/ppc/boot/compressed/head.S
new file mode 100644 (file)
index 0000000..6cd9282
--- /dev/null
@@ -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 --git a/arch/ppc/boot/compressed/inflate.c b/arch/ppc/boot/compressed/inflate.c
new file mode 100644 (file)
index 0000000..848fef6
--- /dev/null
@@ -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 --git a/arch/ppc/boot/compressed/lzw.h b/arch/ppc/boot/compressed/lzw.h
new file mode 100644 (file)
index 0000000..4e640f5
--- /dev/null
@@ -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 --git a/arch/ppc/boot/compressed/misc.c b/arch/ppc/boot/compressed/misc.c
new file mode 100644 (file)
index 0000000..73f06c2
--- /dev/null
@@ -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 --git a/arch/ppc/boot/compressed/piggyback.c b/arch/ppc/boot/compressed/piggyback.c
new file mode 100644 (file)
index 0000000..ab1502d
--- /dev/null
@@ -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 --git a/arch/ppc/boot/compressed/ppc_defs.h b/arch/ppc/boot/compressed/ppc_defs.h
new file mode 100644 (file)
index 0000000..2237e9f
--- /dev/null
@@ -0,0 +1,6 @@
+#define r0 0
+#define r1 1
+#define r2 2
+#define r3 3
+#define r4 4
+#define r5 5
diff --git a/arch/ppc/boot/compressed/unzip.c b/arch/ppc/boot/compressed/unzip.c
new file mode 100644 (file)
index 0000000..d4a6617
--- /dev/null
@@ -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 --git a/arch/ppc/boot/mk_type41.c b/arch/ppc/boot/mk_type41.c
new file mode 100644 (file)
index 0000000..aeb574c
--- /dev/null
@@ -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 );
+}
+
index 813fd20368a9d5de9b3e89697b502d1d2ebc54f0..bf436ceebd08406598ca0e0669d8e0a6ed011612 100644 (file)
 # 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
+endmenu
 
-comment 'character devices'
+mainmenu_option next_comment
+comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
 
-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
+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
-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
-
+endmenu
 
-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
+source fs/Config.in
 
-comment '>>> Edit configuration parameters in ./include/linux/tpqic02.h!'
-
-else
-
-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/'
-
-fi
-fi
-
-bool 'QIC-117 tape support' CONFIG_FTAPE n
-if [ "$CONFIG_FTAPE" = "y" ]; then
-  int ' number of ftape buffers' NR_FTAPE_BUFFERS 3
-fi
+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
index 3566f96c0fe4bc3ba7a0c5a5172defcce88d53e7..7bcf3664507ae1908cf2ebf0745e940d3dd5f8ef 100644 (file)
@@ -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 $<
 #      $(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:
 
index ba82353f22d684aebb0ea8adf2c890ad7be04589..838eb8a0a8fc67cfc8726337437807c4202af133 100644 (file)
@@ -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); \
        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) \
 
 /* 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; \
 
 /* 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; \
        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); \
        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 */ \
        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 */ \
        mtspr   SRR1,r2; \
        SYNC(); \
        rfi; \
-20:   SAVE_REGS(mark); \
+20:    SAVE_REGS(mark); \
        CHECK_STACK()
 
 #define RETURN_FROM_INT(mark) \
        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; \
 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 */ \
        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 @@ _ORG(0x0C00)
        b       SystemCall
 
 _ORG(0x0D00)
-DEFAULT_TRAP(0x0D00)   
+       b       SingleStep
+
 _ORG(0x0E00)
 DEFAULT_TRAP(0x0E00)   
 _ORG(0x0F00)
@@ -649,7 +708,7 @@ _ORG(0x1500)
  * 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 @@ cache_flush_buffer:
 _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 @@ Reset:
        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 @@ DO_RFI_TRACE_UNMAPPED(0xDEAD0000)
 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(0xDEAD0100)
 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 @@ DO_RFI_TRACE_UNMAPPED(0xDEAD0400)
        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 @@ DO_RFI_TRACE_UNMAPPED(0xDEAD0500)
        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,10 +922,80 @@ DO_RFI_TRACE_MAPPED(0xDEAD0600)
        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)
  */
@@ -846,25 +1010,30 @@ MachineCheck:
  * 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)
 
 /*
@@ -897,6 +1066,19 @@ ProgramCheck:
        bl      _EXTERN(ProgramCheckException)
        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]
  */
@@ -909,8 +1091,9 @@ FloatingPointCheck:
 
 /*
  * 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 @@ SystemCall:
        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 @@ SystemCall:
        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 @@ InstructionFetchError:
        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 @@ WriteProtectError:
        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 @@ _GLOBAL(flush_instruction_cache)
        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 @@ _GLOBAL(flush_data_cache)
        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 @@ _GLOBAL(_switch)
        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 @@ _GLOBAL(_switch)
 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 @@ check_trace:
 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_DATA: .space 128*1024
 _RFI_ptr:  .long       _RFI_DATA
        .text   
 #endif
+
diff --git a/arch/ppc/kernel/include/elf/ChangeLog b/arch/ppc/kernel/include/elf/ChangeLog
new file mode 100644 (file)
index 0000000..4573e49
--- /dev/null
@@ -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>
+
+\f
+Local Variables:
+version-control: never
+End:
diff --git a/arch/ppc/kernel/include/elf/common.h b/arch/ppc/kernel/include/elf/common.h
new file mode 100644 (file)
index 0000000..a9bce87
--- /dev/null
@@ -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 --git a/arch/ppc/kernel/include/elf/dwarf.h b/arch/ppc/kernel/include/elf/dwarf.h
new file mode 100644 (file)
index 0000000..bc9723a
--- /dev/null
@@ -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 --git a/arch/ppc/kernel/include/elf/external.h b/arch/ppc/kernel/include/elf/external.h
new file mode 100644 (file)
index 0000000..f2ab63e
--- /dev/null
@@ -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 --git a/arch/ppc/kernel/include/elf/hppa.h b/arch/ppc/kernel/include/elf/hppa.h
new file mode 100644 (file)
index 0000000..e3f70d2
--- /dev/null
@@ -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 --git a/arch/ppc/kernel/include/elf/internal.h b/arch/ppc/kernel/include/elf/internal.h
new file mode 100644 (file)
index 0000000..fb63029
--- /dev/null
@@ -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 --git a/arch/ppc/kernel/include/elf/mips.h b/arch/ppc/kernel/include/elf/mips.h
new file mode 100644 (file)
index 0000000..f6beff7
--- /dev/null
@@ -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
+\f
+/* 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
+\f
+/* 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 *));
+\f
+/* Processor specific section flags.  */
+
+/* This section must be in the global data area.  */
+#define SHF_MIPS_GPREL         0x10000000
+\f
+/* Processor specific program header types.  */
+
+/* Register usage information.  Identifies one .reginfo section.  */
+#define PT_MIPS_REGINFO                0x70000000
+\f
+/* 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 --git a/arch/ppc/kernel/include/elf/ppc.h b/arch/ppc/kernel/include/elf/ppc.h
new file mode 100644 (file)
index 0000000..b4907ac
--- /dev/null
@@ -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 */
index 1670a5db06c02464d6b38dc6f4886d6c60e92044..4bf3a992e95815d5bfc410eeb02df3e1808499dd 100644 (file)
 #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 @@ void disable_irq(unsigned int irq_nr)
        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 @@ void enable_irq(unsigned int irq_nr)
        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};
+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 irqaction *irq_action[16] = {
-         NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL,
-         NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL
+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 @@ asmlinkage void handle_IRQ(struct pt_regs *regs)
  * 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 @@ void check_irq(void )
        _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 @@ _printk("Request IRQ #%d, Handler: %x\n", irq, handler);
 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 @@ void free_irq(unsigned int irq, void *dev_id)
                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 @@ unsigned /*int*/ long probe_irq_on (void)
        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 @@ int probe_irq_off (unsigned /*int*/ long irqs)
                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 @@ void init_IRQ(void)
                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;
-} 
-
-PCI_irq(int irq)
+}
+
+void
+BeBox_disable_irq(int irq)
+{
+       /* Note: this clears the particular bit */
+       *CPU0_INT_MASK = BeBox_IRQ_map[irq-16];
+}
+
+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 --git a/arch/ppc/kernel/ksyms.c b/arch/ppc/kernel/ksyms.c
new file mode 100644 (file)
index 0000000..a0d3ec6
--- /dev/null
@@ -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);
+}
+
index d883fea4006acc4d0cd7e4a7a31fe85d10bd1716..910d34ad3eaff8d7e8311704e07b9b069dd5890a 100644 (file)
@@ -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
index 0d7041ff436ddedd887c1f0b543b6b8de1abc50c..7d4f5859630b6dbbc10702ac5f3377741dacf98c 100644 (file)
@@ -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 @@ _GLOBAL(_disable_interrupts)
        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(_disable_interrupts)
 _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 @@ _GLOBAL(__save_flags)
  *     __restore_flags(long val)
  */
 _GLOBAL(__restore_flags)
+       sync                    /* Some chip revs have problems here... */
        mtmsr   r3
        isync
        blr
@@ -87,6 +90,7 @@ _GLOBAL(cli)
        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(cli)
 _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(_tlbia)
 _GLOBAL(_tlbie)
        tlbie   r3
        BUMP(__TLBIEs)
+       blr
+
+/*
+ * Fetch the current SR register
+ *   get_SR(int index)
+ */
+_GLOBAL(get_SR)
+       mfsrin  r3,r3
        blr     
 
 /*
@@ -130,6 +143,52 @@ _GLOBAL(xchg_u32)
        bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
        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)
@@ -177,6 +236,29 @@ _GLOBAL(end_bh_atomic)
        bne-    10b
        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)
  *{
@@ -281,6 +363,7 @@ _GLOBAL(find_next_zero_bit)
        bgt     20b
 90:    mr      r3,r5           /* Compute result */    
        blr
+#endif
  
 /*
  *
@@ -371,100 +454,36 @@ _GLOBAL(abs)
        neg     r3,r3
 10:    blr
 
-/*
- * Compute IP checksums
- *   _ip_fast_csum(buf, len) -- Optimized for IP header
- *   _ip_compute_csum(buf, len)
- */
+_GLOBAL(_get_SP)
+       mr      r3,r1           /* Close enough */
+       blr
 
-_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_SDR1)
+       mfspr   r3,SDR1
        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_SRx)
+       mfsrin  r3,r3
        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_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 @@ sys_call_table:
        .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 @@ sys_call_table:
        .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
index 14a764531352de7ad83597ef7b7f9167fad24352..e643614403923c0e5d4f06a5b8e6e159eed55991 100644 (file)
@@ -28,7 +28,7 @@ main(int argc, char *argv[])
        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 @@ main(int argc, char *argv[])
        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);
index d48d19f3a32579a7fa8dc3226d678966626443ff..535e342577c5fe99e4ca1a275fac840b950e4a41 100644 (file)
+/*
+ * 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
+
 
index 695dc1fc99b62c37dbb40fffa89dd167a2e62118..b63ea0e6a1f5b8abeaef61f3301d088081ecc199 100644 (file)
@@ -29,6 +29,7 @@ typedef struct _PTE
 #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 --git a/arch/ppc/kernel/no_ramdisk.S b/arch/ppc/kernel/no_ramdisk.S
new file mode 100644 (file)
index 0000000..849ac14
--- /dev/null
@@ -0,0 +1,6 @@
+       .data
+       .globl builtin_ramdisk_image
+builtin_ramdisk_image:
+       .globl builtin_ramdisk_size
+builtin_ramdisk_size:  .long   0
+
index 1e4901cc8e0092b5e70b4bad4b3f94e09606c6cf..ff50a6c5e6447ef5b1f7d205fd9c33ce4e0233fb 100644 (file)
@@ -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>
 #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 @@ unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end)
   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 @@ unsigned short
 _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 @@ int
 pcibios_present (void)
 {
 #ifdef PCI_DEBUG       
-       _printk("PCI [BIOS] present?\n");
+       printk("PCI [BIOS] present?\n");
 #endif 
        return (1);
 }
@@ -57,7 +200,7 @@ pcibios_read_config_dword (unsigned char bus,
        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 @@ pcibios_read_config_dword (unsigned char bus,
        {
                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 @@ pcibios_read_config_word (unsigned char bus,
        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 @@ pcibios_read_config_byte (unsigned char bus,
     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 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);
+       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 @@ pcibios_write_config_dword (unsigned char bus,
        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 @@ pcibios_write_config_word (unsigned char bus,
        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 @@ pcibios_write_config_byte (unsigned char bus,
        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 @@ pcibios_find_device (unsigned short vendor, unsigned short device_id,
                     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 @@ int
 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;
+} 
index 069dad4ce0e13682ad4a5fa72375530eb09e7cb1..3693112b2009dc32a8573431dc25379ae4491497 100644 (file)
@@ -24,6 +24,41 @@ inl(int port)
        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);
@@ -58,6 +93,41 @@ outl(unsigned long val,int port)
        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)
 {
        unsigned long *io_ptr = (unsigned long *)(_IO_BASE+port);
index 83125197d81137b018b54bd7dbd42b1b7976f064..aece3d5f8c353da2b626f6266648fa86824e84a9 100644 (file)
@@ -165,7 +165,4 @@ n:
 /* Missing instructions */
 #define bdne   bc 0,2,
 
-#include <asm/ppc_machine.h>
-
-
-
+#include "ppc_machine.h"
index d92b6f4c71657334708ae4ee859b3c8899b013d9..1965f83e130e71da2e44301ce58c69ab318fab82 100644 (file)
@@ -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 --git a/arch/ppc/kernel/ppc_machine.h b/arch/ppc/kernel/ppc_machine.h
new file mode 100644 (file)
index 0000000..8bdb2bf
--- /dev/null
@@ -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
index 5876539bb75687eb6ed681793690cccf7e31983a..f75b65d3d7e17697a605bbbbfd760444f1df8fad 100644 (file)
@@ -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
  */
 
 /*
 #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 flush_thread(void)
 {
 }
 
+void
+release_thread(struct task_struct *t)
+{
+}
+
 /*
  * Copy a thread..
  */
@@ -101,17 +103,26 @@ void copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
        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 @@ void copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
                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 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
 {
 }
 
-#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 @@ asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
        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 @@ print_backtrace(void)
        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 --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c
new file mode 100644 (file)
index 0000000..dc4012f
--- /dev/null
@@ -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 --git a/arch/ppc/kernel/ramdisk_drvr.c b/arch/ppc/kernel/ramdisk_drvr.c
new file mode 100644 (file)
index 0000000..6eaa5d9
--- /dev/null
@@ -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);
+}
index 64185d5c1e693ea48b96313f11bcfadbf19dd358..c2c34a12aec0f45b59d6adf0d04dab53c79397a3 100644 (file)
@@ -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 @@ _printk(char const *fmt, ...)
 
 #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 @@ static _cvt(unsigned long val, char *buf, long radix, char *digits)
 /*
  * Console I/O interface
  */
+
 typedef const (*proc)();
 typedef int dev_t;
 
@@ -276,24 +227,24 @@ static int port = 0;
 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 @@ cnputc(char c)
          port = CRT_PORT;
       } else
       {
-         port =(int) NS16550_init(0);
+         port = NS16550_init(0);
       }
       init = TRUE;
    }
@@ -329,7 +280,7 @@ cnputc(char c)
    } else
    if (port)
    {
-      NS16550_putc((struct NS16550 *)port, c);
+      NS16550_putc(port, c);
    }
    if (c == '\n')
    {
@@ -345,7 +296,7 @@ cnputc(char c)
    }
 }
 
-void _cnpause(void)
+_cnpause()
 {
    int c;
    int s = _disable_interrupts();
@@ -374,17 +325,56 @@ void _cnpause(void)
    _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 @@ volatile struct NS16550 *NS16550_init(int chan)
 }
 
 
-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 @@ unsigned short      pccolor_so;             /* color/attributes, standout mode */
 /*
  * 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 cursor(void)
        }
 }
 
-static void initscreen(void )
+static void
+initscreen()
 {
        struct screen *d = &screen;
 
@@ -545,7 +536,8 @@ fillw(unsigned short val, unsigned short *buf, int num)
  * "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 @@ int CRT_putc(int port, unsigned char c)
        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 @@ const unsigned char keycode[] = {
        _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 @@ loop:
        goto loop;
 }
 
-int scankbd(void)
-{
+scankbd() {
        return (kbd(1) != -1);
 }
 
-void kbdreset(void)
+kbdreset()
 {
        unsigned char c;
 
@@ -1076,14 +1070,14 @@ void kbdreset(void)
                ;
 }
 
-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 @@ dump_buf(unsigned char *p, int s)
 }
 
 
+do_cnpause()
+{
+       static int line = 0;
+       if (++line > MAX_LINES)
+       {
+               cnpause();
+               line = 0;
+       }
+}
index 661e508a9def103606160dc55dce98125de444f1..579c6f8082829099cc8a77a9fd4cc4a944c0937e 100644 (file)
 #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 @@ struct screen_info screen_info = {
        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 long find_end_of_memory(void)
        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 @@ _printk("Config registers = %x/%x/%x\n", inb(0x0800), inb(0x0801), inb(0x0802));
                        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 @@ _printk("register total = %08X\n", total);
 
 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[];
-
-       ROOT_DEV = DEFAULT_ROOT_DEVICE;
+       unsigned char reg;
+
+       /* 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 @@ extern long builtin_ramdisk_size;
 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));
+}
index cf5db791d088ffaf1a06e49ef0c49a25fea8a92c..0869208d499abef98e0b5547865fedd021b4c578 100644 (file)
@@ -56,7 +56,13 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
        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 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
                        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 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
                                /* fall through */
                        default:
                                current->signal |= _S(signr & 0x7f);
-                               current->flags |= PF_SIGNALED;
                                do_exit(signr);
                        }
                }
index 4d48525b3a24c1e9b3d49bbb515fcc4ad076b6b8..acdd87e2eb6d2e85e471a77bfd2dea1ed414f7c2 100644 (file)
@@ -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 @@ _warn(char *msg)
        _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 --git a/arch/ppc/kernel/support.c b/arch/ppc/kernel/support.c
new file mode 100644 (file)
index 0000000..fb944a4
--- /dev/null
@@ -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 --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c
new file mode 100644 (file)
index 0000000..2ccb4b6
--- /dev/null
@@ -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 --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
new file mode 100644 (file)
index 0000000..a0e2e05
--- /dev/null
@@ -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!");
+}
+
index 82b76fb310ceac556806f200a3330d3c7ec52e42..c602301348e1f740f390fd00a3967a00eff09bc4 100644 (file)
@@ -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 @@ void
 _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 @@ _exception(int signr, struct pt_regs *regs)
 
 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 @@ FloatingPointCheckException(struct pt_regs *regs)
 
 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 @@ dump_regs(struct pt_regs *regs)
 {
        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 @@ dump_regs(struct pt_regs *regs)
                        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();
+       }
 }
 
index 3fa3a280d615e8daf9e662c07832b7eb0e3c73ee..319292840c046b9a03ed67ad16abaf020a05bdd0 100644 (file)
@@ -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 @@ SECTIONS
   .ctors     : { *(.ctors)   }
   .dtors     : { *(.dtors)   }
   /* Read-write section, merged into data segment: */
+  . = (. + 0x0FFF) & 0xFFFFF000;
   .data    :
   {
     *(.data)
diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile
new file mode 100644 (file)
index 0000000..d94420c
--- /dev/null
@@ -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 --git a/arch/ppc/lib/checksum.c b/arch/ppc/lib/checksum.c
new file mode 100644 (file)
index 0000000..0e0a37e
--- /dev/null
@@ -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 --git a/arch/ppc/lib/cksum_support.S b/arch/ppc/lib/cksum_support.S
new file mode 100644 (file)
index 0000000..264d5a6
--- /dev/null
@@ -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
+
index 50a09cecdb1954a7a28a835f8381fa4d6c7a01ea..ac6ef02137233cd101e491450dc428e1eb1add8c 100644 (file)
@@ -23,9 +23,8 @@ modules:
 
 dep:
        $(CPP) -M *.c > .depend
-
+       
 fastdep:
-       $(CPP) -M *.c > .depend
 
 #
 # include a dependency file if one exists
index a76c2f6bbe211fc7a9f05631ff4f62e651883b06..b8216ea8504aa3e17c473caa8252301676854be2 100644 (file)
@@ -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>
 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;
+               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);
        }
-      }
-    } 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);
-  }
 }
 
 /*
@@ -182,160 +137,148 @@ InstructionAccessException(struct pt_regs *regs)
  */
 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);
+}
index cc5e1c6facaef82db7028d82b2fa91b6516c1870..bafb0f28851f5f6ea1f2aff44874163750fd1da7 100644 (file)
@@ -5,7 +5,6 @@
  *  Ported to PPC by Gary Thomas
  */
 
-
 #include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #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 @@ pte_t __bad_page(void)
 
 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 @@ void show_mem(void)
        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 @@ extern unsigned long free_area_init(unsigned long, unsigned long);
  */
 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 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
        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 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
        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 @@ printk("Mem init - Start: %x, End: %x\n", start_mem, high_memory);
                        }
                        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 @@ printk("Mem init - Start: %x, End: %x\n", start_mem, high_memory);
 
 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 BAT1 =
    };
 BAT BAT2 =
    {
-/* map kernel with bats 0 = yes */
-#if 1
        {
                0x00000000>>17,         /* bepi */
                BL_256M,                /* bl */
@@ -342,22 +296,6 @@ BAT BAT2 =
                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 @@ BAT TMP_BAT2 =
    { /* 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 @@ BAT TMP_BAT2 =
 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 @@ MMU_get_item(struct item *hdr)
 
 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 @@ void MMU_init(void)
                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 @@ void MMU_init(void)
                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 @@ void MMU_init(void)
        {
                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 @@ if (va < (unsigned long)0x90000000)
        }
        /* 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 @@ MMU_hash_page(struct thread_struct *tss, unsigned long va, pte *pg)
        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 @@ _printk("Map VA: %08X, Slot: %08X[%08X/%08X], H: %d\n", va, slot, slot0, slot1,
                        } else
                        { /* Read only page */
                                perms = PP_RWRX;
+                               perms = PP_RXRX;
                        }
                } else
                { /* Kernel pages */
@@ -697,7 +657,7 @@ _printk("Map VA: %08X, Slot: %08X[%08X/%08X], H: %d\n", va, slot, slot0, slot1,
                }
 #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 @@ _printk("VA: %08X, PA: %08X, Flags: %x, Perms: %d\n", va, pg->page_num<<12, pg->
                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(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++)
+       pgd = pgd_offset(mm, 0);
+       if (!pgd) return;  /* No map? */
+       address = 0;
+       for (i = 0 ; (i < PTRS_PER_PGD) && (address < KERNELBASE); i++)
        {
-         if (pte_present(*_pte))
-         {
-           flags = MMU_hash_page(&current->tss, address, 0);
-           ((pte *)_pte)->flags |= flags;
-         }
-         _pte++;
-         address += PAGE_SIZE;
+               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
+/* 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++;
        }
-      } else
-      {
-       address += PAGE_SIZE*PTRS_PER_PTE;
-      }
-    } else
-    {
-      address += PAGE_SIZE*PTRS_PER_PTE;
-    }
-    pgd++;
-  }
 } 
 
 void
@@ -766,4 +985,57 @@ cache_mode(char *str, int *ints)
        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() {}
index 695dc1fc99b62c37dbb40fffa89dd167a2e62118..b63ea0e6a1f5b8abeaef61f3301d088081ecc199 100644 (file)
@@ -29,6 +29,7 @@ typedef struct _PTE
 #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 */
 
index 90e166a8913009d18d57090d7ce902670fc08abe..8f12a2eff08bb260d524a57a210ad723818b33a7 100644 (file)
@@ -213,13 +213,6 @@ static inline int __get_order(unsigned long size)
 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 @@ static int fdc_configure(void)
 {
        /* 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 @@ static void fdc_specify(void)
                /*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 @@ static void fdc_specify(void)
                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 @@ static void seek_floppy(void)
                }
        }
 
-#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 @@ int floppy_init(void)
        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++) {
index c5e320320295d47295a881c1baa381e9b161268f..b3ea7ada81e3370bb437b05c0ebc445dac5850fa 100644 (file)
@@ -3207,6 +3207,7 @@ static void probe_for_hwifs (void)
                 * 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 */
index 707adb5e15df0ca817f89406827b4dcab4e58412..3481b2b95d50ab4b68bb259e07123668395e547a 100644 (file)
@@ -854,8 +854,8 @@ static int transfer_data(struct s_drive_stuff *stuffp,
                                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;
index c7ea14e302f8e8ee74991ec1cc2a1f7a56f2ca72..62bff6261561a9809302e4c2015e5e58638b967c 100644 (file)
@@ -2642,7 +2642,9 @@ de4x5_alloc_rx_buff(struct device *dev, int index, int len)
 
     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;
 
index 4986d1fed9fe7c2f7936671f2f3f0e38c52b1c66..7c3e1cad4a2087b2914438aadf81ee9f54d4aedc 100644 (file)
@@ -122,7 +122,6 @@ int loopback_init(struct device *dev)
        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                    */
index f3c7dcefccacbe7020246286861a061c9e5e1f25..2a642bae98398d48d107e15a068ff09a8bbe6cbb 100644 (file)
@@ -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 @@ static int tunnel_close(struct device *dev)
        return 0;
 }
 
-#endif
-
 #ifdef TUNNEL_DEBUG
 void print_ip(struct iphdr *ip)
 {
@@ -348,10 +345,8 @@ int tunnel_init(struct device *dev)
        }
 
        /* 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);
index 56d7e670a40b0dac0d02ea0dd576e1012fcbe25c..a1a2f82ad49c7c4da1bc064de3c4af363b5c1087 100644 (file)
@@ -226,6 +226,9 @@ struct pci_dev_info dev_info[] = {
        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"),
index 9337be4e365a227e7d3bb8336202f2cd9e72986d..c23fdb97ec7f9bc86c487d43b5dd4d940922551d 100644 (file)
@@ -924,7 +924,7 @@ connect_loop :
                        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 @@ int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
        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;
        /*
index 8d9e1a42fcb17b6bf90de663a903fe63bbef39b2..da18dbea9d25ca97c0bcce789264aec7ea03e5a6 100644 (file)
@@ -18,7 +18,7 @@ int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 
 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
index 8e1314b48b9c1b90a3355c3c8c061887f945343e..5b20d22a43ec7d0877463cda148c01b7aefc7fc4 100644 (file)
@@ -74,8 +74,19 @@ hannu@voxware.pp.fi
 
 ----------------- 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 @@ fi
 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 @@ fi
 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 @@ fi
 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 @@ ln -s /dev/audio0 /dev/audio
 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 @@ mknod -m 666 /dev/dsp1 c 14 19
 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
 #
index 3532c99122f9588586ecb5c9e70b19f2c8ce255c..6ead22a270c00520d7f5209b5df716c48bb0540f 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -86,34 +86,37 @@ asmlinkage int sys_truncate(const char * path, unsigned long length)
        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 @@ asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length)
        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 --git a/include/asm-ppc/atomic.h b/include/asm-ppc/atomic.h
new file mode 100644 (file)
index 0000000..a54e6af
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ * PowerPC atomic operations
+ */
+
+#ifndef _ASM_PPC_ATOMIC_H_ 
+#define _ASM_PPC_ATOMIC_H_
+
+typedef int atomic_t;
+#endif
+
index 71ac10d47d0cea04450bb642d99b023914c28c5c..5e0407abd3a73fdede78192c2387b6535fc38b21 100644 (file)
@@ -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 @@ extern __inline__ int set_bit(int nr, void * add)
        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 @@ extern __inline__ int change_bit(int nr, void *add)
        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 clear_bit(int nr, void *add)
 }
 
 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 @@ extern __inline__ int test_bit(int nr, void *add)
        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 */
 
 
index 4615022cab8a7214c51098d3d3657b6d00a895ae..9e6608d54c2e509bbcc5273e8b1aa9befb08a104 100644 (file)
@@ -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 */
 #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 */
 /* 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 @@ static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
  * 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 @@ static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
 /* 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);
 }
 
 
index c33ee7c4e52e67b4eef394e0b95e9bcd545baf76..1b5d9f387c9ebb044d1dc6ad35b04ec743b7a93d 100644 (file)
@@ -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 */
 #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 */
 #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 */
 #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 --git a/include/asm-ppc/floppy.h b/include/asm-ppc/floppy.h
new file mode 100644 (file)
index 0000000..d36d35e
--- /dev/null
@@ -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 --git a/include/asm-ppc/ioctls.h b/include/asm-ppc/ioctls.h
new file mode 100644 (file)
index 0000000..52a3d45
--- /dev/null
@@ -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 */
index f51e2dd0657c77fb4da83834cf6d3105f9f15603..f457f82c3461df162066e946f9c2b52cac765d7f 100644 (file)
@@ -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 --git a/include/asm-ppc/mc146818rtc.h b/include/asm-ppc/mc146818rtc.h
new file mode 100644 (file)
index 0000000..78cf56e
--- /dev/null
@@ -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 */
index bb9f808308e449f3ef9dd3a4d7b7f4e2a39b7682..e0d15f04f2c4d67976a155d53fa8b259563d6844 100644 (file)
@@ -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 */
 #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__ */
index 4301aca82af82d2e11ac100c73b4bf178bb7ff6c..b26b79cd6b39747d033a56dc286c80e2a32b6a41 100644 (file)
@@ -29,6 +29,7 @@ typedef struct _PTE
 #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 --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h
new file mode 100644 (file)
index 0000000..8cee7fb
--- /dev/null
@@ -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 --git a/include/asm-ppc/nvram.h b/include/asm-ppc/nvram.h
new file mode 100644 (file)
index 0000000..1d704ff
--- /dev/null
@@ -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
index 316cf0fdaf57d53cbd28c02a406f33c62d6bbcd2..6984b2a08bd157851187b6c4ef00a38419ef2576 100644 (file)
@@ -63,6 +63,7 @@ typedef unsigned long pgprot_t;
 #define MAP_PAGE_RESERVED      (1<<15)
 
 
+#if 0  /* Now defined in "mm.h" */
 /*
  * This used to be an unsigned short...
  * 
@@ -75,6 +76,7 @@ typedef struct {
                 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
index 5a731fa81d57e706f654aa49a82c62fcc6709b32..9fe0efc7ca64c74e8b12eb2157b732b9bc438b0d 100644 (file)
 #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)
 #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.
 #define __S110 PAGE_SHARED
 #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
@@ -198,14 +222,18 @@ extern unsigned long high_memory;
 
 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 void pmd_reuse(pmd_t * pmdp) { }
 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 pte_t * pte_offset(pmd_t * dir, unsigned long address)
  */
 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 @@ extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
                        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 --git a/include/asm-ppc/posix_types.h b/include/asm-ppc/posix_types.h
new file mode 100644 (file)
index 0000000..7af5c0a
--- /dev/null
@@ -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 */
index 04bf21523d7f0a89c61e41b0eadc3d162e04154e..dc653912aa3b5f3a760509cacaa5dda3640064c9 100644 (file)
@@ -87,33 +87,29 @@ struct thread_struct
        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
index fa2a9c444b0d65f79a7eb568030e7077a45fb4a6..c654d86b7b8245a708c9b3a2c9df5b9d16d0ddc6 100644 (file)
@@ -46,7 +46,54 @@ struct pt_regs {
 
 #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
 
index cd8ff52529abfcadb562d9dcaa7513babbcc9c90..2cffda87124febae33325a288671aea2c6da86ff 100644 (file)
@@ -1,13 +1,6 @@
 #ifndef _PPC_RESOURCE_H
 #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
  */
 #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 */
 
-#ifdef notdef
-#define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space*/
-#endif
+#define RLIM_NLIMITS   9
+
+#ifdef __KERNEL__
+
+#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
index e4a8500c59a12ffd04b736b1aa82223b36eff251..5387400dc21e92c502a1ea289587e375db424887 100644 (file)
@@ -60,6 +60,17 @@ typedef unsigned long sigset_t;              /* at least 32 bits */
 #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 */
index 84faa2d0474c23a0c82198c91b986ca1355ac694..eadf15190cd201ab42ee804ae3b5d9ff4f55820d 100644 (file)
@@ -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 --git a/include/asm-ppc/sockios.h b/include/asm-ppc/sockios.h
new file mode 100644 (file)
index 0000000..385aedc
--- /dev/null
@@ -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 */
index 74e6fb6b0334bfa9f8e704bd6a6a659699437777..462cfa0cd9686e9eff05172aadba283b0af5751f 100644 (file)
@@ -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 old_stat {
 };
 
 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
index 3bd633882f417217a59330fad6a5e65610cf61ed..b507d7a89e78ecda229876fb644c9ff8fae4ef35 100644 (file)
@@ -19,7 +19,7 @@ extern void _enable_interrupts(int);
 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 --git a/include/asm-ppc/termbits.h b/include/asm-ppc/termbits.h
new file mode 100644 (file)
index 0000000..6c19c1f
--- /dev/null
@@ -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 */
index 54bc5cc23a9964cd9f09d4309f6d55ad9a7b4a44..e3d60b6197c04e508f624d1ddf311cb542377e01 100644 (file)
@@ -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 @@ struct ltchars {
 #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 @@ struct winsize {
        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 @@ struct termios {
 };
 
 /* 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 @@ struct termios {
        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 @@ extern inline void trans_to_termio(struct termios * termios,
        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 @@ extern inline void trans_to_termio(struct termios * termios,
 
 #endif /* __KERNEL__ */
 
-#endif /* _ALPHA_TERMIOS_H */
+#endif /* _PPC_TERMIOS_H */
index 29059e021b8df02b3beb87f01249e35e9acb37c0..0582b117c95c8ff5c8cd0402001c4d1e6e7fab75 100644 (file)
@@ -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 unsigned char __u8;
 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 unsigned char u8;
 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
index a25baa3243f16cf3d78b80b10ad6de7830632091..0e6ec2b735946ba3e40f038253e043f8707496b1 100644 (file)
@@ -257,6 +257,14 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
  * 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 --git a/include/asm-ppc/user.h b/include/asm-ppc/user.h
new file mode 100644 (file)
index 0000000..e3bd611
--- /dev/null
@@ -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 */
index 6515380eb97c9f16367fcef5d1c09df43e946742..d85f6dd331f4688a29aae4dfa448170b11d90aa4 100644 (file)
@@ -282,6 +282,8 @@ static int sun_floppy_init(void)
        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.
index caef9d382fa990239263bf9569e6d1833427deca..974f80ab0b00a185c409a6790a33a8f0bbc4d29f 100644 (file)
@@ -36,6 +36,7 @@ typedef unsigned long Elf32_Word;
 #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
index d7dfb2fdda822c91ea01d7ec900ef8b62ee44be2..902745b58450bda7b882ef602d21f04dc65f5ed4 100644 (file)
@@ -272,7 +272,7 @@ struct inode {
        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;
index 89b79da91dad62070f882a05d40e2e232c69aea3..516c93dbeee414323ac31cb83746d8b05a8c7010 100644 (file)
 #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
index 60fce307cb0a1afda5c609ed5cfd9c30f605eb09..63d0bca55c68ee065273bcb38e26426873fabea6 100644 (file)
@@ -210,7 +210,7 @@ int ip_fw_chk(struct iphdr *ip, struct device *rif, __u16 *redirport, struct ip_
        __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 @@ int ip_fw_chk(struct iphdr *ip, struct device *rif, __u16 *redirport, struct ip_
                        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 @@ int ip_fw_chk(struct iphdr *ip, struct device *rif, __u16 *redirport, struct ip_
                        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.
index 791293d6b3b63ff4f9d083f74f8a3bdf22c5a48a..1278259ad69a4526cd3a0610c950cde8bc7ecbd9 100644 (file)
@@ -604,7 +604,8 @@ static __inline__ void fib_add_1(short flags, __u32 dst, __u32 mask,
                 *      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 @@ static __inline__ void fib_add_1(short flags, __u32 dst, __u32 mask,
 
        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;